From 22a46dc9b27fdd90e2dc307292b85bae42516e4f Mon Sep 17 00:00:00 2001 From: Baitinq Date: Fri, 11 Jul 2025 20:34:05 +0200 Subject: Boostrap: Support cast statement --- examples/0.pry | 1 + src/bootstrap/codegen.pry | 13 +++++++++++ src/bootstrap/parser.pry | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/examples/0.pry b/examples/0.pry index eb9f990..a31ab63 100644 --- a/examples/0.pry +++ b/examples/0.pry @@ -7,6 +7,7 @@ let strcmp = (stra: *i8, strb: *i8) => bool { let i = 0; while i < 10 { printf("I: %d\n", i); /* CONTINUE */ + let ca = (*(stra + cast(*i8, i))); i = i + 1; }; 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) { -- cgit 1.4.1