diff --git a/src/lexer.h b/src/lexer.h index 7cbb5ca..ec17b3a 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -29,7 +29,9 @@ typedef enum { TOKEN_SEMI, TOKEN_FN, TOKEN_LET, - TOKEN_IDENT_INT //TODO: unhardcode + TOKEN_IDENT_INT, //TODO: unhardcode + TOKEN_EQU, + TOKEN_RETURN } symbols; typedef enum { @@ -67,7 +69,10 @@ char *token_type_to_string(symbols type) { case TOKEN_FN: return "TOKEN_FN"; case TOKEN_LET: return "TOKEN_LET"; case TOKEN_IDENT_INT: return "TOKEN_IDENT_INT"; - default: return "UNKNOWN_SYMBOL"; + case TOKEN_EQU: return "TOKEN_EQU"; + case TOKEN_RETURN: return "TOKEN_RETURN"; + + // default: return "UNKNOWN_SYMBOL"; } } @@ -196,6 +201,7 @@ size_t read_from_tok(Token *tok, const char *input, size_t cursor) { if (strcmp(buf, "let") == 0) token_push(tok, TOKEN_LET, buf, BHV_UNDEFINED, cursor - start); else if (strcmp(buf, "fn") == 0) token_push(tok, TOKEN_FN, buf, BHV_UNDEFINED, cursor - start); + else if (strcmp(buf, "return") == 0) token_push(tok, TOKEN_RETURN, buf, BHV_UNDEFINED, cursor - start); else if (strcmp(buf, "int") == 0) token_push(tok, TOKEN_IDENT_INT, buf, BHV_UNDEFINED, cursor - start); // TODO: unhardcode else token_push(tok, TOKEN_IDENTIFIER, buf, BHV_IDENT, cursor - start); @@ -212,6 +218,7 @@ size_t read_from_tok(Token *tok, const char *input, size_t cursor) { case '}': token_push(tok, TOKEN_RCURLY, "}", BHV_STACK, 1); break; case ';': token_push(tok, TOKEN_SEMI, ";", BHV_STACK, 1); break; case ':': token_push(tok, TOKEN_COLON, ":", BHV_STACK, 1); break; + case '=': token_push(tok, TOKEN_EQU, "=", BHV_STACK, 1); break; case '(': token_push(tok, TOKEN_LPAREN, "(", BHV_STACK, 1); diff --git a/src/parser.h b/src/parser.h index 56fec4e..4e71c84 100644 --- a/src/parser.h +++ b/src/parser.h @@ -201,6 +201,88 @@ void skip_space(Token *inp, size_t *idx){ while (inp->type[*idx] == TOKEN_SPACE || inp->type[*idx] == TOKEN_NEWLINE) (*idx)++; } + +Token slice_token(Token *inp, size_t a, size_t z){ // probably should be implemented in lexer but not bothered + Token t = {0}; + token_init(&t, z-a+1); + for (size_t i=a; itype[i], inp->text[i], inp->behaviour[i], inp->cursor_skip[i]); + } + return t; +} + +Token parse_statement(Token *inp, size_t *idx, SymbolTable *sym){ + skip_space(inp, idx); + + if (inp->type[*idx] == TOKEN_LET){ + (*idx)++; + skip_space(inp, idx); + + if (inp->type[*idx] != TOKEN_IDENTIFIER){ + fprintf(stderr, "Expected Identifier after 'let'"); + exit(1); + } + + char *var_name = inp->text[*idx]; + (*idx)++; + skip_space(inp, idx); + + if (inp->type[*idx] != TOKEN_EQU){ + fprintf(stderr, "Expected '=' after identifier"); + exit(1); + } + (*idx)++; + skip_space(inp, idx); + + size_t expr_start = *idx; + while (inp->type[*idx] != TOKEN_SEMI && inp->type[*idx] != TOKEN_EOF){ + (*idx)++; + } + + size_t expr_end = *idx; + Token expr = slice_token(inp, expr_start, expr_end); + Token rpn = build_rpn(&expr, sym); + + + Symbol exprn = + { + .name=strdup(var_name), + .symbol_kind = SYM_VAR, + .builtin = false, + .ret_type = TOKEN_UNKNOWN + }; + symbol_table_add(sym, exprn); + + skip_space(inp, idx); + if (inp->type[*idx] == TOKEN_SEMI) { + (*idx)++; + skip_space(inp, idx); + return rpn; + } + } else if (inp->type[*idx] == TOKEN_RETURN) { + (*idx)++; + skip_space(inp, idx); + + size_t expr_start = *idx; + while (inp->type[*idx] != TOKEN_SEMI && inp->type[*idx] != TOKEN_EOF){ + (*idx)++; + } + size_t expr_end = *idx; + + Token expr = slice_token(inp, expr_start, expr_end); + Token rpn = build_rpn(&expr, sym); + (*idx)++; + if (inp->type[*idx] == TOKEN_SEMI) { + (*idx)++; + skip_space(inp, idx); + return rpn; + } + } else { + fprintf(stderr, "Unexpected statement '%s\n'", inp->text[*idx]); + exit(1); + } +} + Token parse_func_def(Token *inp, size_t *idx, SymbolTable *sym) { skip_space(inp, idx); if (inp->type[*idx] != TOKEN_FN) { @@ -291,8 +373,11 @@ Token parse_func_def(Token *inp, size_t *idx, SymbolTable *sym) { (*idx)++; skip_space(inp, idx); + Token statement = {0}; + while (inp->type[*idx] != TOKEN_RCURLY && inp->type[*idx] != TOKEN_EOF) { - (*idx)++; + statement = parse_statement(inp, idx, sym); + skip_space(inp, idx); } if (inp->type[*idx] != TOKEN_RCURLY) { @@ -302,8 +387,7 @@ Token parse_func_def(Token *inp, size_t *idx, SymbolTable *sym) { (*idx)++; symbol_table_add(sym, func); - Token empty = {0}; - return empty; + return statement; // TODO: return block aka multiple statements }