2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
19 private unit compiler.parser.parser;
21 uses compiler.parser.token;
22 uses compiler.parser.dict;
24 fn parse_lambda_function(ctx : function_context, parent_vd : variable_dictionary, t : tokens) : (function_context, list(int));
25 fn parse_file~cache(w : world, d : list(bytes), name : bytes, program : bool, parse_interface : bool) : function_dictionary;
31 uses compiler.parser.gen;
32 uses compiler.parser.gen2;
33 uses compiler.parser.expression;
34 uses compiler.parser.alloc;
35 uses compiler.parser.statement;
36 uses compiler.parser.util;
37 uses compiler.parser.local_type;
38 uses compiler.parser.export;
40 record promoted_variable [
49 fn add_promoted_variable(ctx : function_context, cc : compare_context, vd : variable_dictionary, v : int, pv : promoted_variable) : (function_context, variable_dictionary)
52 ctx, typ := evaluate_type(ctx, cc, pv.typ, empty(compare_fn_stack), empty(token));
55 if pv.cnst or pv.mut then
56 defined := defined_argument;
58 defined := defined_multiple;
60 var nv : local_variable;
61 ctx, nv := new_variable(ctx, typ, defined, pv.mut);
62 ctx.variables[v] := nv;
64 ctx, vd := add_variable(ctx, vd, pv.name, v, pv.impl, empty(token));
69 fn parse_argument(ctx : function_context, vd : variable_dictionary, v n : int, t : tokens, cnst mut retval : bool) : function_context
72 ctx, a := parse_expression_type(ctx, vd, t);
80 defined := defined_argument;
82 defined := defined_multiple;
84 defined := defined_argument;
88 var nv : local_variable;
89 ctx, nv := new_variable(ctx, a, defined, mut);
90 ctx.variables[v + i] := nv;
96 fn parse_arguments(ctx : function_context, vd : variable_dictionary, t : tokens, retval : bool, v : int, cnst : bool) : (function_context, variable_dictionary)
98 if retval and ctx.inferred_return then [
99 for i := 0 to ctx.n_return_values do [
100 var nv : local_variable;
101 ctx, nv := new_variable(ctx, T_InvalidType, defined_argument, false);
102 ctx.variables[v + i] := nv;
106 if len_at_least(t, 2), t[0].t is left_paren and t[0].bracket_skip = len(t) - 1 then [
107 t := t[1 .. len(t) - 1];
110 while len(t) > 0 do [
113 decl, t := split_tokens(t, token_opt.comma);
120 if len(decl) > 0 then [
121 if decl[0].t is k_const then [
126 if decl[0].t is k_mutable then [
131 if decl[0].t is k_implicit then [
138 if cnst and mut then [
139 abort compiler_error("Mutable and const can't be specified together", t);
142 var colon := token_find_colon(decl);
145 var expression := decl[colon + 1 .. ];
146 ctx := parse_argument(ctx, vd, v, colon, expression, cnst, mut, retval);
147 for i := 0 to colon do [
148 var name := decl[i].t.identifier;
149 ctx, vd := add_variable(ctx, vd, name, v, impl, decl);
153 ctx := parse_argument(ctx, vd, v, 1, decl, cnst, mut, retval);
161 fn count_arguments(t : tokens, retval : bool) : int
164 var in_parens := false;
166 if len(t) >= 2, t[0].t is left_paren and t[0].bracket_skip = len(t) - 1 then [
167 t := t[1 .. len(t) - 1];
171 if retval and len(t) = 0 then
172 abort compiler_error("Function has no return value", t);
174 while len(t) > 0 do [
177 decl, t := split_tokens(t, token_opt.comma);
178 if not in_parens and len(t) > 0 then
179 abort compiler_error("Multiple return values must be in parentheses", t);
183 if len(decl) > 0 then [
184 if decl[0].t is k_const then [
188 if decl[0].t is k_mutable then [
192 if decl[0].t is k_implicit then [
199 var colon := token_find_colon(decl);
211 fn parse_function_header(dict : function_dictionary, parent_function : maybe(function_context), parent_vd : maybe(variable_dictionary), promoted_variables : list(promoted_variable), decl_type : token_opt, t : tokens, name : istring, op_mode : op_option, op_priority : int, cnst : bool) : (function_context, variable_dictionary)
213 var inferred_return := false;
214 var arguments : tokens;
215 var return_values : tokens;
217 if len(t) > 0, t[0].t is left_paren then [
218 var matching_paren := t[0].bracket_skip;
219 arguments := t[ .. matching_paren + 1];
220 t := t[matching_paren + 1 .. ];
222 arguments := empty(token);
225 if decl_type is k_fn or decl_type is k_const or decl_type is k_operator then [
226 if decl_type is k_const and len(arguments) > 0 then [
227 abort compiler_error("Constant can't have arguments", arguments);
230 inferred_return := true;
231 return_values := empty(token);
233 xeval token_assert(t, token_opt.colon);
234 return_values := t[1 .. ];
238 abort compiler_error("Unexpected tokens", t);
239 return_values := tokenize("type", "_internal");
242 var n_arguments n_return_values : int;
243 n_arguments := count_arguments(arguments, false);
244 if not inferred_return then
245 n_return_values := count_arguments(return_values, true);
247 n_return_values := 1;
249 if (op_mode is prefix_op or op_mode is postfix_op) and n_arguments < 1 then
250 abort compiler_error("Insufficient arguments for an operator", t);
251 if op_mode is infix_op and n_arguments < 2 then
252 abort compiler_error("Insufficient arguments for an operator", t);
254 n_arguments += len(promoted_variables);
256 var ctx := new_function_context(dict, parent_function, n_arguments, n_return_values, name);
257 ctx.inferred_return := inferred_return;
258 ctx.op_mode := op_mode;
259 ctx.op_priority := op_priority;
261 ctx := generate_Args(ctx);
263 var vd := new_variable_dictionary(parent_vd);
265 if len(promoted_variables) > 0 then [
266 var cc := new_compare_context_from_function(ctx.parent_function.j);
267 cc.lambda_redirect := fill(-1, len(cc.ctx.variables));
268 for i := 0 to len(promoted_variables) do [
269 cc.lambda_redirect[promoted_variables[i].v] := i;
271 for i := 0 to len(promoted_variables) do [
272 ctx, vd := add_promoted_variable(ctx, cc, vd, i, promoted_variables[i]);
276 ctx, vd := parse_arguments(ctx, vd, arguments, false, len(promoted_variables), cnst);
278 ctx := generate_Return_Vars(ctx);
280 var vd2 := new_variable_dictionary_chained(ctx, vd);
281 ctx, vd2 := parse_arguments(ctx, vd2, return_values, true, n_arguments, false);
283 ctx.incomplete := false;
288 fn parse_function_body(ctx : function_context, vd : variable_dictionary, t : tokens) : function_context
291 ctx, lbl := alloc_local_label(ctx);
293 abort internal("The first label should be zero");
295 if t[0].t is assign then [
296 var new_tokens := empty(token);
297 var skip := 2 + len(t[1 .. ]);
298 var nt := new_token(t[0], token_opt.left_bracket);
299 nt.bracket_skip := skip;
301 nt := new_token(t[0], token_opt.k_return);
303 new_tokens += t[1 .. ];
304 nt := new_token(t[0], token_opt.right_bracket);
305 nt.bracket_skip := -skip;
312 ctx, left, term := parse_statement(ctx, vd, true, t);
314 if len(left) > 0 then
315 abort compiler_error("Tokens after the end of the function", left);
317 abort compiler_error("The function must end with terminating statement", t[len(t) - 1 .. ]);
319 ctx := generate_Label(ctx, lbl);
321 ctx := generate_Return(ctx);
323 for i := 0 to len(ctx.list_of_used_labels) do [
324 var name := ctx.list_of_used_labels[i];
325 if not ctx.defined_labels[name] then
326 abort compiler_error("Label " + i_decode(name) + " was not defined", t);
329 for i := 0 to ctx.n_return_values do [
330 var v := ctx.n_arguments + i;
331 if get_type_of_var(ctx, v) = T_InvalidType then
332 abort compiler_error("Return type was not inferred", t);
338 fn parse_record_definition(ctx : function_context, orig_vd : variable_dictionary, is_option : bool, t : tokens) : function_context
341 var def := new_record_definition(is_option);
342 var fields := empty(int);
343 t := t[1 .. len(t) - 1];
344 while len_greater_than(t, 0) do [
345 var semicolon := token_find(t, token_opt.semicolon, true);
346 var decl := t[ .. semicolon];
350 if len_greater_than(decl, 0) then [
351 if not is_option, decl[0].t is k_const then [
358 var colon := token_find_colon(decl);
359 if not is_option and colon = -1 then
360 abort compiler_error("No declared variable", t);
361 t := t[semicolon + 1 .. ];
364 var accessing_other := false;
367 var expr := decl[colon + 1 .. ];
368 var new_ctx : function_context;
369 new_ctx, a := parse_expression_type(ctx, orig_vd, expr);
370 if is_exception new_ctx, exception_type new_ctx = error_compiler_error then [
371 ctx, a := parse_expression_type(ctx, vd, expr);
372 accessing_other := true;
379 def.is_flat_option := true;
385 for i := 0 to colon do [
386 var idx := len(def.entries);
387 xeval token_assert(decl, token_opt.identifier.(0));
388 var name := decl[0].t.identifier;
390 var found := def.dict[name];
391 if not is_uninitialized(found) then
392 abort compiler_error("Entry " + i_decode(name) + " already defined", t);
393 if not is_option then [
395 ctx, l := alloc_local_variable(ctx, a, cnst, false);
396 ctx := generate_Load_Local_Type(ctx, -1, idx, l);
397 ctx, vd := add_variable(ctx, vd, name, l, false, decl);
399 def.dict[name] := idx;
400 def.entries +<= record_entry.[ type_idx : a, cnst : cnst, accessing_other : accessing_other ];
404 if not is_option then
405 ctx := generate_Record_Type(ctx, fields, ctx.n_arguments);
407 ctx := generate_Option_Type(ctx, fields, ctx.n_arguments);
408 ctx := generate_Return(ctx);
409 ctx.record_def := maybe(record_definition).j.(def);
413 fn compare_function_signatures(c1 c2 : function_context) : bool
415 if c1.inferred_return or c2.inferred_return then
418 if ord c1.op_mode <> ord c2.op_mode then
420 if c1.op_priority <> c2.op_priority then
423 if c1.n_arguments <> c2.n_arguments then
425 if c1.n_return_values <> c2.n_return_values then
428 if len(c1.variables) <> len(c2.variables) then
430 for i := 0 to len(c1.variables) do [
431 var v1 := c1.variables[i];
432 var v2 := c2.variables[i];
433 if v1.type_idx <> v2.type_idx then
435 if v1.mut <> v2.mut then
437 if v1.local_type <> v2.local_type then
441 if len(c1.instructions) <> len(c2.instructions) then
443 for i := 0 to len(c1.instructions) do [
444 var i1 := c1.instructions[i];
445 var i2 := c2.instructions[i];
446 if i1.opcode <> i2.opcode then
448 if len(i1.args) <> len(i2.args) then
450 for j := 0 to len(i1.args) do
451 if i1.args[j] <> i2.args[j] then
458 fn is_function_simple(ctx : function_context) : bool
460 if ctx.n_labels > 1 then
463 for i := 0 to len(ctx.variables) do [
464 if ctx.variables[i].defined_at = defined_multiple or ctx.variables[i].mut then
471 fn parse_function(dict : function_dictionary, t : tokens, private_flag implicit_flag conversion_flag : bool) : function_dictionary
473 var decl_type := t[0].t;
476 var op_mode : op_option;
477 var op_priority : int;
478 var post_hints : list(bytes);
479 if decl_type is k_operator then [
480 op_mode := op_option.infix_op;
482 var name_sfx := op_name;
483 if len_at_least(t, 1), t[0].t is k_prefix then [
485 op_mode := op_option.prefix_op;
486 name_sfx := op_prefix_name;
487 ] else if len_at_least(t, 1), t[0].t is k_postfix then [
489 op_mode := op_option.postfix_op;
491 if len_at_least(t, 2), t[0].t is oper then
493 else if len_at_least(t, 2), t[0].t is identifier then
494 name := t[0].t.identifier;
496 abort compiler_error("Operator expected", t);
497 name := i_append(name, name_sfx);
498 xeval token_assert(t[1 .. ], token_opt.number.(""));
499 //op_priority := ston(t[1].t.number);
500 op_priority := instance_number_int.from_bytes(t[1].t.number);
501 post_hints := t[1].post_hints;
504 xeval token_assert(t[1 .. ], token_opt.identifier.(0));
505 name := t[1].t.identifier;
506 post_hints := t[1].post_hints;
507 op_mode := op_option.function;
511 call_mode := get_call_mode(post_hints, true);
514 var vd : variable_dictionary;
515 var ctx : function_context;
516 var cnst := decl_type is k_record or decl_type is k_option;
518 var def := search_function_dictionary(dict, name);
520 if t[len(t) - 1].t is right_bracket then [
521 b := token_find(t, token_opt.left_bracket, true);
522 if b = 0, not is_uninitialized(def) then [
523 ctx := def.signature;
525 //eval debug("implicit args 1: " + i_decode(name));
527 ctx, vd := parse_function_header(dict, maybe(function_context).n, maybe(variable_dictionary).n, empty(promoted_variable), decl_type, t[ .. b], name, op_mode, op_priority, cnst);
530 b := token_find(t, token_opt.assign, false);
531 if b = 0, not is_uninitialized(def) then [
532 ctx := def.signature;
534 //eval debug("implicit args 2: " + i_decode(name));
535 ] else if b >= 0 then [
537 ctx, vd := parse_function_header(dict, maybe(function_context).n, maybe(variable_dictionary).n, empty(promoted_variable), decl_type, t[ .. b], name, op_mode, op_priority, cnst);
539 ctx, vd := parse_function_header(dict, maybe(function_context).n, maybe(variable_dictionary).n, empty(promoted_variable), decl_type, t[ .. len(t) - 1], name, op_mode, op_priority, cnst);
543 if not is_uninitialized(def) then [
544 //eval debug(i_decode(name) + " exists");
545 if not compare_function_signatures(def.signature, ctx) then
546 abort compiler_error("Function type doesn't match previous definition", t);
547 if call_mode <> Call_Mode_Unspecified, call_mode <> def.call_mode then
548 abort compiler_error("Call mode doesn't match previous definition", t);
551 dict.defs[dict.dict[name]].private_flag := true;
553 if implicit_flag then
554 dict.impl +<= def.signature.id.function_index[0];
556 if conversion_flag then
557 dict.conv +<= def.signature.id.function_index[0];
559 // propagate the "const" flags from ctx
560 dict.defs[dict.dict[name]].signature.variables := ctx.variables;
561 def.signature.variables := ctx.variables;
563 //eval debug(i_decode(name) + " doesn't exist");
565 var op_bypass_reverse := false;
566 if decl_type is k_const and call_mode = Call_Mode_Unspecified then
567 call_mode := Call_Mode_Inline;
568 if (decl_type is k_type or decl_type is k_record or decl_type is k_option) and call_mode = Call_Mode_Unspecified then
569 call_mode := Call_Mode_Type;
571 if function_context_is_privileged(ctx) then [
572 for i := 0 to len(post_hints) do [
573 var h := post_hints[i];
574 if list_begins_with(h, "Bin_") or list_begins_with(h, "Un_") then [
575 if list_ends_with(h, "_") then [
576 op_bypass_reverse := true;
577 h := h[ .. len(h) - 1];
579 op_bypass := name_to_value[i_encode(h)];
580 //eval debug("bypass: " + i_decode(name) + ", " + ntos(op_bypass));
585 dict, def := add_function(dict, name, ctx, vd, call_mode, op_bypass, op_bypass_reverse, private_flag, implicit_flag, conversion_flag);
589 if def.body is j then
590 abort compiler_error("Function body was already defined", t);
592 ctx := def.signature;
593 ctx.incomplete := true;
596 ctx := generate_Line_Info_Full(ctx, i_decode(dict.id.unit_string), i_decode(name), t[0].line);
598 if decl_type is k_fn or decl_type is k_type or decl_type is k_const or decl_type is k_operator then [
599 dict.defs[def.signature.id.function_index[0]].typ := Fn_Function;
600 ctx := parse_function_body(ctx, vd, t[b .. ]);
601 if def.call_mode = Call_Mode_Type or def.call_mode = Call_Mode_Flat then [
602 if not is_function_simple(ctx) then
603 abort compiler_error("Type function must be simple (no conditions and no non-const variables)", t);
605 ] else if decl_type is k_record then [
606 dict.defs[def.signature.id.function_index[0]].typ := Fn_Record;
607 ctx := parse_record_definition(ctx, vd, false, t[b .. ]);
608 ] else if decl_type is k_option then [
609 dict.defs[def.signature.id.function_index[0]].typ := Fn_Option;
610 ctx := parse_record_definition(ctx, vd, true, t[b .. ]);
612 abort internal("invalid decl_type " + ntos(ord decl_type));
615 ctx := generate_local_types(ctx);
617 ctx.incomplete := false;
618 ctx := function_context_clear_temp_values(ctx);
620 dict.defs[def.signature.id.function_index[0]].body.j := ctx;
621 if def.signature.inferred_return then
622 dict.defs[def.signature.id.function_index[0]].signature := ctx;
624 if def.signature.inferred_return then
625 abort compiler_error("Function with inferred return type was not defined", t);
628 // uncomment this to disable lazy evaluation of functions
634 fn parse_lambda_function(ctx : function_context, parent_vd : variable_dictionary, t : tokens) : (function_context, list(int))
636 var promoted_variables := empty(promoted_variable);
637 var pv : promoted_variable;
639 var variable : istring;
640 var variable_idx : int;
642 var implicit_variables := get_implicit_variables(parent_vd);
643 implicit_variables := list_reverse(implicit_variables);
645 var prev_hints := t[0].prev_hints;
646 var call_mode := get_call_mode(prev_hints, true);
649 if t[len(t) - 1].t is right_bracket then [
650 b := token_find(t, token_opt.left_bracket, true);
652 b := token_find(t, token_opt.assign, true);
655 var fn_name := i_decode(ctx.name) + "/" + ntos(len(ctx.lambdas));
657 for i := 0 to len(implicit_variables) do [
659 variable_idx := implicit_variables[i];
660 pv := promoted_variable.[
663 cnst : ctx.variables[variable_idx].defined_at <> defined_multiple,
664 mut : ctx.variables[variable_idx].mut,
665 impl : list_search(implicit_variables, variable_idx) >= 0,
666 typ : ctx.variables[variable_idx].type_idx,
668 promoted_variables +<= pv;
670 var ctx_test := new_function_context(ctx.dict, maybe(function_context).j.(ctx), 0, 0, i_encode(fn_name));
671 var vd := new_variable_dictionary(maybe(variable_dictionary).j.(parent_vd));
673 if len(promoted_variables) > 0 then [
674 var cc := new_compare_context_from_function(ctx);
675 cc.lambda_redirect := fill(-1, len(cc.ctx.variables));
676 for i := 0 to len(promoted_variables) do [
677 cc.lambda_redirect[promoted_variables[i].v] := i;
679 for i := 0 to len(promoted_variables) do [
680 ctx_test, vd := add_promoted_variable(ctx, cc, vd, i, promoted_variables[i]);
684 ctx_test, vd := parse_arguments(ctx_test, vd, empty(token), false, len(promoted_variables), false);
686 if is_exception ctx_test, exception_type ctx_test = error_user3 then [
687 variable_idx := exception_aux ctx_test;
688 promoted_variables := promoted_variables[ .. len(promoted_variables) - 1];
689 pv := promoted_variable.[
692 cnst : ctx.variables[variable_idx].defined_at <> defined_multiple,
693 mut : ctx.variables[variable_idx].mut,
694 impl : list_search(implicit_variables, variable_idx) >= 0,
695 typ : ctx.variables[variable_idx].type_idx,
697 promoted_variables +<= pv;
703 var ctx_head, vd := parse_function_header(ctx.dict, maybe(function_context).j.(ctx), maybe(variable_dictionary).j.(parent_vd), promoted_variables, token_opt.k_fn, t[ .. b], i_encode(fn_name), op_option.function, -1, false);
704 if is_exception ctx_head, exception_type ctx_head = error_user2 then [
705 variable := i_encode(exception_payload ctx_head);
708 if is_exception ctx_head, exception_type ctx_head = error_user3 then [
709 variable_idx := exception_aux ctx_head;
713 ctx_head.incomplete := false;
714 var ctx_body := ctx_head;
715 ctx_body.incomplete := true;
716 ctx_body := generate_Line_Info_Full(ctx_body, i_decode(ctx.dict.id.unit_string), fn_name, t[0].line);
717 ctx_body := parse_function_body(ctx_body, vd, t[b .. ]);
718 if is_exception ctx_body, exception_type ctx_body = error_user2 then [
719 variable := i_encode(exception_payload ctx_body);
722 if is_exception ctx_body, exception_type ctx_body = error_user3 then [
723 variable_idx := exception_aux ctx_body;
727 if call_mode = Call_Mode_Type or call_mode = Call_Mode_Flat then
728 if not is_function_simple(ctx_body) then
729 abort compiler_error("Type function must be simple (no conditions and no non-const variables)", t);
731 ctx_body := generate_local_types(ctx_body);
732 ctx_body.incomplete := false;
734 if ctx_head.inferred_return then
735 ctx_head := ctx_body;
737 var fd : function_definition;
738 ctx, fd := add_lambda(ctx, ctx_head, ctx_body, call_mode);
740 if fd.signature.n_arguments = 0 then [
742 ctx, q := generate_Call(ctx, call_mode, fd, empty(int), t);
743 if len(q) <> fd.signature.n_return_values then
744 abort internal("parse_lambda_function: invalid number of return values");
748 ctx, l := generate_Load_Fn(ctx, fd, t);
749 if len(promoted_variables) = 0 then
751 var args := fill(T_InvalidType, len(promoted_variables));
752 for i := 0 to len(promoted_variables) do
753 args[i] := promoted_variables[i].v;
754 var cc, typ := get_deep_type_of_var(ctx, l);
755 cc := set_llt_main(cc, typ);
756 for i := 0 to len(promoted_variables) do
757 cc.llt_redirect +<= new_compare_argument(new_compare_context(ctx), args[i]);
758 ctx, l := generate_Curry(ctx, cc, typ, l, args, t);
759 if len(promoted_variables) = fd.signature.n_arguments then [
761 ctx, q := generate_Call_Indirect(ctx, call_mode, l, t);
762 if len(q) <> fd.signature.n_return_values then
763 abort internal("parse_lambda_function: invalid number of return values");
770 variable_idx := search_variable_dictionary(parent_vd, variable);
772 if variable_idx = -1 then
773 abort internal("Variable " + i_decode(variable) + " not found in parent function");
774 //if ctx.variables[variable_idx].type_idx >= 0 then
775 // abort compiler_error("Variable " + i_decode(variable) + " doesn't have a simple type", t);
777 for i := 0 to len(promoted_variables) do [
778 if promoted_variables[i].v = variable_idx then [
779 promoted_variables[i].name := variable;
784 pv := promoted_variable.[
787 cnst : ctx.variables[variable_idx].defined_at <> defined_multiple,
788 mut : ctx.variables[variable_idx].mut,
789 impl : list_search(implicit_variables, variable_idx) >= 0,
790 typ : ctx.variables[variable_idx].type_idx,
793 promoted_variables +<= pv;
797 if len(promoted_variables) > 0 then
798 promoted_variables := promoted_variables[ .. len(promoted_variables) - 1];
799 pv := promoted_variable.[
802 cnst : ctx.variables[variable_idx].defined_at <> defined_multiple,
803 mut : ctx.variables[variable_idx].mut,
804 impl : list_search(implicit_variables, variable_idx) >= 0,
805 typ : ctx.variables[variable_idx].type_idx,
807 promoted_variables +<= pv;
811 fn parse_unit_name(unit_tokens : tokens) : bytes
815 for i := 0 to len(unit_tokens) do [
816 var s := token_opt_to_string(unit_tokens[i].t, true);
820 if len(file_name) = 0 then [
822 abort compiler_error("invalid unit name", unit_tokens);
825 for i := 0 to len(file_name) do [
826 if path_is_separator(file_name[i]) then
828 if file_name[i] = '.' then [
829 if i = 0 or i = len(file_name) - 1 then
831 if path_is_separator(file_name[i - 1]) then
840 fn merge_interfaces(dict new_dict : function_dictionary) : function_dictionary
842 var m_id := encode_module_id(new_dict.id);
843 if not is_uninitialized(dict.modules_map[m_id]) then
845 dict.modules_map[m_id] := len(dict.modules);
846 dict.modules +<= new_dict;
847 for i := 0 to len(new_dict.modules) do
848 dict := merge_interfaces(dict, new_dict.modules[i]);
852 fn parse_uses(w : world, d : list(bytes), dict : function_dictionary, t : tokens) : function_dictionary
854 var file := parse_unit_name(t);
857 var first := i = len(d) - 1;
860 xfile := dict.name_prefix + xfile;
861 var new_dict := parse_file(w, d[ .. i + 1], xfile, false, true);
862 if is_exception new_dict, exception_class new_dict = ec_syscall then [
866 if new_dict.priv, not first, not is_privileged then [
870 dict := merge_interfaces(dict, new_dict);
873 abort compiler_error("Unit '" + file + "' not found", t);
877 fn parse_system_unit(w : world, d : list(bytes), dict : function_dictionary) : function_dictionary
879 var new_dict := parse_file(w, d[ .. 1], "system", false, true);
880 dict := merge_interfaces(dict, new_dict);
884 fn parse_define(dict : function_dictionary, t : tokens) : function_dictionary
886 xeval token_assert(t[1 .. ], token_opt.identifier.(0));
887 var name := t[1].t.identifier;
889 if len_at_least(t2, 2), t2[0].t is left_bracket then
890 t2 := t2[1 .. len(t2) - 1];
891 else if len_at_least(t2, 1), t2[len(t2) - 1].t is semicolon then
892 t2 := t2[ .. len(t2) - 1];
894 abort compiler_error("Invalid define statement", t);
895 dict.macros[name] := t2;
899 fn expand_macro(t : tokens, m : tokens) : tokens
901 if not t[len(t) - 1].t is semicolon then
902 abort compiler_error("Invalid macro expansion", t);
903 var args := empty(tokens);
904 if len_greater_than(t, 1) then [
905 xeval token_assert(t[1 .. ], token_opt.left_paren);
906 var t1 := t[2 .. len(t) - 2];
908 var comma := token_find(t1, token_opt.comma, false);
911 arg := t1[ .. comma];
916 t1 := t1[comma + 1 .. ];
920 if len_greater_than(args, 9) then
921 abort compiler_error("Too many macro arguments", t);
922 var result := empty(token);
923 for i := 0 to len(m) do [
925 if n.t is macro_expansion then [
927 var str := i_decode(n.t.macro_expansion);
928 if len(str) = 2, str[0] = '@', str[1] >= '1', str[1] <= '9' then [
929 var n_arg := str[1] - '1';
930 if n_arg >= len(args) then
931 abort compiler_error("Argument " + ntos(n_arg) + " not provided", t);
935 var result_str := empty(byte);
936 for j := 0 to len(str) do [
938 if c = '@', j < len(str) - 1, str[j + 1] >= '1', str[j + 1] <= '9' then [
939 var n_arg := str[j + 1] - '1';
940 if n_arg >= len(args) then
941 abort compiler_error("Argument " + ntos(n_arg) + " not provided", t);
942 var expanded : bytes;
943 if len(args[n_arg]) = 0 then [
945 ] else if len(args[n_arg]) > 1 then [
946 abort compiler_error("Argument " + ntos(n_arg) + " must have a single token", t);
948 expanded := token_opt_to_string(args[n_arg][0].t, true);
950 result_str += expanded;
956 toks := tokenize_string(result_str, t);
958 if len_greater_than(toks, 0) then [
959 toks[0].prev_hints += n.prev_hints;
960 toks[len(toks) - 1].post_hints += n.post_hints;
967 for i := 0 to len(result) do [
968 result[i].bracket_skip := 0;
970 var bracket_stack_pos := empty(int);
971 var bracket_stack_type := empty(token_opt);
972 for i := 0 to len(result) do [
973 if result[i].t is left_paren then [
974 bracket_stack_pos +<= i;
975 bracket_stack_type +<= token_opt.right_paren;
976 ] else if result[i].t is left_bracket then [
977 bracket_stack_pos +<= i;
978 bracket_stack_type +<= token_opt.right_bracket;
979 ] else if result[i].t is right_paren or result[i].t is right_bracket then [
980 var l := len(bracket_stack_type);
981 if l = 0 or ord bracket_stack_type[l - 1] <> ord result[i].t then
982 abort compiler_error("Imbalanced bracket in macro expansion", t);
983 var bracket_skip := i - bracket_stack_pos[l - 1];
984 result[bracket_stack_pos[l - 1]].bracket_skip := bracket_skip;
985 result[i].bracket_skip := -bracket_skip;
986 bracket_stack_type := bracket_stack_type[ .. l - 1];
987 bracket_stack_pos := bracket_stack_pos[ .. l - 1];
990 if len(bracket_stack_type) <> 0 then
991 abort compiler_error("Imbalanced bracket in macro expansion", t);
995 fn parse_clause(w : world, d : list(bytes), dict : function_dictionary, t1 : tokens) : (function_dictionary, tokens)
997 var f := token_find_3(t1, token_opt.assign, token_opt.semicolon, token_opt.right_bracket, true);
998 if t1[f].t is assign then [
999 f := token_find(t1, token_opt.semicolon, true);
1001 var t := t1[ .. f + 1];
1003 var private_flag := false;
1004 var implicit_flag := false;
1005 var conversion_flag := false;
1007 if len(t) = 0 then [
1008 abort compiler_error("Empty clause", empty(token));
1010 if t[0].t is k_private then [
1011 private_flag := true;
1015 if t[0].t is k_implicit then [
1016 implicit_flag := true;
1020 if t[0].t is k_conversion then [
1021 conversion_flag := true;
1025 if t[0].t is k_uses then [
1026 if private_flag or implicit_flag or conversion_flag or not t[len(t) - 1].t is semicolon then
1027 abort compiler_error("Invalid uses clause", t);
1028 t := t[1 .. len(t) - 1];
1029 while len(t) > 0 do [
1031 decl, t := split_tokens(t, token_opt.comma);
1032 dict := parse_uses(w, d, dict, decl);
1034 ] else if t[0].t is k_define then [
1035 dict := parse_define(dict, t);
1036 ] else if t[0].t is k_fn or
1037 t[0].t is k_record or
1038 t[0].t is k_option or
1040 t[0].t is k_const or
1041 t[0].t is k_operator then [
1042 dict := parse_function(dict, t, private_flag, implicit_flag, conversion_flag);
1043 ] else if t[0].t is identifier, not is_uninitialized(dict.macros[t[0].t.identifier]) then [
1044 var m := dict.macros[t[0].t.identifier];
1045 m := expand_macro(t, m);
1046 while len_greater_than(m, 0) do [
1047 dict, m := parse_clause(w, d, dict, m);
1050 abort compiler_error("Expected 'fn' or 'record' or 'option' or 'type' or 'const' or 'operator' or 'private' or 'uses' or 'define'", t);
1052 return dict, t1[f + 1 .. ];
1055 fn parse_tokens(w : world, d : list(bytes), t : tokens, name : bytes, program : bool, parse_interface : bool) : function_dictionary
1057 var path_index := len(d) - 1;
1058 var dict := new_function_dictionary(path_index, i_encode(name), program);
1061 if len_greater_than(t, 0), t[0].t is k_private then [
1064 goto next_unit_flag;
1066 var a := token_assert(t, token_opt.k_unit);
1067 if is_exception a then
1068 return exception_make(function_dictionary, ec_syscall, error_system, system_error_enoent, true);
1070 var sc := token_find(t, token_opt.semicolon, true);
1071 var unit_tokens := t[1 .. sc];
1073 var file_name := parse_unit_name(unit_tokens);
1076 if parse_interface then
1077 eval debug("interface: " + file_name);
1079 eval debug("file name: " + file_name);
1082 var name_pos := len(name) - len(file_name);
1083 if name_pos < 0 then [
1084 abort compiler_error("Unit name doesn't match file name", unit_tokens);
1086 if name_pos > 0, not path_is_separator(name[name_pos - 1]) then [
1087 abort compiler_error("Unit name doesn't match file name", unit_tokens);
1089 if name[name_pos .. ] <> file_name then [
1090 abort compiler_error("Unit name doesn't match file name", unit_tokens);
1092 dict.name_prefix := name[ .. name_pos];
1095 if path_index <> 0 or name <> "system" then [
1096 dict := parse_system_unit(w, d, dict);
1099 var was_implementation := false;
1101 while len_greater_than(t, 0) do [
1102 if t[0].t is k_implementation and not was_implementation then [
1103 if parse_interface then [
1106 was_implementation := true;
1112 dict, t := parse_clause(w, d, dict, t);
1118 fn unit_encode(un_name : bytes) : bytes
1121 for i := 0 to len(un_name) do [
1122 if un_name[i] = '"' then
1124 else if un_name[i] < ' ' then
1125 abort compiler_error("invalid program file name", empty(token));
1127 result +<= un_name[i];
1133 fn parse_file~cache(w : world, d : list(bytes), name : bytes, program : bool, parse_interface : bool) : function_dictionary
1135 var idx := len(d) - 1;
1136 var dir := dopen_lazy(dnone(w), d[idx], 0);
1139 xeval register_dependence(w, dir, name + ".ajla");
1141 var f := ropen_lazy(dir, name + ".ajla", 0);
1143 if path_is_separator('\') then [
1144 for i := 0 to len(name) do [
1145 if name[i] = '\' then
1154 var un_dir, un_name := path_to_dir_file(name);
1155 h := "unit " + unit_encode(un_name) + "; uses io, treemap; fn main(implicit w : world, d : dhandle, h : list(handle), args : list(bytes), env : treemap(bytes, bytes)) : world; implementation ";
1158 var t := tokenize(h, name);
1159 var dict := parse_tokens(w, d, t, name, program, parse_interface);
1160 if not parse_interface then [
1161 for i := 0 to len(dict.defs) do [
1162 if dict.defs[i].body is n then
1163 abort compiler_error("function '" + i_decode(dict.defs[i].signature.name) + "' was not defined", empty(token));
1164 dict.defs[i].pcode := dump_function(dict.defs[i]);