os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

commit 3cdca44786443b4142a7a98be8476b890a29a03c
parent 26ac1fd10134d21b5b6d8dffccbd77b85535d71a
Author: erai <erai@omiltem.net>
Date:   Sat,  8 Feb 2025 02:46:51 +0000

merge peg into the omiltem language

Diffstat:
Mbootstrap.sh | 10++++++----
Mcc0.c | 313++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mcc1.om | 34+++++++++++++---------------------
Acc3.om | 152+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dcc3.peg | 148-------------------------------------------------------------------------------
Mir.om | 2++
Mparse2.om | 12+++++++++++-
Mpeg.om | 23+++++------------------
8 files changed, 356 insertions(+), 338 deletions(-)

diff --git a/bootstrap.sh b/bootstrap.sh @@ -1,15 +1,17 @@ #!/bin/sh +set -x + BOOTSTRAP="cc0.c" LIBS="bufio.om lib.om alloc.om syscall.om" -SOURCES="cc1.om type.om parse2.om parse3.om peglib.om as.om decl.om node.om peg.om ir.om ircout.om rb.om" +SOURCES="cc1.om type.om parse2.om peglib.om as.om decl.om node.om peg.om ir.om ircout.om rb.om" # Build the bootstrap compiler from c [ cc0 -nt cc0.c ] || gcc -O1 -g -std=c99 ${BOOTSTRAP} -o cc0 -./cc0 -P cc3.peg -o parse3.om -./cc0 ${LIBS} ${SOURCES} -o cc1 -n cc1.lines -G cc1.call +./cc0 cc3.om -P parse3.om +./cc0 ${LIBS} ${SOURCES} parse3.om -o cc1 -n cc1.lines -G cc1.call # Double check the bootstrap and self hosting compiler have the same output -./cc1 ${LIBS} ${SOURCES} -C cc2.c -o cc2 -n cc2.lines -G cc2.call +./cc1 ${LIBS} ${SOURCES} cc3.om -C cc2.c -o cc2 -n cc2.lines -G cc2.call cmp cc1 cc2 || echo cc mismatch cmp cc0.c cc2.c || echo bootstrap mismatch diff --git a/cc0.c b/cc0.c @@ -28603,6 +28603,13 @@ u my_peg_P_grammar(u v_c) { u v65 = 0; u v66 = 0; u v67 = 0; + u v68 = 0; + u v69 = 0; + u v70 = 0; + u v71 = 0; + u v72 = 0; + u v73 = 0; + u v74 = 0; b0: v2 = (u)my_enter; v3 = v_c; v4 = 0UL; @@ -28658,55 +28665,69 @@ b33: v36 = (u)my_peg_P_func_decl; v38 = ((u (*)())(v36))(v37); b34: v_ok = v38; goto b27; -b27: if (!(v_ok)) { goto b37; } -b36: v39 = (u)my_commit; - v40 = v_c; - v41 = ((u (*)())(v39))(v40); -b35: if (!(v_ok)) { goto b44; } -b43: v45 = 0UL; - goto b45; -b45: if (!(v45)) { goto b40; } -b41: v_ok = 1UL; +b27: if (!(v_ok)) { goto b39; } +b38: v39 = 0UL; + goto b40; +b40: if (!(v39)) { goto b35; } +b36: v40 = (u)my_choice; + v41 = v_c; + v42 = ((u (*)())(v40))(v41); +b41: v43 = (u)my_peg_P_peg_grammar; + v44 = v_c; + v45 = ((u (*)())(v43))(v44); +b42: v_ok = v45; + goto b35; +b35: if (!(v_ok)) { goto b45; } +b44: v46 = (u)my_commit; + v47 = v_c; + v48 = ((u (*)())(v46))(v47); +b43: if (!(v_ok)) { goto b52; } +b51: v52 = 0UL; + goto b53; +b53: if (!(v52)) { goto b48; } +b49: v_ok = 1UL; goto b3; -b3: if (!(v_ok)) { goto b47; } -b48: v49 = (u)my_choice; - v50 = v_c; - v51 = ((u (*)())(v49))(v50); -b50: v52 = (u)my_any; - v53 = v_c; - v54 = ((u (*)())(v52))(v53); -b51: v_ok = v54; - if (!(v_ok)) { goto b54; } -b53: v55 = (u)my_fail; - v56 = v_c; - v57 = ((u (*)())(v55))(v56); -b55: v58 = (u)my_fail; - v59 = v_c; - v60 = ((u (*)())(v58))(v59); -b56: v_ok = 0UL; - goto b47; -b47: if (!(v_ok)) { goto b59; } -b58: v61 = (u)my_leave; - v62 = v_c; - v63 = 0UL; - v64 = ((u (*)())(v61))(v62, v63); -b57: return v_ok; -b59: v65 = (u)my_fail; +b3: if (!(v_ok)) { goto b55; } +b56: v56 = (u)my_choice; + v57 = v_c; + v58 = ((u (*)())(v56))(v57); +b58: v59 = (u)my_any; + v60 = v_c; + v61 = ((u (*)())(v59))(v60); +b59: v_ok = v61; + if (!(v_ok)) { goto b62; } +b61: v62 = (u)my_fail; + v63 = v_c; + v64 = ((u (*)())(v62))(v63); +b63: v65 = (u)my_fail; v66 = v_c; v67 = ((u (*)())(v65))(v66); - goto b57; -b54: v_ok = 1UL; - goto b47; -b40: v46 = (u)my_commit; - v47 = v_c; - v48 = ((u (*)())(v46))(v47); +b64: v_ok = 0UL; + goto b55; +b55: if (!(v_ok)) { goto b67; } +b66: v68 = (u)my_leave; + v69 = v_c; + v70 = 0UL; + v71 = ((u (*)())(v68))(v69, v70); +b65: return v_ok; +b67: v72 = (u)my_fail; + v73 = v_c; + v74 = ((u (*)())(v72))(v73); + goto b65; +b62: v_ok = 1UL; + goto b55; +b48: v53 = (u)my_commit; + v54 = v_c; + v55 = ((u (*)())(v53))(v54); goto b6; -b44: v45 = 1UL; - goto b45; -b37: v42 = (u)my_fail; - v43 = v_c; - v44 = ((u (*)())(v42))(v43); - goto b35; +b52: v52 = 1UL; + goto b53; +b45: v49 = (u)my_fail; + v50 = v_c; + v51 = ((u (*)())(v49))(v50); + goto b43; +b39: v39 = 1UL; + goto b40; b31: v32 = 1UL; goto b32; b23: v25 = 1UL; @@ -30808,119 +30829,119 @@ u my_peg_P_peg_grammar(u v_c) { u v69 = 0; u v70 = 0; u v71 = 0; - u v72 = 0; b0: v2 = (u)my_enter; v3 = v_c; v4 = 90UL; v5 = ((u (*)())(v2))(v3, v4); -b1: v6 = (u)my_peg_P_sp; +b1: v6 = (u)my_literal; v7 = v_c; - v8 = ((u (*)())(v6))(v7); -b2: v_ok = v8; + v8 = (u)"%{"; + v9 = ((u (*)())(v6))(v7, v8); +b2: v_ok = v9; if (!(v_ok)) { goto b3; } -b4: v9 = (u)my_choice; - v10 = v_c; - v11 = ((u (*)())(v9))(v10); -b6: v12 = (u)my_peg_P_peg_rule; - v13 = v_c; - v14 = ((u (*)())(v12))(v13); -b7: v_ok = v14; - if (!(v_ok)) { goto b12; } -b11: v15 = 0UL; - goto b13; -b13: if (!(v15)) { goto b8; } -b9: v16 = (u)my_choice; +b4: v10 = (u)my_peg_P_sp; + v11 = v_c; + v12 = ((u (*)())(v10))(v11); +b6: v_ok = v12; + goto b3; +b3: if (!(v_ok)) { goto b7; } +b8: v13 = (u)my_choice; + v14 = v_c; + v15 = ((u (*)())(v13))(v14); +b10: v16 = (u)my_peg_P_peg_rule; v17 = v_c; v18 = ((u (*)())(v16))(v17); -b14: v19 = (u)my_peg_P_peg_prefix; - v20 = v_c; - v21 = ((u (*)())(v19))(v20); -b15: v_ok = v21; - goto b8; -b8: if (!(v_ok)) { goto b18; } -b17: v22 = (u)my_commit; - v23 = v_c; - v24 = ((u (*)())(v22))(v23); -b16: if (!(v_ok)) { goto b3; } -b24: v28 = (u)my_choice; - v29 = v_c; - v30 = ((u (*)())(v28))(v29); -b26: v31 = (u)my_choice; - v32 = v_c; - v33 = ((u (*)())(v31))(v32); -b27: v34 = (u)my_peg_P_peg_rule; - v35 = v_c; - v36 = ((u (*)())(v34))(v35); -b28: v_ok = v36; - if (!(v_ok)) { goto b33; } -b32: v37 = 0UL; - goto b34; -b34: if (!(v37)) { goto b29; } -b30: v38 = (u)my_choice; +b11: v_ok = v18; + if (!(v_ok)) { goto b16; } +b15: v19 = 0UL; + goto b17; +b17: if (!(v19)) { goto b12; } +b13: v20 = (u)my_choice; + v21 = v_c; + v22 = ((u (*)())(v20))(v21); +b18: v23 = (u)my_peg_P_peg_prefix; + v24 = v_c; + v25 = ((u (*)())(v23))(v24); +b19: v_ok = v25; + goto b12; +b12: if (!(v_ok)) { goto b22; } +b21: v26 = (u)my_commit; + v27 = v_c; + v28 = ((u (*)())(v26))(v27); +b20: if (!(v_ok)) { goto b7; } +b28: v32 = (u)my_choice; + v33 = v_c; + v34 = ((u (*)())(v32))(v33); +b30: v35 = (u)my_choice; + v36 = v_c; + v37 = ((u (*)())(v35))(v36); +b31: v38 = (u)my_peg_P_peg_rule; v39 = v_c; v40 = ((u (*)())(v38))(v39); -b35: v41 = (u)my_peg_P_peg_prefix; - v42 = v_c; - v43 = ((u (*)())(v41))(v42); -b36: v_ok = v43; - goto b29; -b29: if (!(v_ok)) { goto b39; } -b38: v44 = (u)my_commit; - v45 = v_c; - v46 = ((u (*)())(v44))(v45); -b37: if (!(v_ok)) { goto b46; } -b45: v50 = 0UL; - goto b47; -b47: if (!(v50)) { goto b42; } -b43: v_ok = 1UL; - goto b3; -b3: if (!(v_ok)) { goto b49; } -b50: v54 = (u)my_choice; - v55 = v_c; - v56 = ((u (*)())(v54))(v55); -b52: v57 = (u)my_any; - v58 = v_c; - v59 = ((u (*)())(v57))(v58); -b53: v_ok = v59; - if (!(v_ok)) { goto b56; } -b55: v60 = (u)my_fail; - v61 = v_c; - v62 = ((u (*)())(v60))(v61); -b57: v63 = (u)my_fail; - v64 = v_c; - v65 = ((u (*)())(v63))(v64); -b58: v_ok = 0UL; - goto b49; -b49: if (!(v_ok)) { goto b61; } -b60: v66 = (u)my_leave; - v67 = v_c; - v68 = 90UL; - v69 = ((u (*)())(v66))(v67, v68); -b59: return v_ok; -b61: v70 = (u)my_fail; - v71 = v_c; - v72 = ((u (*)())(v70))(v71); - goto b59; -b56: v_ok = 1UL; - goto b49; -b42: v51 = (u)my_commit; +b32: v_ok = v40; + if (!(v_ok)) { goto b37; } +b36: v41 = 0UL; + goto b38; +b38: if (!(v41)) { goto b33; } +b34: v42 = (u)my_choice; + v43 = v_c; + v44 = ((u (*)())(v42))(v43); +b39: v45 = (u)my_peg_P_peg_prefix; + v46 = v_c; + v47 = ((u (*)())(v45))(v46); +b40: v_ok = v47; + goto b33; +b33: if (!(v_ok)) { goto b43; } +b42: v48 = (u)my_commit; + v49 = v_c; + v50 = ((u (*)())(v48))(v49); +b41: if (!(v_ok)) { goto b50; } +b49: v54 = 0UL; + goto b51; +b51: if (!(v54)) { goto b46; } +b47: v_ok = 1UL; + goto b7; +b7: if (!(v_ok)) { goto b53; } +b54: v58 = (u)my_literal; + v59 = v_c; + v60 = (u)"%}"; + v61 = ((u (*)())(v58))(v59, v60); +b56: v_ok = v61; + goto b53; +b53: if (!(v_ok)) { goto b57; } +b58: v62 = (u)my_peg_P_sp; + v63 = v_c; + v64 = ((u (*)())(v62))(v63); +b60: v_ok = v64; + goto b57; +b57: if (!(v_ok)) { goto b63; } +b62: v65 = (u)my_leave; + v66 = v_c; + v67 = 90UL; + v68 = ((u (*)())(v65))(v66, v67); +b61: return v_ok; +b63: v69 = (u)my_fail; + v70 = v_c; + v71 = ((u (*)())(v69))(v70); + goto b61; +b46: v55 = (u)my_commit; + v56 = v_c; + v57 = ((u (*)())(v55))(v56); + goto b28; +b50: v54 = 1UL; + goto b51; +b43: v51 = (u)my_fail; v52 = v_c; v53 = ((u (*)())(v51))(v52); - goto b24; -b46: v50 = 1UL; - goto b47; -b39: v47 = (u)my_fail; - v48 = v_c; - v49 = ((u (*)())(v47))(v48); - goto b37; -b33: v37 = 1UL; - goto b34; -b18: v25 = (u)my_fail; - v26 = v_c; - v27 = ((u (*)())(v25))(v26); - goto b16; -b12: v15 = 1UL; - goto b13; + goto b41; +b37: v41 = 1UL; + goto b38; +b22: v29 = (u)my_fail; + v30 = v_c; + v31 = ((u (*)())(v29))(v30); + goto b20; +b16: v19 = 1UL; + goto b17; } u my_peg_P_peg_identifier(u v_c) { u v_ok = 0; diff --git a/cc1.om b/cc1.om @@ -62,7 +62,7 @@ func comp_setup(a: *alloc, err: *file): *compiler { c.err = err; - c.p = setup_parser(a); + c.p = setup_parser(a, err); c.filename = nil; c.lineno = 0; @@ -92,7 +92,7 @@ func open_coutput(c: *compiler, filename: *byte) { fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, (6 << 6) + (6 << 3) + 6); if (fd < 0) { - die("failed to open output"); + die("open_coutput: failed to open output"); } c.cout = fopen(fd, c.a); @@ -1342,7 +1342,7 @@ func gather_include(c: *compiler, filename: *byte, slen: *int): *byte { fd = open(filename, O_RDONLY, 0); if fd < 0 { - cdie(c, "failed to open include"); + cdie(c, "gather_include: failed to open include"); } blob = readall(fd, slen, c.a); @@ -2176,7 +2176,7 @@ func open_call_out(c: *compiler, filename: *byte) { fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, (6 << 6) + (6 << 3) + 6); if (fd < 0) { - die("failed to open output"); + die("open_call_out: failed to open output"); } c.call_out = fopen(fd, c.a); @@ -2187,7 +2187,7 @@ func open_lines_out(c: *compiler, filename: *byte) { fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, (6 << 6) + (6 << 3) + 6); if (fd < 0) { - die("failed to open output"); + die("open_lines_out: failed to open output"); } c.s.lines_out = fopen(fd, c.a); @@ -2210,7 +2210,7 @@ func main(argc: int, argv: **byte, envp: **byte) { var input: *name_node; var tmp: *name_node; var link: **name_node; - var peg: *peg_compiler; + var pout_filename: *byte; link = &input; @@ -2273,7 +2273,11 @@ func main(argc: int, argv: **byte, envp: **byte) { } if (!strcmp(argv[i], "-P")) { - peg = setup_peg(&a); + i = i + 1; + if (i >= argc) { + die("invalid -P at end of argument list"); + } + pout_filename = argv[i]; i = i + 1; continue; } @@ -2291,20 +2295,8 @@ func main(argc: int, argv: **byte, envp: **byte) { i = i + 1; } - if peg { - if !input { - die("expected input"); - } - peg_open_output(peg, out_filename); - tmp = input; - loop { - if !tmp { - break; - } - peg_compile(peg, tmp.name, err); - tmp = tmp.next; - } - return; + if pout_filename { + peg_open_output(c.p.pc, pout_filename); } tmp = input; diff --git a/cc3.om b/cc3.om @@ -0,0 +1,152 @@ +%{ + +%prefix P_ + +grammar <- sp (enum_decl / struct_decl / union_decl / func_decl / peg_grammar)* !. + +enum_item <- ident sp ('=' sp expr)? +enum_decl <- enum sp '{' sp (enum_item (',' sp enum_item)*)? (',' sp)? '}' sp + +member_decl <- ident sp ':' sp type ';' sp +struct_decl <- struct sp ident sp '{' sp member_decl* '}' sp +union_decl <- union sp ident sp '{' sp member_decl* '}' sp + +func_decl <- 'func' sp ident sp func_type (';' sp / compound_stmt) + +type <- ident sp / byte sp / int sp / void sp + / func sp func_type / ptr_type / '(' sp type ')' sp + +ptr_type <- '*' sp type + +gen_decl <- ident sp ':' sp 'type' sp +arg_decl <- ident sp ':' sp type +func_type <- '(' sp ( arg_decl (',' sp arg_decl)* )? ( ',' sp )? ')' sp + (':' sp type)? + +stmt <- if_stmt / loop_stmt / break_stmt / continue_stmt + / return_stmt / var_stmt / label_stmt / goto_stmt + / assign_stmt / expr_stmt / empty_stmt / compound_stmt + +elif_stmt <- else sp if sp expr compound_stmt +else_stmt <- else sp compound_stmt +if_stmt <- if sp expr compound_stmt elif_stmt* else_stmt? + +loop_stmt <- loop sp compound_stmt sp + +break_stmt <- break sp ';' sp + +continue_stmt <- continue sp ';' sp + +return_stmt <- return sp expr? sp ';' sp + +var_stmt <- var sp ident sp ':' sp type ';' sp + +label_stmt <- ident sp ':' sp + +goto_stmt <- goto sp ident sp ';' sp + +assign_stmt <- unary_expr '=' sp expr ';' sp + +expr_stmt <- expr ';' sp + +empty_stmt <- ';' sp + +compound_stmt <- '{' sp stmt* '}' sp + +expr <- bool_expr + +band_op <- '&&' +bor_op <- '||' +bool_expr <- comp_expr ((band_op / bor_op) sp comp_expr)* + +le_op <- '<=' +ge_op <- '>=' +lt_op <- '<' !'=' !'<' +gt_op <- '>' !'=' !'>' +eq_op <- '==' +ne_op <- '!=' +comp_expr <- add_expr ((le_op / ge_op / lt_op / gt_op / eq_op / ne_op) sp add_expr)? + +add_op <- '+' +sub_op <- '-' +or_op <- '|' !'|' +xor_op <- '^' +add_expr <- mul_expr ((add_op / sub_op / or_op / xor_op) sp mul_expr)* + +mul_op <- '*' +div_op <- '/' !'/' +mod_op <- '%' +and_op <- '&' !'&' +mul_expr <- shift_expr ((mul_op / div_op / mod_op / and_op) sp shift_expr)* + +lsh_op <- '<<' +rsh_op <- '>>' +shift_expr <- unary_expr ((lsh_op / rsh_op) sp unary_expr)* + +ref_op <- '&' !'&' +deref_op <- '*' +pos_op <- '+' +neg_op <- '-' +not_op <- '~' +bnot_op <- '!' !'=' +unary_expr <- ((ref_op / deref_op / pos_op / neg_op / not_op / bnot_op) sp)* post_expr + +index_expr <- '[' sp expr ']' sp +call_expr <- '(' sp ( expr (',' sp expr)* )? (',' sp)? ')' sp +member_expr <- '.' sp ident sp +cast_expr <- 'as' sp type +post_expr <- primary (index_expr / call_expr / member_expr / cast_expr)* + +primary <- ident sp / hex sp / dec sp / str sp / char sp + / sizeof_expr / nil sp / '(' sp expr ')' sp + +sizeof_expr <- sizeof sp '(' sp expr ')' sp + +hex <- '0x'[0-9a-fA-F_]+ +dec <- !'_' [0-9_]+ +str <- ["] ([\\] . / !["] .)* ["] +char <- ['] ([\\] . / !['] .)+ ['] + +reserved <- return / break / sizeof / if / else / loop / continue / goto + / var / enum / struct / union / byte / int / void / func / as / nil + +return <- 'return' ![a-zA-Z0-9_] +break <- 'break' ![a-zA-Z0-9_] +sizeof <- 'sizeof' ![a-zA-Z0-9_] +if <- 'if' ![a-zA-Z0-9_] +else <- 'else' ![a-zA-Z0-9_] +loop <- 'loop' ![a-zA-Z0-9_] +continue <- 'continue' ![a-zA-Z0-9_] +goto <- 'goto' ![a-zA-Z0-9_] +var <- 'var' ![a-zA-Z0-9_] +enum <- 'enum' ![a-zA-Z0-9_] +struct <- 'struct' ![a-zA-Z0-9_] +union <- 'union' ![a-zA-Z0-9_] +byte <- 'byte' ![a-zA-Z0-9_] +int <- 'int' ![a-zA-Z0-9_] +void <- 'void' ![a-zA-Z0-9_] +func <- 'func' ![a-zA-Z0-9_] +as <- 'as' ![a-zA-Z0-9_] +nil <- 'nil' ![a-zA-Z0-9_] + +ident <- !reserved [a-zA-Z_][a-zA-Z0-9_]* + +sp <- ( [ \r\n\t] / '//' (![\r\n] .)* )* + +peg_grammar <- '%{' sp (peg_rule / peg_prefix)+ '%}' sp +peg_rule <- peg_identifier sp '<-' sp peg_pattern +peg_prefix <- '%prefix' sp peg_identifier sp +peg_pattern <- peg_alternative ( '/' !'/' sp peg_alternative )* +peg_alternative <- peg_lookahead+ +peg_lookop <- [!&] +peg_lookahead <- (peg_lookop sp)? peg_suffix +peg_countop <- [*+?] +peg_suffix <- peg_primary (peg_countop sp)* +peg_primary <- ( '(' sp peg_pattern ')' / peg_any / peg_literal / peg_class / peg_call ) sp +peg_any <- '.' +peg_literal <- ['] ( !['] . )* ['] +peg_class <- '[' ( !']' ( . '-' . / . ) )* ']' +peg_call <- peg_identifier !(sp '<-') +peg_identifier <- [a-zA-Z0-9_]+ + +%} diff --git a/cc3.peg b/cc3.peg @@ -1,148 +0,0 @@ -%prefix P_ - -grammar <- sp (enum_decl / struct_decl / union_decl / func_decl)* !. - -enum_item <- ident sp ('=' sp expr)? -enum_decl <- enum sp '{' sp (enum_item (',' sp enum_item)*)? (',' sp)? '}' sp - -member_decl <- ident sp ':' sp type ';' sp -struct_decl <- struct sp ident sp '{' sp member_decl* '}' sp -union_decl <- union sp ident sp '{' sp member_decl* '}' sp - -func_decl <- 'func' sp ident sp func_type (';' sp / compound_stmt) - -type <- ident sp / byte sp / int sp / void sp - / func sp func_type / ptr_type / '(' sp type ')' sp - -ptr_type <- '*' sp type - -gen_decl <- ident sp ':' sp 'type' sp -arg_decl <- ident sp ':' sp type -func_type <- '(' sp ( arg_decl (',' sp arg_decl)* )? ( ',' sp )? ')' sp - (':' sp type)? - -stmt <- if_stmt / loop_stmt / break_stmt / continue_stmt - / return_stmt / var_stmt / label_stmt / goto_stmt - / assign_stmt / expr_stmt / empty_stmt / compound_stmt - -elif_stmt <- else sp if sp expr compound_stmt -else_stmt <- else sp compound_stmt -if_stmt <- if sp expr compound_stmt elif_stmt* else_stmt? - -loop_stmt <- loop sp compound_stmt sp - -break_stmt <- break sp ';' sp - -continue_stmt <- continue sp ';' sp - -return_stmt <- return sp expr? sp ';' sp - -var_stmt <- var sp ident sp ':' sp type ';' sp - -label_stmt <- ident sp ':' sp - -goto_stmt <- goto sp ident sp ';' sp - -assign_stmt <- unary_expr '=' sp expr ';' sp - -expr_stmt <- expr ';' sp - -empty_stmt <- ';' sp - -compound_stmt <- '{' sp stmt* '}' sp - -expr <- bool_expr - -band_op <- '&&' -bor_op <- '||' -bool_expr <- comp_expr ((band_op / bor_op) sp comp_expr)* - -le_op <- '<=' -ge_op <- '>=' -lt_op <- '<' !'=' !'<' -gt_op <- '>' !'=' !'>' -eq_op <- '==' -ne_op <- '!=' -comp_expr <- add_expr ((le_op / ge_op / lt_op / gt_op / eq_op / ne_op) sp add_expr)? - -add_op <- '+' -sub_op <- '-' -or_op <- '|' !'|' -xor_op <- '^' -add_expr <- mul_expr ((add_op / sub_op / or_op / xor_op) sp mul_expr)* - -mul_op <- '*' -div_op <- '/' !'/' -mod_op <- '%' -and_op <- '&' !'&' -mul_expr <- shift_expr ((mul_op / div_op / mod_op / and_op) sp shift_expr)* - -lsh_op <- '<<' -rsh_op <- '>>' -shift_expr <- unary_expr ((lsh_op / rsh_op) sp unary_expr)* - -ref_op <- '&' !'&' -deref_op <- '*' -pos_op <- '+' -neg_op <- '-' -not_op <- '~' -bnot_op <- '!' !'=' -unary_expr <- ((ref_op / deref_op / pos_op / neg_op / not_op / bnot_op) sp)* post_expr - -index_expr <- '[' sp expr ']' sp -call_expr <- '(' sp ( expr (',' sp expr)* )? (',' sp)? ')' sp -member_expr <- '.' sp ident sp -cast_expr <- 'as' sp type -post_expr <- primary (index_expr / call_expr / member_expr / cast_expr)* - -primary <- ident sp / hex sp / dec sp / str sp / char sp - / sizeof_expr / nil sp / '(' sp expr ')' sp - -sizeof_expr <- sizeof sp '(' sp expr ')' sp - -hex <- '0x'[0-9a-fA-F_]+ -dec <- !'_' [0-9_]+ -str <- ["] ([\\] . / !["] .)* ["] -char <- ['] ([\\] . / !['] .)+ ['] - -reserved <- return / break / sizeof / if / else / loop / continue / goto - / var / enum / struct / union / byte / int / void / func / as / nil - -return <- 'return' ![a-zA-Z0-9_] -break <- 'break' ![a-zA-Z0-9_] -sizeof <- 'sizeof' ![a-zA-Z0-9_] -if <- 'if' ![a-zA-Z0-9_] -else <- 'else' ![a-zA-Z0-9_] -loop <- 'loop' ![a-zA-Z0-9_] -continue <- 'continue' ![a-zA-Z0-9_] -goto <- 'goto' ![a-zA-Z0-9_] -var <- 'var' ![a-zA-Z0-9_] -enum <- 'enum' ![a-zA-Z0-9_] -struct <- 'struct' ![a-zA-Z0-9_] -union <- 'union' ![a-zA-Z0-9_] -byte <- 'byte' ![a-zA-Z0-9_] -int <- 'int' ![a-zA-Z0-9_] -void <- 'void' ![a-zA-Z0-9_] -func <- 'func' ![a-zA-Z0-9_] -as <- 'as' ![a-zA-Z0-9_] -nil <- 'nil' ![a-zA-Z0-9_] - -ident <- !reserved [a-zA-Z_][a-zA-Z0-9_]* - -sp <- ( [ \r\n\t] / '//' (![\r\n] .)* )* - -peg_grammar <- sp (peg_rule / peg_prefix)+ !. -peg_rule <- peg_identifier sp '<-' sp peg_pattern -peg_prefix <- '%prefix' sp peg_identifier sp -peg_pattern <- peg_alternative ( '/' !'/' sp peg_alternative )* -peg_alternative <- peg_lookahead+ -peg_lookop <- [!&] -peg_lookahead <- (peg_lookop sp)? peg_suffix -peg_countop <- [*+?] -peg_suffix <- peg_primary (peg_countop sp)* -peg_primary <- ( '(' sp peg_pattern ')' / peg_any / peg_literal / peg_class / peg_call ) sp -peg_any <- '.' -peg_literal <- ['] ( !['] . )* ['] -peg_class <- '[' ( !']' ( . '-' . / . ) )* ']' -peg_call <- peg_identifier !(sp '<-') -peg_identifier <- [a-zA-Z0-9_]+ diff --git a/ir.om b/ir.om @@ -2518,6 +2518,8 @@ func irblock_value(ic: *irfunc, ib: *irblock) { break; } + // TODO: value forwarding + i = i + 1; } } diff --git a/parse2.om b/parse2.om @@ -1,9 +1,11 @@ struct parser { a: *alloc; p: *peg; + pc: *peg_compiler; + err: *file; } -func setup_parser(a: *alloc): *parser { +func setup_parser(a: *alloc, err: *file): *parser { var c: *parser; c = alloc(a, sizeof(*c)) as *parser; @@ -12,6 +14,10 @@ func setup_parser(a: *alloc): *parser { c.p = peg_new("", "", 0, a, peg_P_grammar, P_tag_to_str); + c.pc = setup_peg(a); + + c.err = err; + return c; } @@ -73,6 +79,10 @@ func reconstruct(c: *parser, pn: *peg_node): *node { n = reconstruct_union(c, pn); } else if pn.tag == P_func_decl { n = reconstruct_func(c, pn); + } else if pn.tag == P_peg_grammar { + peg_compile(c.pc, pn, c.err); + pn = pn.next; + continue; } else { die("invalid decl"); } diff --git a/peg.om b/peg.om @@ -488,34 +488,21 @@ func peg_open_output(c: *peg_compiler, filename: *byte) { fd = open(filename, O_CREAT | O_WRONLY, (6 << 6) + (6 << 3) + 6); if fd < 0 { - die("failed to open output"); + die("peg_open_output: failed to open output"); } f = fopen(fd, c.a); c.out = f; } -func peg_compile(c: *peg_compiler, filename: *byte, err: *file) { - var fd: int; - var f: *file; - var src: *byte; - var len: int; +func peg_compile(c: *peg_compiler, pn: *peg_node, err: *file) { var node: *peg_node; - if strcmp(filename, "-") == 0 { - fd = 0; - } else { - fd = open(filename, O_RDONLY, 0); - if fd < 0 { - die("failed to open output"); - } + if !c.out { + return; } - f = fopen(fd, c.a); - src = freadall(f, &len); - fclose(f); - - c.p = peg_new(filename, src, len, c.a, peg_P_peg_grammar, P_tag_to_str); + c.p = peg_new(pn.filename, pn.str, pn.len, c.a, peg_P_peg_grammar, P_tag_to_str); node = peg_parse(c.p, P_sp, err); translate(c, node);