mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-05 22:38:44 +00:00
fixes, cleanup, some copies removed
This commit is contained in:
parent
2589f6166f
commit
d90a8cf89f
16 changed files with 373 additions and 666 deletions
|
|
@ -1,5 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "parser.h"
|
||||
#include "utils.h"
|
||||
|
||||
void run(Bytefile *bf, int argc, char **argv);
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@
|
|||
DEF(CMD_BINOP_AND, &&) \
|
||||
DEF(CMD_BINOP_OR, ||)
|
||||
|
||||
const char *read_cmd(char *ip);
|
||||
const char *read_cmd(char *ip, const Bytefile *bf);
|
||||
|
||||
Bytefile *read_file(char *fname);
|
||||
|
||||
// void dump_file(FILE *f, bytefile *bf);
|
||||
// Bytefile *read_file(const char *fname);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <ostream>
|
||||
|
||||
extern "C" {
|
||||
#include "parser.h"
|
||||
#include "utils.h"
|
||||
}
|
||||
|
||||
|
|
@ -46,29 +47,12 @@ enum class Cmd : int8_t {
|
|||
|
||||
Bytefile *read_file(const char *fname);
|
||||
|
||||
static inline int ip_read_int(char **ip, const Bytefile &bf) {
|
||||
if (*ip + sizeof(int) > bf.code_ptr + bf.code_size) {
|
||||
failure("last command is invalid, int parameter can not be read\n");
|
||||
}
|
||||
*ip += sizeof(int);
|
||||
return *(int *)((*ip) - sizeof(int));
|
||||
}
|
||||
|
||||
static inline uint8_t ip_read_byte(char **ip, const Bytefile &bf) {
|
||||
if (*ip + sizeof(char) > bf.code_ptr + bf.code_size) {
|
||||
failure("last command is invalid, byte parameter can not be read\n");
|
||||
}
|
||||
return *(*ip)++;
|
||||
}
|
||||
|
||||
static inline uint8_t ip_read_byte_unsafe(char **ip) { return *(*ip)++; }
|
||||
|
||||
static inline const char *ip_read_string(char **ip, const Bytefile &bf) {
|
||||
return get_string(&bf, ip_read_int(ip, bf));
|
||||
}
|
||||
|
||||
std::pair<Cmd, uint8_t> parse_command(char **ip, const Bytefile &bf);
|
||||
std::pair<Cmd, uint8_t> parse_command(char **ip, const Bytefile &bf,
|
||||
std::pair<Cmd, uint8_t> parse_command(char **ip, const Bytefile *bf);
|
||||
std::pair<Cmd, uint8_t> parse_command(char **ip, const Bytefile *bf,
|
||||
std::ostream &out);
|
||||
|
||||
std::pair<Cmd, uint8_t> parse_command_name(char **ip, const Bytefile *bf);
|
||||
|
||||
bool is_command_name(char *ip, const Bytefile *bf, Cmd cmd);
|
||||
|
||||
void print_file(const Bytefile &bf, std::ostream &out);
|
||||
|
|
|
|||
|
|
@ -196,9 +196,11 @@ static inline void s_enter_f(char *rp, bool is_closure_call, auint args_sz,
|
|||
}
|
||||
|
||||
static inline void s_exit_f() {
|
||||
#ifndef WITH_CHECK
|
||||
if (s.fp == NULL) {
|
||||
s_failure(&s, "exit: no func");
|
||||
}
|
||||
#endif
|
||||
|
||||
struct Frame frame = *s.fp;
|
||||
|
||||
|
|
@ -274,13 +276,15 @@ static inline void **var_by_category(enum VarCategory category, size_t id) {
|
|||
#endif
|
||||
var = f_args(s.fp) + (f_args_sz(s.fp) - id - 1);
|
||||
break;
|
||||
case VAR_CLOSURE: // TODO: check that clojure vars are used only in clojures
|
||||
case VAR_CLOSURE:
|
||||
#ifndef WITH_CHECK
|
||||
if (s.fp == NULL) {
|
||||
s_failure(&s, "can't read closure parameter outside of function");
|
||||
}
|
||||
if (s.fp->closure == NULL) {
|
||||
s_failure(&s, "can't read closure parameter not in closure");
|
||||
}
|
||||
#endif
|
||||
if (UNBOXED(s.fp->closure)) {
|
||||
s_failure(&s, "not boxed value expected in closure index");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,12 +69,12 @@ void construct_state(Bytefile *bf, struct State *s, void **stack);
|
|||
void cleanup_state(struct State *state);
|
||||
|
||||
static inline void s_failure(struct State *s, const char *msg) {
|
||||
exec_failure(read_cmd(s->instr_ip), s->current_line,
|
||||
exec_failure(read_cmd(s->instr_ip, s->bf), s->current_line,
|
||||
s->instr_ip - s->bf->code_ptr, msg);
|
||||
}
|
||||
|
||||
static inline void ip_failure(char *ip, Bytefile *bf, const char *msg) {
|
||||
exec_failure(read_cmd(ip), 0, ip - bf->code_ptr, msg);
|
||||
exec_failure(read_cmd(ip, bf), 0, ip - bf->code_ptr, msg);
|
||||
}
|
||||
|
||||
static inline void ip_safe_failure(char *ip, Bytefile *bf, const char *msg) {
|
||||
|
|
@ -99,7 +99,7 @@ static inline enum VarCategory to_var_category(uint8_t category) {
|
|||
return (enum VarCategory)category;
|
||||
}
|
||||
|
||||
enum CMD {
|
||||
enum CMD_TOPLVL {
|
||||
CMD_BINOP = 0,
|
||||
CMD_BASIC,
|
||||
CMD_LD,
|
||||
|
|
@ -112,7 +112,7 @@ enum CMD {
|
|||
};
|
||||
|
||||
enum CMD_BINOPS {
|
||||
CMD_BINOP_ADD = 1, // +
|
||||
CMD_BINOP_ADD = 0, // +
|
||||
CMD_BINOP_SUB, // -
|
||||
CMD_BINOP_MULT, // *
|
||||
CMD_BINOP_DIV, // /
|
||||
|
|
|
|||
|
|
@ -26,28 +26,106 @@ static inline void exec_failure(const char *cmd, int line, aint offset,
|
|||
msg);
|
||||
}
|
||||
|
||||
// --- unsafe versions
|
||||
|
||||
// access data
|
||||
|
||||
/* Gets a string from a string table by an index */
|
||||
static inline const char *get_string(const Bytefile *f, size_t pos) {
|
||||
if (pos >= f->stringtab_size) {
|
||||
failure("strinpg pos is out of range: %zu >= %i\n", pos, f->stringtab_size);
|
||||
}
|
||||
return &f->string_ptr[pos];
|
||||
static inline const char *get_string_unsafe(const Bytefile *bf, size_t pos) {
|
||||
return &bf->string_ptr[pos];
|
||||
}
|
||||
|
||||
/* Gets a name offset for a public symbol */
|
||||
static inline size_t get_public_name_offset_unsafe(const Bytefile *bf,
|
||||
size_t i) {
|
||||
return bf->public_ptr[i * 2];
|
||||
}
|
||||
|
||||
/* Gets a name for a public symbol */
|
||||
static inline const char *get_public_name(const Bytefile *f, size_t i) {
|
||||
if (i >= f->public_symbols_number) {
|
||||
failure("public number is out of range: %zu >= %i\n", i,
|
||||
f->public_symbols_number);
|
||||
}
|
||||
return get_string(f, f->public_ptr[i * 2]);
|
||||
static inline const char *get_public_name_unsafe(const Bytefile *bf, size_t i) {
|
||||
return get_string_unsafe(bf, get_public_name_offset_unsafe(bf, i));
|
||||
}
|
||||
|
||||
/* Gets an offset for a publie symbol */
|
||||
static inline size_t get_public_offset(const Bytefile *f, size_t i) {
|
||||
static inline size_t get_public_offset_unsafe(const Bytefile *bf, size_t i) {
|
||||
return bf->public_ptr[i * 2 + 1];
|
||||
}
|
||||
|
||||
// read from ip
|
||||
|
||||
static inline uint16_t ip_read_half_int_unsafe(char **ip) {
|
||||
*ip += sizeof(uint16_t);
|
||||
return *(uint16_t *)((*ip) - sizeof(uint16_t));
|
||||
}
|
||||
|
||||
static inline int32_t ip_read_int_unsafe(char **ip) {
|
||||
*ip += sizeof(int32_t);
|
||||
return *(int32_t *)((*ip) - sizeof(int32_t));
|
||||
}
|
||||
|
||||
static inline uint8_t ip_read_byte_unsafe(char **ip) { return *(*ip)++; }
|
||||
|
||||
static inline const char *ip_read_string_unsafe(char **ip, const Bytefile *bf) {
|
||||
return get_string_unsafe(bf, ip_read_int_unsafe(ip));
|
||||
}
|
||||
// --- safe versions
|
||||
|
||||
// access data
|
||||
|
||||
/* Gets a string from a string table by an index */
|
||||
static inline const char *get_string_safe(const Bytefile *f, size_t pos) {
|
||||
if (pos >= f->stringtab_size) {
|
||||
failure("string pos is out of range: %zu >= %i\n", pos, f->stringtab_size);
|
||||
}
|
||||
return get_string_unsafe(f, pos);
|
||||
}
|
||||
|
||||
/* Gets a name offset for a public symbol */
|
||||
static inline size_t get_public_name_offset_safe(const Bytefile *f, size_t i) {
|
||||
if (i >= f->public_symbols_number) {
|
||||
failure("public number is out of range: %zu >= %i\n", i,
|
||||
f->public_symbols_number);
|
||||
}
|
||||
return f->public_ptr[i * 2 + 1];
|
||||
return get_public_name_offset_unsafe(f, i);
|
||||
}
|
||||
|
||||
/* Gets a name for a public symbol */
|
||||
static inline const char *get_public_name_safe(const Bytefile *f, size_t i) {
|
||||
return get_string_safe(f, get_public_name_offset_safe(f, i));
|
||||
}
|
||||
|
||||
/* Gets an offset for a publie symbol */
|
||||
static inline size_t get_public_offset_safe(const Bytefile *f, size_t i) {
|
||||
if (i >= f->public_symbols_number) {
|
||||
failure("public number is out of range: %zu >= %i\n", i,
|
||||
f->public_symbols_number);
|
||||
}
|
||||
return get_public_offset_unsafe(f, i);
|
||||
}
|
||||
|
||||
// read from ip
|
||||
|
||||
static inline uint16_t ip_read_half_int_safe(char **ip, const Bytefile *bf) {
|
||||
if (*ip + sizeof(uint16_t) > bf->code_ptr + bf->code_size) {
|
||||
failure("last command is invalid, int parameter can not be read\n");
|
||||
}
|
||||
return ip_read_half_int_unsafe(ip);
|
||||
}
|
||||
|
||||
static inline int32_t ip_read_int_safe(char **ip, const Bytefile *bf) {
|
||||
if (*ip + sizeof(int32_t) > bf->code_ptr + bf->code_size) {
|
||||
failure("last command is invalid, int parameter can not be read\n");
|
||||
}
|
||||
return ip_read_int_unsafe(ip);
|
||||
}
|
||||
|
||||
static inline uint8_t ip_read_byte_safe(char **ip, const Bytefile *bf) {
|
||||
if (*ip + sizeof(char) > bf->code_ptr + bf->code_size) {
|
||||
failure("last command is invalid, byte parameter can not be read\n");
|
||||
}
|
||||
return ip_read_byte_unsafe(ip);
|
||||
}
|
||||
|
||||
static inline const char *ip_read_string_safe(char **ip, const Bytefile *bf) {
|
||||
return get_string_safe(bf, ip_read_int_safe(ip, bf));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue