wip compiler
This commit is contained in:
parent
f516f0fbe7
commit
8e9ed0da1e
File diff suppressed because it is too large
Load Diff
|
|
@ -32,20 +32,16 @@ typedef struct plex_tab_s PlexTable;
|
||||||
typedef struct scope_s Scope;
|
typedef struct scope_s Scope;
|
||||||
typedef struct scope_tab_s ScopeTable;
|
typedef struct scope_tab_s ScopeTable;
|
||||||
|
|
||||||
|
#define MAX_SYMBOL_NAME_LENGTH 64
|
||||||
|
|
||||||
struct value_type_s {
|
struct value_type_s {
|
||||||
SymbolType type;
|
SymbolType type;
|
||||||
u32 name;
|
char name[MAX_SYMBOL_NAME_LENGTH];
|
||||||
|
u8 name_length;
|
||||||
u32 size;
|
u32 size;
|
||||||
u32 table_ref; // if it is a heap object
|
u32 table_ref; // if it is a heap object
|
||||||
};
|
};
|
||||||
|
|
||||||
struct plex_def_s {
|
|
||||||
u32 name;
|
|
||||||
u32 size;
|
|
||||||
u32 field_ref_start;
|
|
||||||
u32 field_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct plex_fields_tab_s {
|
struct plex_fields_tab_s {
|
||||||
u32 *plex_refs;
|
u32 *plex_refs;
|
||||||
ValueType *fields;
|
ValueType *fields;
|
||||||
|
|
@ -53,13 +49,20 @@ struct plex_fields_tab_s {
|
||||||
u32 capacity;
|
u32 capacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct plex_def_s {
|
||||||
|
char name[MAX_SYMBOL_NAME_LENGTH];
|
||||||
|
u8 name_length;
|
||||||
|
u32 size;
|
||||||
|
u32 field_ref_start;
|
||||||
|
u32 field_count;
|
||||||
|
};
|
||||||
|
|
||||||
struct plex_tab_s {
|
struct plex_tab_s {
|
||||||
PlexDef *symbols;
|
PlexDef *symbols;
|
||||||
u32 count;
|
u32 count;
|
||||||
u32 capacity;
|
u32 capacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_SYMBOL_NAME_LENGTH 64
|
|
||||||
struct symbol_s {
|
struct symbol_s {
|
||||||
char name[MAX_SYMBOL_NAME_LENGTH];
|
char name[MAX_SYMBOL_NAME_LENGTH];
|
||||||
u8 name_length;
|
u8 name_length;
|
||||||
|
|
@ -80,6 +83,7 @@ struct scope_tab_s {
|
||||||
u32 count;
|
u32 count;
|
||||||
u32 capacity;
|
u32 capacity;
|
||||||
i32 scope_ref;
|
i32 scope_ref;
|
||||||
|
u32 depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool compile(VM *vm, ScopeTable *st, char *source);
|
bool compile(VM *vm, ScopeTable *st, char *source);
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,14 @@ typedef struct {
|
||||||
const char *start;
|
const char *start;
|
||||||
const char *current;
|
const char *current;
|
||||||
int line;
|
int line;
|
||||||
} Lexer;
|
} Parser;
|
||||||
|
|
||||||
Lexer lexer;
|
Parser parser;
|
||||||
|
|
||||||
void initLexer(const char *source) {
|
void init_parser(const char *source) {
|
||||||
lexer.start = source;
|
parser.start = source;
|
||||||
lexer.current = source;
|
parser.current = source;
|
||||||
lexer.line = 1;
|
parser.line = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isAlpha(char c) {
|
static bool isAlpha(char c) {
|
||||||
|
|
@ -23,36 +23,36 @@ static bool isAlpha(char c) {
|
||||||
|
|
||||||
static bool isDigit(char c) { return c >= '0' && c <= '9'; }
|
static bool isDigit(char c) { return c >= '0' && c <= '9'; }
|
||||||
|
|
||||||
static bool isAtEnd() { return *lexer.current == '\0'; }
|
static bool isAtEnd() { return *parser.current == '\0'; }
|
||||||
|
|
||||||
static char advance() {
|
static char advance() {
|
||||||
lexer.current++;
|
parser.current++;
|
||||||
return lexer.current[-1];
|
return parser.current[-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static char peek() { return *lexer.current; }
|
static char peek() { return *parser.current; }
|
||||||
|
|
||||||
static char peekNext() {
|
static char peekNext() {
|
||||||
if (isAtEnd())
|
if (isAtEnd())
|
||||||
return '\0';
|
return '\0';
|
||||||
return lexer.current[1];
|
return parser.current[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool match(char expected) {
|
static bool match(char expected) {
|
||||||
if (isAtEnd())
|
if (isAtEnd())
|
||||||
return false;
|
return false;
|
||||||
if (*lexer.current != expected)
|
if (*parser.current != expected)
|
||||||
return false;
|
return false;
|
||||||
lexer.current++;
|
parser.current++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Token makeToken(TokenType type) {
|
static Token makeToken(TokenType type) {
|
||||||
Token token;
|
Token token;
|
||||||
token.type = type;
|
token.type = type;
|
||||||
token.start = lexer.start;
|
token.start = parser.start;
|
||||||
token.length = (int)(lexer.current - lexer.start);
|
token.length = (int)(parser.current - parser.start);
|
||||||
token.line = lexer.line;
|
token.line = parser.line;
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ static Token errorToken(const char *message) {
|
||||||
token.type = TOKEN_ERROR;
|
token.type = TOKEN_ERROR;
|
||||||
token.start = message;
|
token.start = message;
|
||||||
token.length = (int)strlen(message);
|
token.length = (int)strlen(message);
|
||||||
token.line = lexer.line;
|
token.line = parser.line;
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,7 +75,7 @@ static void skipWhitespace() {
|
||||||
advance();
|
advance();
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
lexer.line++;
|
parser.line++;
|
||||||
advance();
|
advance();
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
|
|
@ -90,7 +90,7 @@ static void skipWhitespace() {
|
||||||
advance();
|
advance();
|
||||||
while (!isAtEnd()) {
|
while (!isAtEnd()) {
|
||||||
if (peek() == '\n')
|
if (peek() == '\n')
|
||||||
lexer.line++;
|
parser.line++;
|
||||||
if (peek() == '*' && peekNext() == '/') {
|
if (peek() == '*' && peekNext() == '/') {
|
||||||
advance();
|
advance();
|
||||||
advance();
|
advance();
|
||||||
|
|
@ -110,8 +110,8 @@ static void skipWhitespace() {
|
||||||
|
|
||||||
static TokenType checkKeyword(int start, int length, const char *rest,
|
static TokenType checkKeyword(int start, int length, const char *rest,
|
||||||
TokenType type) {
|
TokenType type) {
|
||||||
if (lexer.current - lexer.start == start + length &&
|
if (parser.current - parser.start == start + length &&
|
||||||
memcmp(lexer.start + start, rest, length) == 0) {
|
memcmp(parser.start + start, rest, length) == 0) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,8 +217,6 @@ static TokenType identifierType() {
|
||||||
switch (lexer.start[2]) {
|
switch (lexer.start[2]) {
|
||||||
case 'a':
|
case 'a':
|
||||||
return checkKeyword(3, 1, "d", TOKEN_KEYWORD_READ);
|
return checkKeyword(3, 1, "d", TOKEN_KEYWORD_READ);
|
||||||
case 'f':
|
|
||||||
return checkKeyword(3, 4, "resh", TOKEN_KEYWORD_REFRESH);
|
|
||||||
case 't':
|
case 't':
|
||||||
return checkKeyword(3, 3, "urn", TOKEN_KEYWORD_RETURN);
|
return checkKeyword(3, 3, "urn", TOKEN_KEYWORD_RETURN);
|
||||||
}
|
}
|
||||||
|
|
@ -231,7 +229,14 @@ static TokenType identifierType() {
|
||||||
if (lexer.current - lexer.start > 1) {
|
if (lexer.current - lexer.start > 1) {
|
||||||
switch (lexer.start[1]) {
|
switch (lexer.start[1]) {
|
||||||
case 't':
|
case 't':
|
||||||
return checkKeyword(2, 1, "r", TOKEN_TYPE_STR);
|
if (lexer.current - lexer.start > 2) {
|
||||||
|
switch (lexer.start[2]) {
|
||||||
|
case 'r':
|
||||||
|
return checkKeyword(2, 0, "", TOKEN_TYPE_STR);
|
||||||
|
case 'a':
|
||||||
|
return checkKeyword(2, 1, "t", TOKEN_KEYWORD_STAT);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -269,8 +274,6 @@ static TokenType identifierType() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'g':
|
|
||||||
return checkKeyword(1, 5, "lobal", TOKEN_KEYWORD_GLOBAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TOKEN_IDENTIFIER;
|
return TOKEN_IDENTIFIER;
|
||||||
|
|
@ -303,7 +306,7 @@ static Token number() {
|
||||||
static Token string() {
|
static Token string() {
|
||||||
while (peek() != '"' && !isAtEnd()) {
|
while (peek() != '"' && !isAtEnd()) {
|
||||||
if (peek() == '\n')
|
if (peek() == '\n')
|
||||||
lexer.line++;
|
parser.line++;
|
||||||
advance();
|
advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -317,7 +320,7 @@ static Token string() {
|
||||||
|
|
||||||
Token next_token() {
|
Token next_token() {
|
||||||
skipWhitespace();
|
skipWhitespace();
|
||||||
lexer.start = lexer.current;
|
parser.start = parser.current;
|
||||||
|
|
||||||
if (isAtEnd())
|
if (isAtEnd())
|
||||||
return makeToken(TOKEN_EOF);
|
return makeToken(TOKEN_EOF);
|
||||||
|
|
@ -440,8 +443,6 @@ const char *token_type_to_string(TokenType type) {
|
||||||
return "KEYWORD_TRUE";
|
return "KEYWORD_TRUE";
|
||||||
case TOKEN_KEYWORD_FALSE:
|
case TOKEN_KEYWORD_FALSE:
|
||||||
return "KEYWORD_FALSE";
|
return "KEYWORD_FALSE";
|
||||||
case TOKEN_KEYWORD_GLOBAL:
|
|
||||||
return "KEYWORD_GLOBAL";
|
|
||||||
case TOKEN_OPERATOR_NOT:
|
case TOKEN_OPERATOR_NOT:
|
||||||
return "OPERATOR_NOT";
|
return "OPERATOR_NOT";
|
||||||
case TOKEN_OPERATOR_AND:
|
case TOKEN_OPERATOR_AND:
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ typedef enum {
|
||||||
TOKEN_KEYWORD_USE,
|
TOKEN_KEYWORD_USE,
|
||||||
TOKEN_KEYWORD_INIT,
|
TOKEN_KEYWORD_INIT,
|
||||||
TOKEN_KEYWORD_THIS,
|
TOKEN_KEYWORD_THIS,
|
||||||
TOKEN_KEYWORD_GLOBAL,
|
|
||||||
TOKEN_KEYWORD_OPEN,
|
TOKEN_KEYWORD_OPEN,
|
||||||
TOKEN_KEYWORD_READ,
|
TOKEN_KEYWORD_READ,
|
||||||
TOKEN_KEYWORD_WRITE,
|
TOKEN_KEYWORD_WRITE,
|
||||||
|
|
@ -82,7 +81,7 @@ typedef struct {
|
||||||
int line;
|
int line;
|
||||||
} Token;
|
} Token;
|
||||||
|
|
||||||
void initLexer(const char *source);
|
void init_parser(const char *source);
|
||||||
Token next_token();
|
Token next_token();
|
||||||
const char* token_type_to_string(TokenType type);
|
const char* token_type_to_string(TokenType type);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ bool step_vm(VM *vm) {
|
||||||
child->locals[i] = frame->locals[src_reg];
|
child->locals[i] = frame->locals[src_reg];
|
||||||
mask = 1 << (src_reg % 32);
|
mask = 1 << (src_reg % 32);
|
||||||
if (frame->heap_mask[src_reg / 32] & mask) {
|
if (frame->heap_mask[src_reg / 32] & mask) {
|
||||||
child->heap_mask[i / 32] |= 1 << (i % 32);
|
child->heap_mask[i / 32] |= 1 << (i % 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,7 +174,8 @@ bool step_vm(VM *vm) {
|
||||||
parent->heap_mask[parent->return_reg / 32] |= (1 << parent->return_reg);
|
parent->heap_mask[parent->return_reg / 32] |= (1 << parent->return_reg);
|
||||||
} else {
|
} else {
|
||||||
parent->locals[parent->return_reg] = value;
|
parent->locals[parent->return_reg] = value;
|
||||||
parent->heap_mask[parent->return_reg / 32] &= ~(1 << parent->return_reg);
|
parent->heap_mask[parent->return_reg / 32] &=
|
||||||
|
~(1 << parent->return_reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -473,7 +474,7 @@ bool step_vm(VM *vm) {
|
||||||
frame->locals[0] = dest;
|
frame->locals[0] = dest;
|
||||||
vm->flag = 1;
|
vm->flag = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_MEMSET_16: {
|
case OP_MEMSET_16: {
|
||||||
u32 i, start, end;
|
u32 i, start, end;
|
||||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||||
|
|
@ -535,7 +536,7 @@ bool step_vm(VM *vm) {
|
||||||
frame->locals[0] = dest;
|
frame->locals[0] = dest;
|
||||||
vm->flag = 1;
|
vm->flag = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_REG_MOV: {
|
case OP_REG_MOV: {
|
||||||
u8 dest, src1;
|
u8 dest, src1;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue