From 5de2e1fd9f426348127a66d2c51c300cb90cc3a4 Mon Sep 17 00:00:00 2001 From: Carlos Maniero Date: Wed, 10 May 2023 00:20:00 -0300 Subject: gas: Generate code for if statement If statements are now working, the only exception is for the comparators || and && that will be addressed in a further commit. Checks tested: fn main(): i32 { let n: i32 = 11; if (n == 11) { if n != 12 { if n < 12 { if n <= 11 { if n > 10 { if n >= 11 { return 42; } } } } } } return n; } To compile the && and || a precedence issue must be addressed: they must have the highest precedence, witch is not working now: 1 == 2 || 3 != 2 The or should be the higher level of the tree in the example above. Signed-off-by: Carlos Maniero --- src/gas_assembly_generator.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gas_assembly_generator.h') diff --git a/src/gas_assembly_generator.h b/src/gas_assembly_generator.h index 92972f9..3d9a43c 100644 --- a/src/gas_assembly_generator.h +++ b/src/gas_assembly_generator.h @@ -46,6 +46,7 @@ typedef struct gas_assembly_generator_t FILE *stream; vector_t *refs; int stack_offset; + uint64_t label_counter; evaluation_result_t latest_evaluation; } gas_assembly_generator_t; -- cgit v1.2.3 From 88630ebbea03e85119cf9795320a83cb846bdd20 Mon Sep 17 00:00:00 2001 From: Carlos Maniero Date: Wed, 10 May 2023 01:43:40 -0300 Subject: gas: Implement && and || for if statements Now if statements are complete! The function %gas_assembly_generator_compile_condition% is generic and will be used for any other flow-control statment. The only requirement to it work is having two labels: One to jump when the condition is true, and another one when the condition is false. Signed-off-by: Carlos Maniero --- src/gas_assembly_generator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gas_assembly_generator.h') diff --git a/src/gas_assembly_generator.h b/src/gas_assembly_generator.h index 3d9a43c..2e195fb 100644 --- a/src/gas_assembly_generator.h +++ b/src/gas_assembly_generator.h @@ -46,7 +46,7 @@ typedef struct gas_assembly_generator_t FILE *stream; vector_t *refs; int stack_offset; - uint64_t label_counter; + uint64_t cur_label_index; evaluation_result_t latest_evaluation; } gas_assembly_generator_t; -- cgit v1.2.3 From a96a0cac034e16dcd7455a3b2fabf2b5b3e716bd Mon Sep 17 00:00:00 2001 From: Carlos Maniero Date: Wed, 10 May 2023 12:20:04 -0300 Subject: gas: Compile boolean variable assignment When the assignment value is a literal, it just assigns zero or one to the variable stack's location. If the value is an expression, it compiles the expression and assign zeros and ones based on expression result. --- src/gas_assembly_generator.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gas_assembly_generator.h') diff --git a/src/gas_assembly_generator.h b/src/gas_assembly_generator.h index 2e195fb..e400d2c 100644 --- a/src/gas_assembly_generator.h +++ b/src/gas_assembly_generator.h @@ -26,12 +26,14 @@ typedef enum evaluation_result_kind_t EVALUATION_RESULT_VOID, EVALUATION_RESULT_ON_RAX, EVALUATION_RESULT_ON_STACK, - EVALUATION_RESULT_AS_LITERAL_INTEGER + EVALUATION_RESULT_AS_LITERAL_INTEGER, + EVALUATION_RESULT_AS_LITERAL_BOOL } evaluation_result_kind_t; typedef union evaluation_result_data_t { int64_t literal_int; + bool literal_bool; int stack_offset; } evaluation_result_data_t; -- cgit v1.2.3 From 2cf0bcb409f3a1fd298b664103d57c945c6349f5 Mon Sep 17 00:00:00 2001 From: Carlos Maniero Date: Wed, 10 May 2023 14:26:40 -0300 Subject: gas: Removes Linux entrypoint logic from function declaration Before this commit, function declarations were making syscalls to interrupt the flow. This is a fair approach considering all our examples just have a main function. But won't work if the namespace has more then a single function. The return now always sets the return value on RAX and jumps to the function return label. The function return label, will restore RBP and jump back to callee's next instruction using RET instruction. Function labels are kept, which means that a function called my_fn will have the assembly label my_fn, so then, they can have INTEROP with other languages. Signed-off-by: Carlos Maniero --- src/gas_assembly_generator.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/gas_assembly_generator.h') diff --git a/src/gas_assembly_generator.h b/src/gas_assembly_generator.h index e400d2c..18ffb7f 100644 --- a/src/gas_assembly_generator.h +++ b/src/gas_assembly_generator.h @@ -48,7 +48,8 @@ typedef struct gas_assembly_generator_t FILE *stream; vector_t *refs; int stack_offset; - uint64_t cur_label_index; + uint64_t counter_label_index; + uint64_t return_label_index; evaluation_result_t latest_evaluation; } gas_assembly_generator_t; @@ -58,4 +59,7 @@ gas_assembly_generator_init(gas_assembly_generator_t *gen, FILE *stream); void gas_assembly_generator_compile(gas_assembly_generator_t *gen, ast_node_t *ast); +void +gas_assembly_generator_compile_linux_main(gas_assembly_generator_t *gen, ast_node_t *func); + #endif /* GAS_ASSEMBLY_GENERATOR_H */ -- cgit v1.2.3 From 75639fbf01bd6ae1212521b6cf822025eb8b598d Mon Sep 17 00:00:00 2001 From: Carlos Maniero Date: Wed, 10 May 2023 16:07:39 -0300 Subject: namespaces: Add a namespace structure that represents a file We have been always parsing a single function. Since we want to have multiple functions in a near future, this patch introduces an namespace that represents an entire file. To ensure a function is defined inside a namespace, a helper function was created. Today our ast_node structure is highly exposed, and this is something that Johnny and I have been discussed. So then, this is a first step to try to protected the code generation from our ast tree. Signed-off-by: Carlos Maniero --- src/gas_assembly_generator.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gas_assembly_generator.h') diff --git a/src/gas_assembly_generator.h b/src/gas_assembly_generator.h index 18ffb7f..26aa87b 100644 --- a/src/gas_assembly_generator.h +++ b/src/gas_assembly_generator.h @@ -59,6 +59,9 @@ gas_assembly_generator_init(gas_assembly_generator_t *gen, FILE *stream); void gas_assembly_generator_compile(gas_assembly_generator_t *gen, ast_node_t *ast); +void +gas_assembly_generator_compile_ns(gas_assembly_generator_t *gen, ast_namespace_t *ns); + void gas_assembly_generator_compile_linux_main(gas_assembly_generator_t *gen, ast_node_t *func); -- cgit v1.2.3