diff --git a/.gitignore b/.gitignore index b9e3ca7..56ada95 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Binaries for programs and plugins main onev +exec *.exe *.exe~ *.so diff --git a/generator.v b/generator.v index 14bf965..cd7495b 100644 --- a/generator.v +++ b/generator.v @@ -17,7 +17,7 @@ fn (mut g Generator) gen_stmt(stmt Stmt) { match stmt { VarDecl { c_type := g.get_c_type(stmt.type) - g.out.write_string('${c_type} ${stmt.name} = ') + g.out.write_string('${c_type} v${stmt.name}${stmt.scope_depth.str()} = ') g.gen_expr(stmt.value) g.out.writeln(';') } @@ -57,10 +57,9 @@ fn (mut g Generator) gen_expr(expr Expr) { g.out.write_string(expr.val.str()) } Variable { - g.out.write_string(expr.name) + g.out.write_string('v${expr.name}${expr.scope_depth.str()}') } UnaryExpr { - // Handle postfix/prefix logic if necessary g.out.write_string('${expr.ident}${expr.op}') } BinaryExpr { @@ -86,7 +85,15 @@ fn (mut g Generator) gen_expr(expr Expr) { g.out.write_string('(${c_type})') g.gen_expr(expr.expr) } - else {panic('unimplemented ${expr}')} + ParenExpr { + g.out.write_string('(') + g.gen_expr(expr.expr) + g.out.write_string(')') + } + FnCall { + g.out.write_string('${expr.name}()') + } + else {panic("Unimplemented expression")} } } diff --git a/main.v b/main.v index c732235..4cd1079 100644 --- a/main.v +++ b/main.v @@ -31,6 +31,6 @@ fn main() { out_c := generator.gen_c(statements) - compile_with_clang(out_c, 'test', true) + compile_with_clang(out_c, 'exec', true) } diff --git a/parser.v b/parser.v index cbef600..ad19de7 100644 --- a/parser.v +++ b/parser.v @@ -91,7 +91,7 @@ fn (mut s SymbolTable) is_in_global_scope() bool { // ------------------------------------------- Expressions -type Expr = VoidExpr | UnaryExpr | BinaryExpr | IntegerLiteral | RealLiteral | BoolLiteral | Variable | TypeExpr | Function | TypeCast | ParenExpr | PrintExpr +type Expr = VoidExpr | UnaryExpr | BinaryExpr | IntegerLiteral | RealLiteral | BoolLiteral | Variable | TypeExpr | Function | TypeCast | ParenExpr | PrintExpr | FnCall struct VoidExpr {} @@ -120,6 +120,7 @@ struct BoolLiteral { struct Variable { name string + scope_depth int } struct TypeExpr { @@ -144,6 +145,10 @@ struct PrintExpr { type string } +struct FnCall { + name string +} + // ------------------------------------------- Statements type Stmt = VarDecl | ExprStmt | ReturnStmt | Block | FuncDecl @@ -152,6 +157,7 @@ struct VarDecl { name string type string value Expr + scope_depth int } struct FuncDecl { @@ -253,10 +259,16 @@ fn (mut p Parser) parse_expr(prec Precedence) Expr { } fn (mut p Parser) parse_ident(ident string) Expr { - return match p.peek().type { - .increment, .decrement {UnaryExpr {ident: ident, op: p.next().text}} - else {Variable{ident}} + expr := match p.peek().type { + .increment, .decrement {Expr(UnaryExpr {ident: ident, op: p.next().text})} + .lparen { + p.expect(.lparen) + p.expect(.rparen) + FnCall{name: ident} + } + else {Variable{ident, p.symbols.variable_scopes.len}} } + return expr } fn (mut p Parser) parse_print() PrintExpr { @@ -333,6 +345,10 @@ fn (mut p Parser) get_expr_type(expr Expr) string { return info.type } TypeCast {expr.type} + FnCall { + fninfo := p.symbols.lookup_func(expr.name) or {parse_error("Tried to call undefined function ${expr.name}")} + fninfo.type + } else {"Tried getting type of unexpected Expr"} } @@ -407,6 +423,7 @@ fn (mut p Parser) parse_var_decl() VarDecl { name: name_tok.text value: val type: type_tok.text + scope_depth: p.symbols.variable_scopes.len } } @@ -463,7 +480,7 @@ fn (mut p Parser) parse_return_stmt() ReturnStmt { .integer {IntegerLiteral{token.text.int()}} .real {RealLiteral{token.text.f32()}} .boolean {BoolLiteral{token.text == 'true'}} - .identifier {Variable{token.text}} + .identifier {Variable{token.text, p.symbols.variable_scopes.len}} .semicolon {VoidExpr{}} else {parse_error("Unexpected Token")} } diff --git a/test b/test deleted file mode 100755 index f0afffd..0000000 Binary files a/test and /dev/null differ