aboutsummaryrefslogtreecommitdiff
path: root/kscurses/lambdas.jai
diff options
context:
space:
mode:
authordam <dam@gudinoff>2023-08-17 20:28:47 +0100
committerdam <dam@gudinoff>2023-08-17 20:28:47 +0100
commit709879ee56d31fe543a0ad882713bd4e3d17d2d2 (patch)
tree12a35282bdd0f1f8a2159ade147944c89254db24 /kscurses/lambdas.jai
parentfa1b8ea54646f1a0f3eadef33e3a660b875cc1ff (diff)
downloadtask-time-tracker-709879ee56d31fe543a0ad882713bd4e3d17d2d2.tar.zst
task-time-tracker-709879ee56d31fe543a0ad882713bd4e3d17d2d2.zip
Added kscurses and testing program.
Diffstat (limited to 'kscurses/lambdas.jai')
-rw-r--r--kscurses/lambdas.jai255
1 files changed, 255 insertions, 0 deletions
diff --git a/kscurses/lambdas.jai b/kscurses/lambdas.jai
new file mode 100644
index 0000000..fd5ffa4
--- /dev/null
+++ b/kscurses/lambdas.jai
@@ -0,0 +1,255 @@
+decl_lambda :: ($code_src : Code) -> Code #expand {
+ node_src := compiler_get_nodes(code_src);
+ proc_node, data_node, names, names_field, node_header, node_block := split_src(false, node_src);
+ pair_names, pair_srcs := get_lambda_pairs(proc_node, data_node, names, names_field, node_header, node_block);
+ return compiler_get_code(*Code_Compound_Declaration.{
+ kind = .COMPOUND_DECLARATION,
+ comma_separated_assignment = xx pair_names,
+ declaration_properties = *Code_Declaration.{
+ kind = .DECLARATION,
+ expression = pair_srcs
+ }
+ });
+}
+assign_lambda :: ($code_src : Code, parent_scope := #caller_code) #expand {
+ #insert,scope(parent_scope) #run _assign_lambda(code_src);
+}
+struct_lambda :: ($code_src : Code, parent_scope := #caller_code) #expand {
+ #insert,scope(parent_scope) #run _struct_lambda(code_src);
+}
+#scope_file
+#import "Compiler";
+#import "Basic";
+#import "Program_Print";
+debug_print_code :: (root : *Code_Node) {
+ builder := String_Builder.{allocator = temp};
+ print_expression(*builder, root);
+ print("%\n", builder_to_string(*builder, allocator = temp));
+}
+_assign_lambda :: ($code_src : Code) -> Code {
+ node_src := compiler_get_nodes(code_src);
+ proc_node, data_node, names, names_field, node_header, node_block := split_src(false, node_src);
+ pair_names, pair_srcs := get_lambda_pairs(proc_node, data_node, names, names_field, node_header, node_block);
+ node_assign := Code_Binary_Operator.{
+ kind = .BINARY_OPERATOR,
+ operator_type = #char"=",
+ left = pair_names,
+ right = pair_srcs
+ };
+ return compiler_get_code(*node_assign);
+}
+_struct_lambda :: ($code_src : Code) -> Code {
+ node_src := compiler_get_nodes(code_src);
+ proc_node, data_node, names, names_field, node_header, node_block := split_src(true, node_src);
+ pair_names, pair_srcs := get_lambda_pairs(proc_node, data_node, names, names_field, node_header, node_block);
+ node_assign := Code_Binary_Operator.{
+ kind = .BINARY_OPERATOR,
+ operator_type = #char"=",
+ left = pair_names,
+ right = pair_srcs
+ };
+ debug_print_code(*node_assign);
+ return compiler_get_code(*node_assign);
+}
+//TODO add support for non-"proc/data" names
+split_src :: (gen_pair : bool, node_src : *Code_Node) -> proc_node:*Code_Node, data_node:*Code_Node, names:[]string, names_field:[]string, node_header:*Code_Procedure_Header, node_block:*Code_Block #expand {
+ offset := ifx gen_pair then 1 else 2;
+ assert(node_src.kind == .BLOCK);
+ node_src_block := cast(*Code_Block) node_src;
+ node_src_statements := node_src_block.statements;
+ captured_count := node_src_statements.count - 2 - offset;
+ assert(captured_count >= 0);
+ names := NewArray(captured_count, string);
+ names_field := NewArray(captured_count, string);
+ for i : offset..captured_count-1+offset {
+ assert(node_src_statements[i].kind == .IDENT);
+ }
+ for i : 0..captured_count-1 {
+ name := (cast(*Code_Ident)node_src_statements[i + offset]).name;
+ names[i], names_field[i] = name, sprint("_%", name);
+ }
+ assert(node_src_statements[captured_count + offset].kind == .PROCEDURE_HEADER);
+ node_header := cast(*Code_Procedure_Header) node_src_statements[captured_count + offset];
+ assert(node_src_statements[captured_count + offset + 1].kind == .BLOCK);
+ node_block := cast(*Code_Block) node_src_statements[captured_count + offset + 1];
+ assert(node_block.block_type == .IMPERATIVE);
+ proc_node, data_node : *Code_Node;
+ if gen_pair {
+ proc_node = *Code_Binary_Operator.{
+ kind = .BINARY_OPERATOR,
+ operator_type = #char".",
+ left = node_src_statements[0],
+ right = *Code_Ident.{
+ kind = .IDENT,
+ name = "proc"
+ }
+ };
+ data_node = *Code_Binary_Operator.{
+ kind = .BINARY_OPERATOR,
+ operator_type = #char".",
+ left = node_src_statements[0],
+ right = *Code_Ident.{
+ kind = .IDENT,
+ name = "data"
+ }
+ };
+ } else {
+ proc_node, data_node = node_src_statements[0], node_src_statements[1];
+ }
+ return proc_node, data_node, names, names_field, node_header, node_block;
+}
+gen_struct_type_node :: (names : []string, names_field : []string) -> *Code_Node #expand {
+ captured_count := names.count;
+ nodes_ident := NewArray(captured_count, Code_Ident);
+ nodes_ptr := NewArray(captured_count, Code_Unary_Operator);
+ nodes_typeof := NewArray(captured_count, Code_Size_Or_Type_Info);
+ nodes_type := NewArray(captured_count, Code_Type_Instantiation);
+ nodes_declaration := NewArray(captured_count, Code_Declaration);
+ nodes_declaration_ptr := NewArray(captured_count, *Code_Node);
+ for i : 0..captured_count-1 {
+ nodes_ident[i] = .{
+ kind = .IDENT,
+ name = names[i]
+ };
+ nodes_ptr[i] = .{
+ kind = .UNARY_OPERATOR,
+ operator_type = #char"*",
+ subexpression = *(nodes_ident[i])
+ };
+ nodes_typeof[i] = .{
+ kind = .SIZE_OR_TYPE_INFO,
+ query_kind = .TYPE_OF,
+ type_of_expression = *(nodes_ptr[i])
+ };
+ nodes_type[i] = .{
+ kind = .TYPE_INSTANTIATION,
+ type_valued_expression = *(nodes_typeof[i])
+ };
+ nodes_declaration[i] = .{
+ kind = .DECLARATION,
+ name = names_field[i],
+ type_inst = *(nodes_type[i])
+ };
+ nodes_declaration_ptr[i] = *(nodes_declaration[i]);
+ }
+ node_struct := Code_Struct.{
+ kind = .STRUCT,
+ block = *Code_Block.{
+ kind = .BLOCK,
+ block_type = .DATA_DECLARATIONS,
+ statements = nodes_declaration_ptr
+ }
+ };
+ return *node_struct;
+}
+//TODO better assertions
+get_lambda_pairs :: (proc_node:*Code_Node, data_node:*Code_Node, names:[]string, names_field:[]string, node_header:*Code_Procedure_Header, node_block:*Code_Block) -> pair_names:*Code_Node, pair_srcs:*Code_Node #expand {
+ node_0 := gen_struct_type_node(names, names_field);
+ stat_count := node_block.statements.count;
+ nodes_new_statements := NewArray(stat_count + 1, *Code_Node);
+ for i : 0..stat_count-1 {
+ nodes_new_statements[i + 1] = node_block.statements[i];
+ }
+ nodes_new_statements[0] = *Code_Using.{
+ kind = .USING,
+ expression = *Code_Cast.{
+ kind = .CAST,
+ target_type = *Code_Type_Instantiation.{
+ kind = .TYPE_INSTANTIATION,
+ type_valued_expression = *Code_Unary_Operator.{
+ kind = .UNARY_OPERATOR,
+ subexpression = node_0,
+ operator_type = #char"*"
+ }
+ },
+ expression = *Code_Ident.{
+ kind = .IDENT,
+ name = "__data"
+ }
+ }
+ };
+ arg_count := node_header.arguments.count;
+ node_new_args := NewArray(arg_count + 1, *Code_Declaration);
+ for i : 0..arg_count-1 {
+ node_new_args[i] = node_header.arguments[i];
+ }
+ node_new_args[arg_count] = *Code_Declaration.{
+ kind = .DECLARATION,
+ name = "__data",
+ type_inst = *Code_Type_Instantiation.{
+ kind = .TYPE_INSTANTIATION,
+ type_valued_expression = *Code_Unary_Operator.{
+ kind = .UNARY_OPERATOR,
+ operator_type = #char"*",
+ subexpression = *Code_Ident.{
+ kind = .IDENT,
+ name = "void"
+ }
+ }
+ }
+ };
+ nodes_13 := NewArray(names.count, Code_Ident);
+ nodes_14 := NewArray(names.count, Code_Unary_Operator);
+ nodes_14_ptr := NewArray(names.count, *Code_Node);
+ for i : 0..names.count-1 {
+ nodes_13[i] = Code_Ident.{
+ kind = .IDENT,
+ name = names[i]
+ };
+ nodes_14[i] = Code_Unary_Operator.{
+ kind = .UNARY_OPERATOR,
+ subexpression = *(nodes_13[i]),
+ operator_type = #char"*"
+ };
+ nodes_14_ptr[i] = *(nodes_14[i]);
+ }
+ exprs : [2]*Code_Node;
+ exprs[0] = *Code_Procedure_Header.{
+ kind = .PROCEDURE_HEADER,
+ arguments = node_new_args,
+ returns = node_header.returns,
+ body_or_null = *Code_Procedure_Body.{
+ kind = .PROCEDURE_BODY,
+ block = *Code_Block.{
+ kind = .BLOCK,
+ statements = nodes_new_statements
+ }
+ }
+ };
+ exprs[1] = *Code_Unary_Operator.{
+ kind = .UNARY_OPERATOR,
+ operator_type = #char"*",
+ subexpression = *Code_Literal.{
+ kind = .LITERAL,
+ value_type = .STRUCT,
+ struct_literal_info = *Code_Struct_Literal_Info.{
+ type_expression = *Code_Type_Instantiation.{
+ kind = .TYPE_INSTANTIATION,
+ type_valued_expression = node_0
+ },
+ arguments = nodes_14_ptr
+ }
+ }
+ };
+ _exprs : [2]Code_Comma_Separated_Argument = .[
+ .{exprs[0], .NONE},
+ .{exprs[1], .NONE},
+ ];
+ node_19 := Code_Comma_Separated_Arguments.{
+ kind = .COMMA_SEPARATED_ARGUMENTS,
+ arguments = _exprs
+ };
+ exprs2 : [2]*Code_Node;
+ exprs2[0] = proc_node;
+ exprs2[1] = data_node;
+ _exprs2 : [2]Code_Comma_Separated_Argument = .[
+ .{exprs2[0], .NONE},
+ .{exprs2[1], .NONE},
+ ];
+
+ node_22 := Code_Comma_Separated_Arguments.{
+ kind = .COMMA_SEPARATED_ARGUMENTS,
+ arg = _exprs2
+ };
+ return *node_22, *node_19;
+}