diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bootstrap/codegen.pry | 13 | ||||
| -rw-r--r-- | src/bootstrap/parser.pry | 56 |
2 files changed, 69 insertions, 0 deletions
diff --git a/src/bootstrap/codegen.pry b/src/bootstrap/codegen.pry index 1a81c42..50836cc 100644 --- a/src/bootstrap/codegen.pry +++ b/src/bootstrap/codegen.pry @@ -648,6 +648,19 @@ let codegen_generate_expression_value = (c: *codegen, expression: *Node, name: * if ((*expression).type == NODE_FUNCTION_CALL_STATEMENT) { return codegen_generate_function_call_statement(c, expression); }; + + if ((*expression).type == NODE_CAST_STATEMENT) { + let exp = *cast(*NODE_CAST_STATEMENT_DATA, (*expression).data); + let val = codegen_generate_expression_value(c, exp.expression, ""); + assert(val != cast(*Variable, null)); + let v = Variable{}; + v.value = (*val).value; + v.type = cast(LLVMTypeRef, null); + v.stack_level = cast(*i64, null); + v.node = expression; + v.node_type = exp.typ; + return codegen_create_variable(c, v); + }; printf("ASSERT 1: %d\n", (*expression).type); assert(false); diff --git a/src/bootstrap/parser.pry b/src/bootstrap/parser.pry index b24ec33..29aba73 100644 --- a/src/bootstrap/parser.pry +++ b/src/bootstrap/parser.pry @@ -278,6 +278,50 @@ let parser_parse_return_statement = (p: *parser) => *Node { extern parser_parse_type = (*parser) => *Node; +/* CastStatement ::= "cast" LPAREN TYPE "," Expression RPAREN */ +let parser_parse_cast_statement = (p: *parser) => *Node { + let ident = parser_accept_token(p, TOKEN_IDENTIFIER); + if ident == cast(*token, null) { + return cast(*Node, null); + }; + + if !strcmp(cast(*i8, (*ident).data), "cast") { + return cast(*Node, null); + }; + + if parser_accept_token(p, TOKEN_LPAREN) == cast(*token, null) { + return cast(*Node, null); + }; + + let typ = parser_parse_type(p); + if typ == cast(*Node, null) { + return cast(*Node, null); + }; + + if parser_accept_token(p, TOKEN_COMMA) == cast(*token, null) { + return cast(*Node, null); + }; + + let expression = parser_parse_expression(p); + if expression == cast(*Node, null) { + return cast(*Node, null); + }; + + if parser_accept_token(p, TOKEN_RPAREN) == cast(*token, null) { + return cast(*Node, null); + }; + + let d = cast(*NODE_CAST_STATEMENT_DATA , arena_alloc((*p).arena, sizeof(NODE_CAST_STATEMENT_DATA ))); + (*d).typ = typ; + (*d).expression = expression; + + let r = Node{}; + r.type = NODE_CAST_STATEMENT; + r.data = cast(*void, d); + + return create_node(p, r); +}; + /* FunctionType ::= LPAREN (Type ("," Type)*)? RPAREN ARROW Type */ let parser_parse_function_type = (p: *parser) => *Node { if parser_accept_token(p, TOKEN_LPAREN) == cast(*token, null) { @@ -756,6 +800,10 @@ let parser_parse_equality_expression = (p: *parser) => *Node { /* PostfixExpression ::= PrimaryExpression (CastStatement | SizeOfStatement | FunctionCallStatement | FieldAccess )* */ let parser_parse_postfix_expression = (p: *parser) => *Node { + let ex = parser_accept_parse(p, parser_parse_cast_statement); + if ex != cast(*Node, null) { + return ex; + }; let ex = parser_accept_parse(p, parse_function_call_statement); if ex != cast(*Node, null) { return ex; @@ -973,6 +1021,14 @@ let parse_function_call_statement = (p: *parser) => *Node { /* Statement ::= (AssignmentStatement | ImportDeclaration | ExternDeclaration | CastStatement | SizeOfStatement | FunctionCallStatement | IfStatement | WhileStatement | ReturnStatement | "break" | "continue") SEMICOLON */ let parser_parse_statement = (p: *parser) => *Node { + let fn_call = parser_accept_parse(p, parser_parse_cast_statement); + if fn_call != cast(*Node, null) { + if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) { + return cast(*Node, null); + }; + return fn_call; + }; + let fn_call = parser_accept_parse(p, parse_function_call_statement); if fn_call != cast(*Node, null) { if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) { |