about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-07-11 20:34:05 +0200
committerBaitinq <[email protected]>2025-07-11 20:34:05 +0200
commit22a46dc9b27fdd90e2dc307292b85bae42516e4f (patch)
treeebfaba570113926c694702719fb85c6fd86b83ab
parentBoostrap: Parse ( expr ) (diff)
downloadpry-lang-22a46dc9b27fdd90e2dc307292b85bae42516e4f.tar.gz
pry-lang-22a46dc9b27fdd90e2dc307292b85bae42516e4f.tar.bz2
pry-lang-22a46dc9b27fdd90e2dc307292b85bae42516e4f.zip
Boostrap: Support cast statement
-rw-r--r--examples/0.pry1
-rw-r--r--src/bootstrap/codegen.pry13
-rw-r--r--src/bootstrap/parser.pry56
3 files changed, 70 insertions, 0 deletions
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) {