diff --git a/.gitignore b/.gitignore index 0f04456..a506653 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ out/ .data/ +hadron \ No newline at end of file diff --git a/main.c b/main.c index 8fd33fb..0de05bd 100644 --- a/main.c +++ b/main.c @@ -98,6 +98,8 @@ int main(int argc, char *argv[]) { printAST(p->data, 5); + printf("token count %i\n", ((Array *)t->data)->l); + free(contents); freeArray(t->data); free(t); diff --git a/src/parser.c b/src/parser.c index d24ff4e..7d58ebc 100644 --- a/src/parser.c +++ b/src/parser.c @@ -7,6 +7,9 @@ #include static void initParser(char *, Array *, char *); +static void synchronize(); +// go to nearest delimiter or newline +static void psync(); static boolean end(void); static boolean start(void); static Token *next(void); @@ -76,7 +79,7 @@ Value *fmatch(Type t, char *e) { } else { r->error = true; r->value = error("Parse", parser.file, e, next()); - }; + } return r; } @@ -145,12 +148,19 @@ boolean check(Value *r) { void delmt(boolean throw) { match(DELMT); - if (throw &¤t() && peekNext() && + if (throw && current() && peekNext() && (current()->pos.line == peekNext()->pos.line)) pushArray(parser.errors, error("Parse", parser.file, "expected delimiter", current())); } +void psync() { + debug_log("psync", parser.code, peekNext()); + while (!end() && (current()->type != DELMT && current()->pos.line == peekNext()->pos.line)) { + next(); + } +} + Value *parseClassDeclaration() { Value *n = parseIdentifier(NULL); if (check(n)) return freeValue(n); @@ -193,9 +203,12 @@ Value *funcParams() { Value *funcBody() { Array *a = newArray(2); while (!match(RCURLY)) { - Value *v = parseExpression(); - if (check(v)) return freeArray(a), freeValue(v); - pushArray(a, v->value); + Value *v = parseStatement(); + if (check(v)) { + psync(); + freeValue(v); + // if (check(v)) return freeArray(a), freeValue(v); + } else pushArray(a, v->value); }; trimArray(a); return toValue(a); @@ -234,15 +247,17 @@ Value *parseAssignmentExpression(Value *t) { prev(); Value *n = parseIdentifier(t); if (check(n)) return freeValue(t), freeValue(n); - Value *q = fmatch(EQ, "expected ="); - if (check(q)) return freeValue(t), freeValue(n), freeValue(q); + // Value *q = fmatch(EQ, "expected ="); + next(); // consume operator + // if (check(q)) return freeValue(t), freeValue(n), freeValue(q); Value *r = parseExpression(); - if (check(r)) return freeValue(t), freeValue(n), freeValue(q), freeValue(r); + if (check(r)) return freeValue(t), freeValue(n), freeValue(r); match(DELMT); - return toValue(initAssignmentExpression(n->value, r->value)); + return toValue(initAssignmentExpression(n->value, r->value, 0)); } Value *parseIdentifier(Value *t) { + debug_log("iden", parser.code, peekNext()); Value *id = fmatch(NAME, "expected identifier"); if (check(id)) return freeValue(id), freeValue(t); return toValue( @@ -254,9 +269,17 @@ Value *parseStringLiteral() { return toValue(initStringLiteral(getTokenContent(parser.code, current()))); } Value *parseLiteral() { + debug_log("lit", parser.code, peekNext()); if (match(STR)) return parseStringLiteral(); + if (matchAny(14, FOR, CLASS, FUNC, WHILE, IF, DO, ELSE, FROM, IMPORT, NEW, AWAIT, AS, ASYNC, RETURN)) { + debug_log("---lit", parser.code, peekNext()); + Value *v = malloc(sizeof(Value)); + v->error = true; + v->value = error("Parse", parser.file, "unexpected keyword", current()); + return v; + } if (!matchAny(6, TRUE, FALSE, DEC, HEX, OCTAL, BIN)) return NULL; - return toValue(initLiteral(getTokenContent(parser.code, current()))); + return toValue(initLiteral(getTokenContent(parser.code, peekNext()))); } Value *varDecl(Value *t) { Value *n = parseIdentifier(t); @@ -266,7 +289,7 @@ Value *varDecl(Value *t) { Value *r = parseExpression(); if (check(r)) return freeValue(t), freeValue(n), freeValue(q), freeValue(r); match(DELMT); - return toValue(initAssignmentExpression(n->value, r->value)); + return toValue(initAssignmentExpression(n->value, r->value, ASGN_EQ)); } //* working as expected @@ -357,10 +380,12 @@ Value *parseExpression() { else if (nextIs(LPAREN)) return parseCallExpression(t); // else if (nextIs(DOT)) return chainExpr(); - else if (nextIs(EQ)) + else if (matchAny(3, EQ, ADD_EQ, SUB_EQ)) { + prev(); return parseAssignmentExpression(t); + } else - return prev(), parseIdentifier(t); + return parseIdentifier(t); } else if (matchAny(4, DEC, HEX, OCTAL, BIN)) { Value *l = toValue(current()); if (matchAny(13, ADD, SUB, MUL, DIV, LAND, LOR, BAND, BOR, BXOR, REM, @@ -470,8 +495,10 @@ Value *parseWhileStatement() { return NULL; } // todo Value *parseForStatement() { return NULL; } // todo Value *parseReturnStatement() { + debug_log("retstmt", parser.code, peekNext()); Value *retval = parseExpression(); - return retval; + if (check(retval)) return NULL; + return toValue(initReturnStatement(retval->value)); } // todo Value *parseStatement() { diff --git a/src/types.c b/src/types.c index 5e0c446..e41bb72 100644 --- a/src/types.c +++ b/src/types.c @@ -60,11 +60,12 @@ ClassDeclaration *initClassDeclaration(Identifier *n, Array *b) { return decl; } -AssignmentExpression *initAssignmentExpression(Typed *l, Typed *r) { +AssignmentExpression *initAssignmentExpression(Typed *l, Typed *r, AssignmentOperator oper) { AssignmentExpression *asgn = malloc(sizeof(AssignmentExpression)); asgn->type = ASSIGNMENT_EXPRESSION; asgn->left = l; asgn->right = r; + asgn->oper = oper; return asgn; } @@ -91,7 +92,7 @@ Identifier *initIdentifier(char *n) { TypedIdentifier *initTypedIdentifier(char *n, char *k) { TypedIdentifier *id = malloc(sizeof(TypedIdentifier)); - id->type = IDENTIFIER; + id->type = TYPED_IDENTIFIER; id->name = n; id->kind = k; return id; @@ -131,3 +132,10 @@ ExpressionStatement *initExpressionStatement(Typed *e) { stmt->expr = e; return stmt; } + +ReturnStatement *initReturnStatement(Typed *e) { + ReturnStatement *stmt = malloc(sizeof(ReturnStatement)); + stmt->type = RETURN_STATEMENT; + stmt->expr = e; + return stmt; +} \ No newline at end of file diff --git a/src/types.h b/src/types.h index 07684b1..621889c 100644 --- a/src/types.h +++ b/src/types.h @@ -68,7 +68,7 @@ typedef enum __attribute__((__packed__)) Types { DEC, //* 123 DOT, //* . DELMT, //* ; - NEWLINE, //* \n + NEWLINE, //* \n todo remove SEP, //* , AT, //* @ HASH, //* # @@ -130,7 +130,8 @@ typedef enum __attribute__((__packed__)) AST_Types { STRING_LITERAL, IDENTIFIER, TYPED_IDENTIFIER, - EXPRESSION_STATEMENT + EXPRESSION_STATEMENT, + RETURN_STATEMENT } AST_Type; typedef struct Typed { @@ -176,8 +177,8 @@ typedef struct ImportDeclaration { } ImportDeclaration; typedef struct FunctionDeclaration { - boolean async; AST_Type type; + boolean async; Identifier *name; Array *params; Array *body; @@ -200,25 +201,30 @@ typedef struct ExpressionStatement { Typed *expr; } ExpressionStatement; -typedef enum BinaryAssignmentOperators { - BIN_ASGN_EQ = 1, - BIN_ASGN_ADD_EQ, - BIN_ASGN_SUB_EQ, - BIN_ASGN_MUL_EQ, - BIN_ASGN_DIV_EQ, - BIN_ASGN_LAND_EQ, - BIN_ASGN_LOR_EQ, - BIN_ASGN_BAND_EQ, - BIN_ASGN_BOR_EQ, - BIN_ASGN_BXOR_EQ, - BIN_ASGN_REM_EQ, - BIN_ASGN_RSHIFT_EQ, - BIN_ASGN_LSHIFT_EQ -} BinaryAssignmentOperator; +typedef struct ReturnStatement { + AST_Type type; + Typed *expr; +} ReturnStatement; + +typedef enum AssignmentOperators { + ASGN_EQ = 1, + ASGN_ADD_EQ, + ASGN_SUB_EQ, + ASGN_MUL_EQ, + ASGN_DIV_EQ, + ASGN_LAND_EQ, + ASGN_LOR_EQ, + ASGN_BAND_EQ, + ASGN_BOR_EQ, + ASGN_BXOR_EQ, + ASGN_REM_EQ, + ASGN_RSHIFT_EQ, + ASGN_LSHIFT_EQ +} AssignmentOperator; typedef struct AssignmentExpression { AST_Type type; - BinaryAssignmentOperator oper; + AssignmentOperator oper; Typed *left; Typed *right; } AssignmentExpression; @@ -263,7 +269,7 @@ extern ImportSpecifier *initImportSpecifier( extern ImportDeclaration *initImportDeclaration( StringLiteral *, Array *import_specifier_array); extern AssignmentExpression *initAssignmentExpression( - Typed *left, Typed *right); + Typed *left, Typed *right, AssignmentOperator oper); extern Literal *initLiteral(char *value); extern StringLiteral *initStringLiteral(char *value); extern Identifier *initIdentifier(char *name); @@ -272,5 +278,6 @@ extern CallExpression *initCallExpression(Identifier *callee, Array *params); extern BinaryExpression *initBinaryExpression( BinaryOperator oper, Typed *left, Typed *right); extern ExpressionStatement *initExpressionStatement(Typed *expr); +extern ReturnStatement *initReturnStatement(Typed *expr); #endif diff --git a/src/util/print.c b/src/util/print.c index 3ae2fc9..77cbde0 100644 --- a/src/util/print.c +++ b/src/util/print.c @@ -152,6 +152,10 @@ void util_typelog(Typed *v) { printf( "\x1b[95mExpressionStatement\x1b[0m { \x1b[94m...\x1b[0m }\n"); break; + case RETURN_STATEMENT: + printf( + "\x1b[95mReturnStatement\x1b[0m { \x1b[94m...\x1b[0m }\n"); + break; case LITERAL: printf("\x1b[93m%s\x1b[0m\n", ((Literal *)v)->value); break; @@ -193,7 +197,8 @@ void util_linelog(Typed *v) { void tab(int indent) { for (int i = 0; i < indent; i++) { // printf("%s ", i%2 ? "" : ""); - printf("\x1b[30m \x1b[0m"); + // printf("\x1b[30m \x1b[0m"); + printf("\x1b[30m│ \x1b[0m"); } } @@ -207,9 +212,18 @@ void util_log(Typed *v, int indent, int depth) { switch (v->type) { case EXPRESSION_STATEMENT: { printf("\x1b[95mExpressionStatement\x1b[0m {\n"); - ExpressionStatement *expr = (ExpressionStatement *)v; + ExpressionStatement *stmt = (ExpressionStatement *)v; + tab(indent + 1); + util_log(stmt->expr, indent + 1, depth); + tab(indent); + printf("}\n"); + break; + } + case RETURN_STATEMENT: { + printf("\x1b[95mReturnStatement\x1b[0m {\n"); + ReturnStatement *stmt = (ReturnStatement *)v; tab(indent + 1); - util_log(expr->expr, indent + 1, depth); + util_log(stmt->expr, indent + 1, depth); tab(indent); printf("}\n"); break;