├── Cp1 ├── assign.cp1 ├── bool.cp1 ├── bools.cp1 ├── break.cp1 ├── call.cp1 ├── cast.cp1 ├── char.cp1 ├── common.cp1 ├── compare.cp1 ├── compile.cp1 ├── continue.cp1 ├── cvar.cp1 ├── enum.cp1 ├── export.cp1 ├── expr.cp1 ├── file.cp1 ├── func.cp1 ├── fvar.cp1 ├── gvar.cp1 ├── if.cp1 ├── index.cp1 ├── int.cp1 ├── loop.cp1 ├── lvar.cp1 ├── math.cp1 ├── meta.cp1 ├── null.cp1 ├── parse.cp1 ├── rdr.cp1 ├── ref.cp1 ├── return.cp1 ├── run.cp1 ├── size.cp1 ├── soa.cp1 ├── space.cp1 ├── stmt.cp1 ├── str.cp1 ├── struct.cp1 ├── switch.cp1 ├── unary.cp1 ├── var.cp1 └── wtr.cp1 ├── LICENSE ├── Makefile-clang ├── Makefile-gcc ├── Makefile-tcc ├── Makefile-template ├── Makefile.py ├── README.md ├── bin ├── cp1-compile.exe ├── cp1-parse.exe ├── cp1-qjs.exe └── cp1-run.exe ├── build-clang-debug.ninja ├── build-clang-release.ninja ├── build-clang.ninja ├── build-crc32c.c ├── build-crc32c.h ├── build-gcc-debug.ninja ├── build-gcc-release.ninja ├── build-gcc.ninja ├── build-qjs.ninja ├── build-tcc.ninja ├── build-template.ninja ├── build-windows.ninja ├── build.ninja.py ├── compile.c ├── compile.cp1.c ├── compile2.c ├── cp1-qjs.c ├── cp1.vim ├── cp1_parse.c ├── cp1_parse.y ├── crc32c.c ├── crc32c.h ├── examples ├── 01-hello.cp1 ├── 02-methods.cp1 ├── 03-loops.cp1 ├── 04-variables.cp1 ├── 05-virtual.cp1 └── README.md ├── export.cp1 ├── export.h ├── file.cp1.h ├── hashtable.c ├── hashtable2.c ├── images └── helloworld-2025-02-26.5.png ├── include ├── LibC │ ├── float.cp1 │ ├── limits.cp1 │ ├── math.cp1 │ ├── stdio.cp1 │ ├── stdlib.cp1 │ ├── string.cp1 │ └── time.cp1 ├── LibCp1 │ └── stdout.cp1 └── Posix │ ├── fcntl.cp1 │ ├── stat.cp1 │ ├── timerfd.cp1 │ └── unistd.cp1 ├── lemon.c ├── lempar.c ├── lex-re2c.c ├── lex.c ├── num.c ├── parse.c ├── parse.cp1.c ├── parse2.c ├── preprocess.cp1.c ├── qjs ├── cutils.c ├── cutils.h ├── libbf.c ├── libbf.h ├── libregexp-opcode.h ├── libregexp.c ├── libregexp.h ├── libunicode-table.h ├── libunicode.c ├── libunicode.h ├── list.h ├── quickjs-atom.h ├── quickjs-libc.c ├── quickjs-libc.h ├── quickjs-opcode.h ├── quickjs.c └── quickjs.h ├── run.cp1.c ├── system2.h ├── token.cp1 ├── unordered_dense.h └── upgrade.sh /Cp1/bool.cp1: -------------------------------------------------------------------------------- 1 | using Cp1 { 2 | expr-bool(value:bool):ExprI { 3 | var e:ExprBool; 4 | quick-alloc-one(e); 5 | e-idx! = expr-push(e.base, #bool); 6 | e.value = value; 7 | return e-idx; 8 | } 9 | using ExprI { 10 | wr-bool(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 11 | var e:ExprBool = expr; 12 | w.b(e.value); 13 | } 14 | rd-bool(e-idx:ExprI, r:Rdr) @case.rd() @inline { 15 | set-bool(e-idx, r.b()); 16 | } 17 | set-bool(e-idx:ExprI, val:bool) { 18 | var e:ExprBool; 19 | quick-alloc-one(e); 20 | e-idx.set(e.base, #bool); 21 | e.value = val; 22 | } 23 | write-bool(expr:Expr) @case.write() @inline { 24 | var e:ExprBool = expr; 25 | if e.value { 26 | output{"true"} 27 | } else { 28 | output{"false"} 29 | } 30 | } 31 | process-bool(expr:Expr, ok:bool&) @case.process() @inline { 32 | .include-stdbool = true; 33 | ok = true; 34 | } 35 | type-bool(expr:Expr, at:At&) @case.type() @inline { 36 | at = basic-type(#bool); 37 | } 38 | value-bool(le:this, reff:i32, paren:bool, v:Value, ok:bool&) @case.value() @inline { 39 | v.type = basic-type(#bool); 40 | v.info.init(); 41 | v.info.array-c = 0; 42 | v.info.ref-v[0] = ''\0; 43 | v.info.star-c = 0; 44 | v.reff = 1; 45 | v.paren = false; 46 | ok = true; 47 | } 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Cp1/bools.cp1: -------------------------------------------------------------------------------- 1 | using Cp1 { 2 | expr-bools(left:ExprI, right:ExprI, type:Bools):ExprI { 3 | var e:ExprBools; 4 | quick-alloc-one(e); 5 | e-idx! = expr-push(e.base, #bools); 6 | e.left = left; 7 | e.right = right; 8 | e.type = type; 9 | return e-idx; 10 | } 11 | expr-bools-add(bools:ExprI, right:ExprI):ExprI { 12 | var e:ExprBools = bools.ptr(); 13 | i! = e.item-c++; 14 | if e.item-cap <= e.item-c { 15 | old-cap! = e.item-cap; 16 | grow(e.item-cap, e.item-c); 17 | realloc(e.item-v, e.item-cap, old-cap); 18 | } 19 | e.item-v[i].expr = right; 20 | return bools; 21 | } 22 | enum Bools[#and, #or]:u8 { 23 | wr(e:this, w:Wtr) @inline { 24 | w.n1(e:base); 25 | } 26 | rd(e:this&, r:Rdr) @inline { 27 | e = r.n1():Bools; 28 | } 29 | } 30 | using ExprI { 31 | type-bools(expr:Expr, at:At&) @case.type() @inline { 32 | at = basic-type(#bool); 33 | } 34 | value-bools(e:this, reff:i32, paren:bool, v:Value, ok:bool&) @case.value() @inline { 35 | v.type = basic-type(#bool); 36 | v.info.init(); 37 | v.info.array-c = 0; 38 | v.info.ref-v[0] = ''\0; 39 | v.info.star-c = 0; 40 | v.reff = 1; 41 | v.paren = false; 42 | ok = true; 43 | } 44 | process-bools(expr:Expr, ok:bool&) @case.process() @inline { 45 | var e:ExprBools = expr; 46 | if !e.left.value(1, true, e.left-val) { return } 47 | if !e.right.value(1, true, e.right-val) { return } 48 | loop i = 0; e.item-c; i++ { 49 | item! = e.item-v[i]; 50 | if !item.expr.value(1, true, item.val) { return } 51 | } 52 | ok = true; 53 | } 54 | write-bools(expr:Expr) @case.write() @inline { 55 | var e:ExprBools = expr; 56 | switch e.type { 57 | case #and { 58 | output{''(} 59 | e.left.write-value(e.left-val); 60 | output{" && "} 61 | e.right.write-value(e.right-val); 62 | loop i = 0; e.item-c; i++ { 63 | output{" && "} 64 | item! = e.item-v[i]; 65 | item.expr.write-value(item.val); 66 | } 67 | output{'')} 68 | } 69 | case #or { 70 | output{''(} 71 | e.left.write-value(e.left-val); 72 | output{" || "} 73 | e.right.write-value(e.right-val); 74 | loop i = 0; e.item-c; i++ { 75 | output{" || "} 76 | item! = e.item-v[i]; 77 | item.expr.write-value(item.val); 78 | } 79 | output{'')} 80 | } 81 | } 82 | } 83 | wr-bools(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 84 | var e:ExprBools = expr; 85 | e.left.wr(w, header); 86 | e.right.wr(w, header); 87 | w.n1(e.item-c); 88 | loop i = 0; e.item-c; i++ { 89 | e.item-v[i].expr.wr(w, header); 90 | } 91 | e.type.wr(w); 92 | } 93 | rd-bools(e-idx:ExprI, r:Rdr) @case.rd() @inline { 94 | var e:ExprBools; 95 | quick-alloc-one(e); 96 | e-idx.set(e.base, #bools); 97 | e.left.rd(r); 98 | e.right.rd(r); 99 | item-c! = r.n1(); 100 | if item-c > 0 { 101 | e.item-c = item-c; 102 | quick-alloc-arr(e.item-v, item-c); 103 | loop i = 0; item-c; i++ { 104 | e.item-v[i].expr.rd(r); 105 | } 106 | } 107 | e.type.rd(r); 108 | } 109 | } 110 | 111 | 112 | } 113 | -------------------------------------------------------------------------------- /Cp1/break.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | struct StmtBreak[ 5 | base:Stmt., 6 | nest:u8, 7 | ]; 8 | stmt-break(id:Id, begin-row:u32, begin-col:u32, end-row:u32, end-col:u32) { 9 | var s:StmtBreak; 10 | quick-alloc-one(s); 11 | stmt-push(s.base, begin-row, begin-col, end-row, end-col, #break); 12 | // s.id = id; 13 | if .nest-stack-c <= 0 { 14 | C1.stdout{.input-path '': begin-row '': begin-col ": Cannot have a break because it:S not inside a loop\n"} 15 | C.exit(#failure); 16 | } 17 | s.nest = .nest-stack-c - 1; 18 | } 19 | using StmtSpace { 20 | wr-break(stmt:Stmt, w:Wtr, header:bool) @case.wr() @inline { 21 | var s:StmtBreak = stmt; 22 | w.n1(s.nest); 23 | } 24 | rd-break(space:StmtSpace, r:Rdr) @case.rd() @inline { 25 | var s:StmtBreak; 26 | quick-alloc-one(s); 27 | s.nest = r.n1(); 28 | space.stmt-push(s.base, .ctx-begin-row, .ctx-begin-col, .ctx-end-row, .ctx-end-col, #break); 29 | } 30 | } 31 | using Stmt { 32 | write-break(stmt:Stmt) @case.write() @inline { 33 | var s:StmtBreak = stmt; 34 | output{"goto break_" .nest-stack-id-v[s.nest] ";\n"} 35 | } 36 | process-break(stmt:Stmt, ok:bool&) @case.process() @inline { 37 | var s:StmtBreak = stmt; 38 | ok = true; 39 | } 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Cp1/cast.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | expr-cast-fast(expr:ExprI, type:At):ExprI { 5 | var e:ExprCastFast; 6 | quick-alloc-one(e); 7 | e-idx! = expr-push(e.base, #cast-fast); 8 | e.expr = expr; 9 | e.type = type; 10 | return e-idx; 11 | } 12 | using ExprCastFast { 13 | write-value(e:this, v:Value) @inline { 14 | output{"(("} 15 | e.type.write-type-info(v.info, 0); 16 | output{")("} 17 | e.expr.write-value(e.val); 18 | output{"))"} 19 | } 20 | } 21 | using ExprI { 22 | wr-cast-fast(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 23 | var e:ExprCastFast = expr; 24 | e.expr.wr(w, header); 25 | e.type.wr(w, header); 26 | } 27 | rd-cast-fast(e-idx:ExprI, r:Rdr) @case.rd() @inline { 28 | var e:ExprCastFast; 29 | quick-alloc-one(e); 30 | e-idx.set(e.base, #cast-fast); 31 | e.expr.rd(r); 32 | e.type.rd(r); 33 | } 34 | value-cast-fast(e:this, reff:i8, paren:bool, v:Value, ok:bool&) @case.value() @inline { 35 | var expr:ExprCastFast = e.ptr(); 36 | expr.expr.value(reff, paren, v); 37 | v.type = expr.type; 38 | ok = true; 39 | } 40 | type-cast-fast(expr:Expr, at:At&) @case.type() @inline { 41 | var e:ExprCastFast = expr; 42 | at = e.type; 43 | } 44 | process-cast-fast(expr:Expr, ok:bool&) @case.process() @inline { 45 | var e:ExprCastFast = expr; 46 | if !e.expr.value(1, false, e.val) { 47 | return; 48 | } 49 | if e.type == #nil { 50 | at! = e.val.type.ptr(); 51 | if at.def != #enum { 52 | C1.stdout{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col ": Operator ':base' was used but the type of expression was not an enum\n"} 53 | return; 54 | } 55 | e.type = at.decl.enumm.ptr().base-type; 56 | } 57 | e.type = at-validate(e.type, .ctx-func.at, .ctx-func.file, .ctx-begin-row, .ctx-begin-col); 58 | e.type.output(.ctx-func.file, .ctx-begin-row, .ctx-begin-col); 59 | ok = true; 60 | } 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /Cp1/char.cp1: -------------------------------------------------------------------------------- 1 | using Cp1 { 2 | expr-char(value:i32):ExprI { 3 | var e:ExprChar; 4 | quick-alloc-one(e); 5 | e-idx! = expr-push(e.base, #char); 6 | e.value = value; 7 | return e-idx; 8 | } 9 | write-char(c:char); 10 | using ExprI { 11 | wr-char(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 12 | var e:ExprChar = expr; 13 | w.n(e.value); 14 | } 15 | rd-char(e-idx:ExprI, r:Rdr) @case.rd() @inline { 16 | var e:ExprChar; 17 | quick-alloc-one(e); 18 | e-idx.set(e.base, #char); 19 | e.value = r.n(); 20 | } 21 | write-char(expr:Expr) @case.write() @inline { 22 | var e:ExprChar = expr; 23 | Cp1.write-char(e.value); 24 | } 25 | process-char(expr:Expr, ok:bool&) @case.process() @inline { 26 | ok = true; 27 | } 28 | type-char(expr:Expr, at:At&) @case.type() @inline { 29 | at = basic-type(#char); 30 | } 31 | value-char(le:this, reff:i32, paren:bool, v:Value, ok:bool&) @case.value() @inline { 32 | v.type = basic-type(#char); 33 | v.info.init(); 34 | v.info.array-c = 0; 35 | v.info.ref-v[0] = ''\0; 36 | v.info.star-c = 0; 37 | v.reff = 1; 38 | v.paren = false; 39 | ok = true; 40 | } 41 | } 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Cp1/compare.cp1: -------------------------------------------------------------------------------- 1 | using C1 = LibCp1; 2 | using Cp1 { 3 | enum Compare[#eq, #not-eq, #lt, #le, #gt, #ge]:u8 { 4 | wr(e:this, w:Wtr) @inline { 5 | w.n1(e:base); 6 | } 7 | rd(e:this&, r:Rdr) @inline { 8 | e = r.n1():Compare; 9 | } 10 | } 11 | expr-compare(left:ExprI, right:ExprI, type:Compare):ExprI { 12 | var e:ExprCompare; 13 | quick-alloc-one(e); 14 | e-idx! = expr-push(e.base, #compare); 15 | e.left = left; 16 | e.right = right; 17 | e.type = type; 18 | return e-idx; 19 | } 20 | using ExprI { 21 | wr-compare(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 22 | var e:ExprCompare = expr; 23 | e.left.wr(w, header); 24 | e.right.wr(w, header); 25 | e.type.wr(w); 26 | } 27 | rd-compare(e-idx:ExprI, r:Rdr) @case.rd() @inline { 28 | var e:ExprCompare; 29 | quick-alloc-one(e); 30 | e-idx.set(e.base, #compare); 31 | e.left.rd(r); 32 | e.right.rd(r); 33 | e.type.rd(r); 34 | } 35 | write-compare(expr:Expr) @case.write() @inline { 36 | var e:ExprCompare = expr; 37 | e.left.write-value(e.left-val); 38 | switch e.type { 39 | case #eq { output{" == "} } 40 | case #not-eq { output{" != "} } 41 | case #lt { output{" < "} } 42 | case #le { output{" <= "} } 43 | case #gt { output{" > "} } 44 | case #ge { output{" >= "} } 45 | } 46 | e.right.write-value(e.right-val); 47 | } 48 | value-compare(e:this, reff:i8, paren:bool, v:Value, ok:bool&) @case.value() @inline { 49 | var expr:ExprCompare = e.ptr(); 50 | v.type = basic-type(#bool); 51 | v.info.init(); 52 | v.info.array-c = 0; 53 | v.info.ref-v[0] = ''\0; 54 | v.info.star-c = 0; 55 | v.reff = 1; 56 | v.paren = paren; 57 | ok = true; 58 | } 59 | type-compare(expr:Expr, at:At&) @case.type() @inline { 60 | var e:ExprCompare = expr; 61 | at = basic-type(#bool); 62 | } 63 | process-compare(expr:Expr, ok:bool&) @case.process() @inline { 64 | var e:ExprCompare = expr; 65 | if !e.left.value(1, true, e.left-val) { 66 | return; 67 | } 68 | e.right.try-deduce(e.left-val.type); 69 | if !e.right.value(1, true, e.right-val) { 70 | return; 71 | } 72 | if !compatible(e.left-val.type, e.left-val.info.star-c + e.left-val.type.pointer(), e.right-val.type, e.right-val.info.star-c + e.right-val.type.pointer()) { 73 | C1.stdbuf{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col ": Type mismatch for the left and right operands of the comparison operator '"} 74 | switch e.type { 75 | case #eq { C1.stdbuf{"=="} } 76 | case #not-eq { C1.stdbuf{"!="} } 77 | case #lt { C1.stdbuf{"<"} } 78 | case #le { C1.stdbuf{"<="} } 79 | case #gt { C1.stdbuf{">"} } 80 | case #ge { C1.stdbuf{">="} } 81 | } 82 | C1.stdout{"'\n"} 83 | return; 84 | } 85 | ok = true; 86 | } 87 | } 88 | 89 | 90 | } 91 | -------------------------------------------------------------------------------- /Cp1/continue.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | struct StmtContinue[ 5 | base:Stmt., 6 | nest:u8, 7 | ]; 8 | stmt-continue(id:Id, begin-row:u32, begin-col:u32, end-row:u32, end-col:u32) { 9 | var s:StmtContinue; 10 | quick-alloc-one(s); 11 | stmt-push(s.base, begin-row, begin-col, end-row, end-col, #continue); 12 | // s.id = id; 13 | if .nest-stack-c <= 0 { 14 | C1.stdout{.input-path '': begin-row '': begin-col ": Cannot have a continue because it:S not inside a loop\n"} 15 | C.exit(#failure); 16 | } 17 | s.nest = .nest-stack-c - 1; 18 | } 19 | using StmtSpace { 20 | wr-continue(stmt:Stmt, w:Wtr, header:bool) @case.wr() @inline { 21 | var s:StmtContinue = stmt; 22 | w.n1(s.nest); 23 | } 24 | rd-continue(space:StmtSpace, r:Rdr) @case.rd() @inline { 25 | var s:StmtContinue; 26 | quick-alloc-one(s); 27 | s.nest = r.n1(); 28 | space.stmt-push(s.base, .ctx-begin-row, .ctx-begin-col, .ctx-end-row, .ctx-end-col, #continue); 29 | } 30 | } 31 | using Stmt { 32 | write-continue(stmt:Stmt) @case.write() @inline { 33 | var s:StmtContinue = stmt; 34 | output{"goto continue_" .nest-stack-id-v[s.nest] ";\n"} 35 | } 36 | process-continue(stmt:Stmt, ok:bool&) @case.process() @inline { 37 | var s:StmtContinue = stmt; 38 | ok = true; 39 | } 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Cp1/cvar.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | enum Cvar[#nil = -1, #0]:i32 { 5 | rd(c:this&, r:Rdr) @inline { 6 | idx! = (r.n() - 1):Cvar; 7 | if idx == #nil { 8 | c = #nil; 9 | } else { 10 | c = .cvar-table[idx]; 11 | } 12 | } 13 | wr(g:this, w:Wtr) @inline { 14 | w.n(g:base + 1); 15 | } 16 | process(c:this):bool { 17 | num! = c:u32; 18 | n3! = num >> 3; 19 | n17! = 1 << (num & 7); 20 | if (.cvar-is-outputted[n3] & n17) != 0 { return true } 21 | .cvar-is-outputted[n3] |= n17; 22 | 23 | cvar! = c.ptr(); 24 | 25 | if (cvar.flags & #set-expr) != #0 { 26 | if !cvar.expr-set.process() { return false } 27 | } elif cvar.last-cvar != #nil { 28 | if !cvar.last-cvar.process() { return false } 29 | } 30 | 31 | at-i! = cvar.decl.type; 32 | if at-i != #nil { 33 | at-i = at-validate(at-i, cvar.at, cvar.file, cvar.row, cvar.col); 34 | cvar.decl.type = at-i; 35 | at! = at-i.ptr(); 36 | if (&&, at.type != #basic, at.decl.structt == #nil) { 37 | C1.stdout{"Error, the type '" at.name.id "' used in cvar '." cvar.decl.name "' was not defined\n"} 38 | return false; 39 | } 40 | at-i.output(cvar.file, cvar.row, cvar.col); 41 | } 42 | 43 | // if (gvar.flags & #no-decl) == #0 { 44 | .cvar-outputted-v[.cvar-outputted-c++] = c; 45 | // } 46 | 47 | return true; 48 | } 49 | ptr(c:this):CvarData @inline { 50 | return .cvar-v[c]; 51 | } 52 | write(c:this) @inline { 53 | cvar! = c.ptr(); 54 | if (cvar.decl.flags & #real-name) != #0 { 55 | // if (cvar.decl.name.len() == 7) && (C.memcmp(cvar.decl.name.str(), "failure", 7) == 0) { 56 | // output{"EXIT_FAILURE"} 57 | // } else { 58 | output{cvar.decl.real-name} 59 | // } 60 | } else { 61 | cvar.at.write-space(); 62 | output{"_C" cvar.decl.name.c-name()} 63 | } 64 | } 65 | } 66 | enum CvarFlags[ 67 | #0, 68 | #set-expr = 1, 69 | #as-enum = 2, 70 | #no-name = 4, 71 | // #real-name = 2, 72 | ]:u8 { 73 | wr(f:this, w:Wtr) @inline { 74 | w.n1(f:base); 75 | } 76 | rd(f:this&, r:Rdr) @inline { 77 | f = r.n1():CvarFlags; 78 | } 79 | } 80 | var cvar-c:Cvar; 81 | var cvar-cap:Cvar; 82 | var cvar-v:CvarData.[]; 83 | expr-cvar(at:At, name:Id):ExprI { 84 | var e:ExprCvar; 85 | quick-alloc-one(e); 86 | e-idx! = expr-push(e.base, #cvar); 87 | e.at = at; 88 | e.name = name; 89 | return e-idx; 90 | } 91 | using ExprI { 92 | write-cvar(expr:Expr) @case.write() @inline { 93 | var e:ExprCvar = expr; 94 | e.cvar.write(); 95 | } 96 | wr-cvar(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 97 | var e:ExprCvar = expr; 98 | e.at.wr(w, header); 99 | e.name.wr(w, header); 100 | } 101 | rd-cvar(e-idx:ExprI, r:Rdr) @case.rd() @inline { 102 | At.rd(at!, r); 103 | Id.rd(name!, r); 104 | set-cvar(e-idx, at, name); 105 | } 106 | set-cvar(e-idx:ExprI, at:At, name:Id) { 107 | var e:ExprCvar; 108 | quick-alloc-one(e); 109 | e-idx.set(e.base, #cvar); 110 | e.at = at; 111 | e.name = name; 112 | e.try = #nil; 113 | } 114 | value-cvar(e:this, reff:i8, paren:bool, v:Value, ok:bool&) @case.value() @inline { 115 | var expr:ExprCvar = e.ptr(); 116 | cvar! = expr.cvar.ptr(); 117 | if (cvar.decl.type == #nil) && ((cvar.flags & #set-expr) != #0) { 118 | ok = cvar.expr-set.value(reff, paren, v); 119 | } else { 120 | v.set(reff, paren, cvar.decl.type, cvar.decl.type-info); 121 | if v.reff == 1 { 122 | v.paren = false; 123 | } 124 | ok = true; 125 | } 126 | } 127 | type-cvar(expr:Expr, at:At&) @case.type() @inline { 128 | var e:ExprCvar = expr; 129 | cvar! = e.cvar.ptr(); 130 | if (cvar.decl.type == #nil) && ((cvar.flags & #set-expr) != #0) { 131 | at = cvar.expr-set.type(); 132 | } else { 133 | at = cvar.decl.type; 134 | } 135 | } 136 | process-cvar(expr:Expr, ok:bool&) @case.process() @inline { 137 | var e:ExprCvar = expr; 138 | name! = e.name; 139 | var cvar-c, cvar-v; 140 | if e.try != #nil { 141 | at! = e.try.ptr(); 142 | cvar-c = at.cvar-c; 143 | cvar-v = at.cvar-v; 144 | // C1.stdout{"e.try = " e.try ", " at.name.id ", " name ", cvar-c " cvar-c ''\n} 145 | loop i = 0; cvar-c; i++ { 146 | cvar! = cvar-v[i]; 147 | // C1.stdout{"- " cvar.ptr.decl.name ''\n} 148 | if cvar.ptr().decl.name == name { 149 | if !cvar.process() { return } 150 | e.cvar = cvar; 151 | ok = true; 152 | return; 153 | } 154 | } 155 | } 156 | var at-idx, at; 157 | try-parent! = false; 158 | if e.at != #nil { 159 | e.at = at-validate(e.at, .ctx-func.at, .ctx-func.file, .ctx-begin-row, .ctx-begin-col); 160 | at-idx = e.at; 161 | at = at-idx.ptr(); 162 | cvar-c = at.cvar-c; 163 | cvar-v = at.cvar-v; 164 | } else { 165 | at-idx = .ctx-func.at; 166 | at = at-idx.ptr(); 167 | cvar-c = at.cvar-c; 168 | cvar-v = at.cvar-v; 169 | try-parent = true; 170 | } 171 | loop { 172 | loop i = 0; cvar-c; i++ { 173 | cvar! = cvar-v[i]; 174 | if cvar.ptr().decl.name == name { 175 | if !cvar.process() { return } 176 | e.cvar = cvar; 177 | ok = true; 178 | return; 179 | } 180 | } 181 | if !try-parent { break } 182 | if at-idx == #root { break } 183 | at-idx = at.parent; 184 | at = at-idx.ptr(); 185 | cvar-c = at.cvar-c; 186 | cvar-v = at.cvar-v; 187 | } 188 | C1.stdout{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col " - " .ctx-end-row '': .ctx-end-col ": Cannot find #" name ''\n} 189 | } 190 | try-deduce-cvar(expr:Expr, at:At) @case.try-deduce() @inline { 191 | var e:ExprCvar = expr; 192 | if e.at == #nil { 193 | e.try = at; 194 | } 195 | } 196 | } 197 | 198 | 199 | } 200 | -------------------------------------------------------------------------------- /Cp1/enum.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | enum Enum[#nil = -1, #0, #1]:i32 { 5 | wr(f:this, w:Wtr) @inline { 6 | w.n(f + #1); 7 | } 8 | rd(f:this&, r:Rdr) @inline { 9 | f = (r.n() - #1):Func; 10 | } 11 | ptr(f:this):EnumData @inline { 12 | return .enum-v[f]; 13 | } 14 | output(e-i:this) { 15 | num! = e-i:u32; 16 | n3! = num >> 3; 17 | n17! = 1 << (num & 7); 18 | if (.enum-is-outputted[n3] & n17) != 0 { return } 19 | .enum-is-outputted[n3] |= n17; 20 | e! = e-i.ptr(); 21 | 22 | e.base-type.output(e.file, e.begin-row, e.begin-col); 23 | 24 | if e.include != #nil { 25 | e.include.output(); 26 | } 27 | 28 | // if (e.flags & #no-decl) == #0 { 29 | .enum-outputted-v[.enum-outputted-c++] = e-i; 30 | // } 31 | } 32 | } 33 | enum EnumFlags[ 34 | #0, 35 | #real-name = 1, 36 | #no-decl = 2, 37 | #soa-field = 4, 38 | #overload-get = 8, 39 | #overload-set = 16, 40 | #overload-math = 32, 41 | ]:u8 { 42 | wr(e:this, w:Wtr) @inline { 43 | w.n1(e:base); 44 | } 45 | rd(e:this&, r:Rdr) @inline { 46 | e = r.n1():EnumFlags; 47 | } 48 | } 49 | var enum-c:Enum; 50 | var enum-cap:Enum; 51 | var enum-v:EnumData[]; 52 | var decl-enum-row:u32; 53 | var decl-enum-col:u32; 54 | var decl-enum-at:At; 55 | var decl-enum-real-name:Id; 56 | var decl-enum-flags:EnumFlags; 57 | var decl-enum-last-cvar:Cvar; 58 | var decl-enum-soa-field-gvar-at:At; 59 | var decl-enum-soa-field-gvar-id:Id; 60 | decl-var-as-evar() { 61 | evar! = .decl-evar-c++; 62 | if .decl-evar-cap <= .decl-evar-c { 63 | grow(.decl-evar-cap, .decl-evar-c); 64 | realloc(.decl-evar-v, .decl-evar-cap); 65 | } 66 | .decl-evar-v[evar].copy-from(.decl-var); 67 | } 68 | decl-at-begin-enum(name:Id, row:u32, col:u32) { 69 | .decl-enum-row = row; 70 | .decl-enum-col = col; 71 | .build-at = .decl-at; 72 | decl-at-add(name, #struct-enum, row, col); 73 | .decl-at-v[.decl-at-c++] = .decl-at; 74 | .decl-at = .build-at; 75 | .decl-enum-at = .build-at; 76 | .decl-enum-flags = #0; 77 | .decl-enum-last-cvar = #nil; 78 | // C1.stdout{"began enum at:\n"} 79 | // at-i! = .build-at; 80 | // loop { 81 | // at! = at-i.ptr(); 82 | // C1.stdout{"- " at.name.id ''\n} 83 | // at-i = at.parent; 84 | // if at-i == #root { break } 85 | // } 86 | } 87 | enum-base-begin() { 88 | .decl-at = .decl-at.ptr().parent; 89 | } 90 | // enum-base-end() { 91 | // .decl-at = .decl-enum-at; 92 | // } 93 | enum-attr-soa-field(at:At, id:Id) { 94 | .decl-enum-flags |= #soa-field; 95 | .decl-enum-soa-field-gvar-at = at; 96 | .decl-enum-soa-field-gvar-id = id; 97 | } 98 | enum-attr-no-decl() { 99 | .decl-enum-flags |= #no-decl; 100 | } 101 | enum-attr-real-name(id:Id) { 102 | .decl-enum-flags |= #real-name; 103 | .decl-enum-real-name = id; 104 | } 105 | decl-enum-end(base-type:At, row:u32, col:u32) { 106 | s-idx! = .enum-c++; 107 | if .enum-cap <= .enum-c { 108 | old-cap! = .enum-cap; 109 | .enum-cap = grow(.enum-c:base):Enum; 110 | realloc(.enum-v, .enum-cap:base, old-cap:base); 111 | } 112 | var s:EnumData; 113 | quick-alloc-one(s); 114 | .enum-v[s-idx] = s; 115 | s.begin-row = .decl-enum-row; 116 | s.begin-col = .decl-enum-col; 117 | s.end-row = row; 118 | s.end-col = col; 119 | s.include = .decl-include; 120 | s.at = .decl-enum-at; 121 | s.base-type = base-type; 122 | .decl-at = .decl-enum-at; 123 | s.flags = .decl-enum-flags; 124 | s.soa-field-gvar-at = .decl-enum-soa-field-gvar-at; 125 | s.soa-field-gvar-id = .decl-enum-soa-field-gvar-id; 126 | s.real-name = .decl-enum-real-name; 127 | .decl-enum-last-cvar = #nil; 128 | // s.name = .decl-enum-name; 129 | // s.evar-c = .decl-evar-c; 130 | // C1.stdout{"There are " s.evar-c " evars\n"} 131 | // loop i = 0; .decl-evar-c; i ++ { 132 | // a! = s.evar-v[i]; 133 | // a.decl.copy-from(.decl-evar-v[i]); 134 | // // C1.stdout{"- " a.name ''\n} 135 | // } 136 | } 137 | var last-cvar:Cvar; 138 | enum-add-cvar(name:Id, row:u32, col:u32) { 139 | c-idx! = .cvar-c++; 140 | .last-cvar = c-idx; 141 | if .cvar-cap <= .cvar-c { 142 | old-cap! = .cvar-cap; 143 | .cvar-cap = grow(.cvar-c:base):Cvar; 144 | realloc(.cvar-v, .cvar-cap:base, old-cap:base); 145 | } 146 | c! = c-idx.ptr(); 147 | c.row = row; 148 | c.col = col; 149 | c.include = .decl-include; 150 | c.at = .decl-at; 151 | c.decl.name = name; 152 | c.decl.type = .decl-enum-at; 153 | c.decl.type-info.init(); 154 | c.flags = #as-enum; 155 | c.last-cvar = .decl-enum-last-cvar; 156 | .decl-enum-last-cvar = c-idx; 157 | } 158 | decl-add-cvar(name:Id, row:u32, col:u32) { 159 | c-idx! = .cvar-c++; 160 | .last-cvar = c-idx; 161 | if .cvar-cap <= .cvar-c { 162 | old-cap! = .cvar-cap; 163 | .cvar-cap = grow(.cvar-c:base):Cvar; 164 | realloc(.cvar-v, .cvar-cap:base, old-cap:base); 165 | } 166 | c! = c-idx.ptr(); 167 | c.row = row; 168 | c.col = col; 169 | c.include = .decl-include; 170 | c.at = .decl-at; 171 | .decl-var.name = name; 172 | c.decl.copy-from(.decl-var); 173 | if (c.decl.flags & #real-name) != #0 { 174 | if (c.decl.name.len() == 7) && (C.memcmp(c.decl.name.str(), "failure", 7) == 0) { 175 | C1.stdout{"failure has a real-name at decl-add-cvar\n"} 176 | } 177 | } 178 | c.flags = #0; 179 | } 180 | enum-set-cvar-expr(set:ExprI) { 181 | c! = .last-cvar.ptr(); 182 | c.flags |= #set-expr; 183 | c.expr-set = set; 184 | } 185 | cvar-attr-real-name(name:Id) { 186 | c! = .last-cvar.ptr(); 187 | c.decl.flags |= #real-name; 188 | c.decl.real-name = name; 189 | } 190 | cvar-attr-no-decl() { 191 | c! = .last-cvar.ptr(); 192 | c.decl.flags |= #no-decl; 193 | } 194 | cvar-attr-no-name() { 195 | c! = .last-cvar.ptr(); 196 | c.flags |= #no-name; 197 | } 198 | 199 | 200 | } 201 | -------------------------------------------------------------------------------- /Cp1/export.cp1: -------------------------------------------------------------------------------- 1 | using Cp1 { 2 | export() { 3 | quick-alloc-undo(0); 4 | decl-import(#nil, 0, 0, false); 5 | decl-template-inst(#nil, 0, 0); 6 | decl-template-code(#nil, 0, false, false); 7 | decl-func-begin(#0, 0, 0); 8 | decl-func-end(0, 0); 9 | decl-struct-end(0, 0); 10 | decl-var-begin(#0, 0, 0); 11 | decl-var-attr-real-name(#nil); 12 | decl-var-attr-extern(); 13 | decl-var-attr-no-decl(); 14 | decl-var-end(); 15 | decl-var-as-farg(0, 0); 16 | farg-next-group(); 17 | decl-var-as-this(); 18 | decl-var-as-fvar(); 19 | func-body-end(); 20 | func-header-end(); 21 | expr-push-call(0, 0); 22 | expr-pop-func(#nil, #nil); 23 | expr-pop-metafunc(#nil, #nil); 24 | expr-pop-metamethod(#nil, #nil); 25 | expr-pop-method(#nil, #nil); 26 | metacarg-push(#nil); 27 | metacarg-next-group(); 28 | carg-push(#nil); 29 | carg-push-str(#nil); 30 | carg-next-group(); 31 | expr2stmt(#nil, 0, 0, 0, 0); 32 | stmt-return(#nil, 0, 0, 0, 0); 33 | stmt-continue(#nil, 0, 0, 0, 0); 34 | stmt-break(#nil, 0, 0, 0, 0); 35 | func-attr-main(); 36 | func-attr-decl(); 37 | func-attr-cp1-name(); 38 | func-attr-process(); 39 | func-attr-inline(); 40 | func-attr-var-args(); 41 | func-attr-no-decl(); 42 | func-attr-no-body(); 43 | func-attr-overload-get(); 44 | func-attr-overload-set(); 45 | func-attr-overload-math(); 46 | func-attr-real-name(#nil); 47 | func-attr-meta-method(#nil, #nil, #nil); 48 | func-attr-case(#nil); 49 | enum-attr-soa-field(#nil, #nil); 50 | enum-attr-no-decl(); 51 | enum-attr-real-name(#nil); 52 | expr-lvar(#0, 0, 0, 0); 53 | expr-gvar(#nil, #0, 0, 0); 54 | expr-fvar(#nil, #nil, 0, 0); 55 | expr-soa-field(#nil, #nil, #nil, 0, 0); 56 | expr-assign(#0, #0, #eq); 57 | expr-math(#0, #0, #add); 58 | expr-math-add(#0, #0); 59 | expr-bools(#0, #0, #and); 60 | expr-bools-add(#0, #0); 61 | token-name(#nil); 62 | decl-var-type(#nil); 63 | decl-var-this(); 64 | // stmt-lvar-begin(0, 0); 65 | stmt-lvar-add(#0, #nil, 0, 0); 66 | stmt-lvar-end(0, 0); 67 | decl-include-begin(#0, 0, 0); 68 | decl-include-end(); 69 | decl-at-basic(#root); 70 | decl-at-add(#0, #module, 0, 0); 71 | decl-at-begin(0, 0); 72 | decl-at-begin-struct(#nil, 0, 0); 73 | decl-at-end(); 74 | decl-alias(#nil, #nil, 0, 0); 75 | at-push(#0, #module, 0, 0); 76 | at-done(); 77 | at-begin(); 78 | at-begin-relative(); 79 | at-begin-relative-pause(); 80 | at-begin-relative-resume(); 81 | at-root(); 82 | at-alias(#nil, 0, 0); 83 | at-graves(0, 0, 0); 84 | // at-create(); 85 | at-basic-type(#i32); 86 | decl-var-as-gvar(); 87 | type-info-arr(null, 0); 88 | type-info-ref(0); 89 | type-info-static(); 90 | type-info-begin(false); 91 | type-info-finalize(); 92 | expr-int(0, #i32); 93 | expr-int64(0, #u64); 94 | expr-f32(0.0f); 95 | expr-size-of-type(#nil); 96 | expr-null(); 97 | decl-at-begin-enum(#nil, 0, 0); 98 | // decl-enum-begin(#nil, 0, 0); 99 | decl-enum-end(#nil, 0, 0); 100 | expr-cvar(#nil, #nil); 101 | enum-add-cvar(#nil, 0, 0); 102 | decl-add-cvar(#nil, 0, 0); 103 | enum-set-cvar-expr(#nil); 104 | struct-attr-real-name(#nil); 105 | struct-attr-aligned(0); 106 | struct-attr-union(); 107 | struct-attr-no-decl(); 108 | expr-str(#nil); 109 | expr-unary(#nil, #neg); 110 | expr-ref(#nil); 111 | expr-cast-fast(#nil, #nil); 112 | expr-index(#nil, null, 0); 113 | enum-base-begin(); 114 | stmt-switch-begin(); 115 | stmt-switch-set(#nil, 0, 0, 0, 0, #nil); 116 | stmt-switch-expr-add(#nil); 117 | stmt-switch-case-begin(0, 0, 0, 0, false); 118 | stmt-switch-case-end(); 119 | stmt-switch-default-begin(0, 0, 0, 0, false); 120 | stmt-switch-default-end(); 121 | stmt-switch-end(); 122 | stmt-if-begin(); 123 | stmt-if-set(#nil, 0, 0, 0, 0); 124 | stmt-if-end(); 125 | stmt-loop-begin(); 126 | stmt-loop-set(#nil, 0, 0, 0, 0, null); 127 | stmt-loop-end(); 128 | stmt-elif-begin(); 129 | stmt-elif-set(#nil, 0, 0, 0, 0); 130 | stmt-elif-end(); 131 | stmt-else-set(); 132 | stmt-else-end(); 133 | stmt-if-end-ifs(); 134 | stmt-space-begin(); 135 | stmt-space-begin-detach(); 136 | stmt-space-end(); 137 | expr-compare(#nil, #nil, #eq); 138 | expr-bool(false); 139 | expr-char(0); 140 | cvar-attr-real-name(#nil); 141 | cvar-attr-no-decl(); 142 | cvar-attr-no-name(); 143 | } 144 | 145 | 146 | } 147 | -------------------------------------------------------------------------------- /Cp1/fvar.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | enum Fvar[#nil = -1, #0]:i32; 5 | expr-fvar(expr:ExprI, member:Id, row:u32, col:u32):ExprI { 6 | if .decl-func-ctx-space == null { 7 | C1.stdout{.input-path '': row '': row ": Use of member variables are now allowed here\n"} 8 | C.exit(#failure); 9 | } 10 | var e:ExprFvar; 11 | quick-alloc-one(e); 12 | e-idx! = expr-push(e.base, #fvar); 13 | e.expr = expr; 14 | e.member = member; 15 | return e-idx; 16 | } 17 | using ExprI { 18 | wr-fvar(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 19 | var e:ExprFvar = expr; 20 | e.expr.wr(w, header); 21 | e.member.wr(w, header); 22 | } 23 | rd-fvar(e-idx:ExprI, r:Rdr) @case.rd() @inline { 24 | ExprI.rd(expr!, r); 25 | Id.rd(member!, r); 26 | e-idx.set-fvar(expr, member); 27 | } 28 | set-fvar(e-idx:this, expr:ExprI, member:Id) { 29 | var e:ExprFvar; 30 | quick-alloc-one(e); 31 | e-idx.set(e.base, #fvar); 32 | e.expr = expr; 33 | e.member = member; 34 | } 35 | type-fvar(expr:Expr, at:At&) @case.type() @inline { 36 | var e:ExprFvar = expr; 37 | at = e.val.type.ptr().decl.structt.ptr().fvar-v[e.fvar].decl.type; 38 | } 39 | value-fvar(expr:this, reff:i8, paren:bool, v:Value, ok:bool&) @case.value() @inline { 40 | var e:ExprFvar = expr.ptr(); 41 | fvar! = e.val.type.ptr().decl.structt.ptr().fvar-v[e.fvar]; 42 | v.set(reff, paren, fvar.decl.type, fvar.decl.type-info); 43 | if v.reff == 1 { 44 | v.paren = false; 45 | } 46 | ok = true; 47 | } 48 | write-fvar(expr:Expr) @case.write() @inline { 49 | var e:ExprFvar = expr; 50 | e.expr.write-value(e.val); 51 | output{''.} 52 | e.val.type.ptr().decl.structt.ptr().fvar-v[e.fvar].decl.write(#fvar); 53 | } 54 | process-fvar(expr:Expr, ok:bool&) @case.process() @inline { 55 | var e:ExprFvar = expr; 56 | type-i! = e.expr.type(); 57 | if type-i == #nil { 58 | C1.stdout{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col " - " .ctx-end-row '': .ctx-end-col " Cannot get member '." e.member "' from an expression of unknown type\n"} 59 | return; 60 | } 61 | type! = type-i.ptr(); 62 | if type.def != #struct { 63 | C1.stdout{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col " - " .ctx-end-row '': .ctx-end-col " Cannot get member '." e.member "' because the type is not a struct or union\n"} 64 | return; 65 | } 66 | if !e.expr.value(1 - type-i.pointer(), true, e.val) { return } 67 | if e.val.info.array-c > 0 { 68 | C1.stdout{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col " - " .ctx-end-row '': .ctx-end-col " Cannot get member '." e.member "' because the expression is an array(" e.val.info.array-c ")\n"} 69 | return; 70 | } 71 | if type.decl.structt == #nil { 72 | C1.stdout{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col " - " .ctx-end-row '': .ctx-end-col " Cannot get member '." e.member "' because the type '/" type.name.id "' was not defined\n"} 73 | return; 74 | } 75 | struct-i! = type.decl.structt; 76 | struct-i.output(); 77 | structt! = struct-i.ptr(); 78 | member! = e.member; 79 | loop i = 0:Fvar; structt.fvar-c; i++ { 80 | if structt.fvar-v[i].decl.name == member { 81 | e.fvar = i; 82 | ok = true; 83 | return; 84 | } 85 | } 86 | C1.stdout{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col " - " .ctx-end-row '': .ctx-end-col " Cannot find member named '." e.member "' from type '/" type.name.id "'\n"} 87 | } 88 | } 89 | 90 | 91 | } 92 | -------------------------------------------------------------------------------- /Cp1/gvar.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | enum GvarFlags[#0, #no-decl = 1]:u8; 5 | enum Gvar[#nil = -1, #0]:i32 { 6 | process(g:this):bool { 7 | num! = g:u32; 8 | n3! = num >> 3; 9 | n17! = 1 << (num & 7); 10 | if (.gvar-is-outputted[n3] & n17) != 0 { return true } 11 | .gvar-is-outputted[n3] |= n17; 12 | 13 | gvar! = g.ptr(); 14 | at-i! = gvar.decl.type; 15 | at! = at-i.ptr(); 16 | if !gvar.decl.process(gvar.file, gvar.row, gvar.col, gvar.at) { return false } 17 | 18 | if (gvar.flags & #no-decl) == #0 { 19 | .gvar-outputted-v[.gvar-outputted-c++] = g; 20 | } 21 | 22 | return true; 23 | } 24 | write(g:this) { 25 | gvar! = g.ptr(); 26 | gvar.decl.write(#gvar); 27 | } 28 | // write(g:this) { 29 | // gvar! = g.ptr(); 30 | // if (gvar.decl.flags & #real-name) != #0 { 31 | // output{gvar.decl.real-name} 32 | // return; 33 | // } 34 | // gvar.at.write-space(); 35 | // output{"_G" gvar.decl.name.c-name} 36 | // } 37 | ptr(g:this):DeclGvar @inline { 38 | return .gvar-v[g]; 39 | } 40 | } 41 | expr-gvar(at:At, name:Id, row:u32, col:u32):ExprI { 42 | if .decl-func-ctx-space == null { 43 | C1.stdout{.input-path '': row '': row ": Use of global variables are now allowed here\n"} 44 | C.exit(#failure); 45 | } 46 | var e:ExprGvar; 47 | quick-alloc-one(e); 48 | e-idx! = expr-push(e.base, #gvar); 49 | e.at = at; 50 | e.name = name; 51 | return e-idx; 52 | } 53 | using ExprI { 54 | value-gvar(g:this, reff:i32, paren:bool, v:Value, ok:bool&) @case.value() @inline { 55 | var e:ExprGvar = g.ptr(); 56 | gvar! = e.gvar.ptr(); 57 | v.set(reff, paren, gvar.decl.type, gvar.decl.type-info); 58 | if v.reff == 1 { 59 | v.paren = false; 60 | } 61 | ok = true; 62 | } 63 | type-gvar(expr:Expr, at:At&) @case.type() @inline { 64 | var e:ExprGvar = expr; 65 | gvar! = e.gvar.ptr(); 66 | at = gvar.decl.type; 67 | } 68 | wr-gvar(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 69 | var e:ExprGvar = expr; 70 | e.at.wr(w, header); 71 | e.name.wr(w, header); 72 | } 73 | rd-gvar(e-idx:ExprI, r:Rdr) @case.rd() @inline { 74 | At.rd(at-idx!, r); 75 | Id.rd(name!, r); 76 | e-idx.set-gvar(at-idx, name); 77 | } 78 | set-gvar(e-idx:this, at-idx:At, name:Id) { 79 | var e:ExprGvar; 80 | quick-alloc-one(e); 81 | e-idx.set(e.base, #gvar); 82 | try-parent! = false; 83 | if at-idx == #nil { 84 | at-idx = .ctx-func.at; 85 | try-parent = true; 86 | } else { 87 | at-idx = at-validate(at-idx, .ctx-func.at, .ctx-func.file, .ctx-begin-row, .ctx-begin-col); 88 | } 89 | loop { 90 | at! = at-idx.ptr(); 91 | loop i = 0; at.gvar-c; i++ { 92 | gvar! = at.gvar-v[i]; 93 | if gvar.ptr().decl.name == name { 94 | e.gvar = gvar; 95 | return; 96 | } 97 | } 98 | if !try-parent { break } 99 | if at-idx == #root { break } 100 | at-idx = at.parent; 101 | } 102 | C1.stdout{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col " - " .ctx-end-row '': .ctx-end-col ": Cannot find gvar '." name "'\n"} 103 | C.exit(#failure); 104 | } 105 | write-gvar(expr:Expr) @case.write() @inline { 106 | var e:ExprGvar = expr; 107 | e.gvar.write(); 108 | } 109 | process-gvar(expr:Expr, ok:bool&) @case.process() @inline { 110 | var e:ExprGvar = expr; 111 | if !e.gvar.process() { return } 112 | ok = true; 113 | } 114 | } 115 | 116 | 117 | } 118 | -------------------------------------------------------------------------------- /Cp1/if.cp1: -------------------------------------------------------------------------------- 1 | using Cp1 { 2 | using StmtSpace { 3 | wr-if(stmt:Stmt, w:Wtr, header:bool) @case.wr() @inline { 4 | var s:StmtIf = stmt; 5 | s.expr.wr(w, header); 6 | } 7 | rd-if(space:StmtSpace, r:Rdr) @case.rd() @inline { 8 | var s:StmtIf; 9 | quick-alloc-one(s); 10 | s.expr.rd(r); 11 | space.stmt-push(s.base, .ctx-begin-row, .ctx-begin-col, .ctx-end-row, .ctx-end-col, #if); 12 | } 13 | wr-if-elif(stmt:Stmt, w:Wtr, header:bool) @case.wr() @inline { 14 | var s:StmtIfElif = stmt; 15 | s.expr.wr(w, header); 16 | } 17 | rd-if-elif(space:StmtSpace, r:Rdr) @case.rd() @inline { 18 | var s:StmtIfElif; 19 | quick-alloc-one(s); 20 | s.expr.rd(r); 21 | space.stmt-push(s.base, .ctx-begin-row, .ctx-begin-col, .ctx-end-row, .ctx-end-col, #if-elif); 22 | } 23 | wr-if-else(stmt:Stmt, w:Wtr, header:bool) @case.wr() @inline { 24 | } 25 | rd-if-else(space:StmtSpace, r:Rdr) @case.rd() @inline { 26 | var s:StmtIfElse; 27 | quick-alloc-one(s); 28 | space.stmt-push(s.base, 0, 0, 0, 0, #if-else); 29 | } 30 | wr-if-end(stmt:Stmt, w:Wtr, header:bool) @case.wr() @inline { 31 | } 32 | rd-if-end(space:StmtSpace, r:Rdr) @case.rd() @inline { 33 | var s:StmtIfEnd; 34 | quick-alloc-one(s); 35 | space.stmt-push(s.base, 0, 0, 0, 0, #if-end); 36 | } 37 | } 38 | using Stmt { 39 | write-if(stmt:Stmt) @case.write() @inline { 40 | var s:StmtIf = stmt; 41 | output{"if("} 42 | s.expr.write-value(s.val); 43 | output{") {\n"} 44 | } 45 | process-if(stmt:Stmt, ok:bool&) @case.process() @inline { 46 | var s:StmtIf = stmt; 47 | if !s.expr.value(1, false, s.val) { 48 | return; 49 | } 50 | ok = true; 51 | } 52 | write-if-elif(stmt:Stmt) @case.write() @inline { 53 | var s:StmtIfElif = stmt; 54 | output{"} else if("} 55 | s.expr.write-value(s.val); 56 | output{") {\n"} 57 | } 58 | process-if-elif(stmt:Stmt, ok:bool&) @case.process() @inline { 59 | var s:StmtIfElif = stmt; 60 | if !s.expr.value(1, false, s.val) { 61 | return; 62 | } 63 | ok = true; 64 | } 65 | write-if-else(stmt:Stmt) @case.write() @inline { 66 | var s:StmtIfElse = stmt; 67 | output{"} else {\n"} 68 | } 69 | process-if-else(stmt:Stmt, ok:bool&) @case.process() @inline { 70 | var s:StmtIfElse = stmt; 71 | ok = true; 72 | } 73 | write-if-end(stmt:Stmt) @case.write() @inline { 74 | var s:StmtIfEnd = stmt; 75 | output{"}\n"} 76 | } 77 | process-if-end(stmt:Stmt, ok:bool&) @case.process() @inline { 78 | var s:StmtIfEnd = stmt; 79 | ok = true; 80 | } 81 | } 82 | stmt-if-begin() { 83 | stmt-space-begin(); 84 | .decl-func-ctx-space.flags |= #skip-lvar-decl; 85 | } 86 | stmt-elif-begin() { 87 | } 88 | stmt-if-set(expr:ExprI, begin-row:u32, begin-col:u32, end-row:u32, end-col:u32) { 89 | var s:StmtIf; 90 | quick-alloc-one(s); 91 | s.expr = expr; 92 | stmt-push(s.base, begin-row, begin-col, end-row, end-col, #if); 93 | stmt-space-begin(); 94 | } 95 | stmt-elif-set(expr:ExprI, begin-row:u32, begin-col:u32, end-row:u32, end-col:u32) { 96 | var s:StmtIfElif; 97 | quick-alloc-one(s); 98 | s.expr = expr; 99 | stmt-push(s.base, begin-row, begin-col, end-row, end-col, #if-elif); 100 | stmt-space-begin(); 101 | } 102 | stmt-else-set() { 103 | var s:StmtIfElse; 104 | quick-alloc-one(s); 105 | stmt-push(s.base, 0, 0, 0, 0, #if-else); 106 | stmt-space-begin(); 107 | } 108 | stmt-if-end() { 109 | stmt-space-end(); 110 | } 111 | stmt-elif-end() { 112 | stmt-space-end(); 113 | } 114 | stmt-else-end() { 115 | stmt-space-end(); 116 | } 117 | stmt-if-end-ifs() { 118 | var s:StmtIfEnd; 119 | quick-alloc-one(s); 120 | stmt-push(s.base, 0, 0, 0, 0, #if-end); 121 | stmt-space-end(); 122 | } 123 | 124 | 125 | } 126 | -------------------------------------------------------------------------------- /Cp1/index.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | expr-index(left:ExprI, right-v:ExprI[], right-c:i32):ExprI { 5 | var e-idx; 6 | loop i = right-c; right-c; { 7 | var e:ExprIndex; 8 | quick-alloc-one(e); 9 | e-idx = expr-push(e.base, #index); 10 | e.left = left; 11 | e.right = right-v[i -= 1]; 12 | } 13 | return e-idx; 14 | } 15 | using ExprI { 16 | wr-index(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 17 | var e:ExprIndex = expr; 18 | e.left.wr(w, header); 19 | e.right.wr(w, header); 20 | } 21 | write-index(expr:Expr) @case.write() @inline { 22 | var e:ExprIndex = expr; 23 | e.left.write-value(e.left-val); 24 | output{''[} 25 | e.right.write-value(e.right-val); 26 | output{'']} 27 | } 28 | rd-index(e-idx:ExprI, r:Rdr) @case.rd() @inline { 29 | ExprI.rd(left!, r); 30 | ExprI.rd(right!, r); 31 | e-idx.set-index(left, right); 32 | } 33 | set-index(e-idx:this, left:ExprI, right:ExprI) { 34 | var e:ExprIndex; 35 | quick-alloc-one(e); 36 | e-idx.set(e.base, #index); 37 | e.left = left; 38 | e.right = right; 39 | } 40 | type-index(expr:Expr, at:At&) @case.type() @inline { 41 | var e:ExprIndex = expr; 42 | at = e.left.type(); 43 | } 44 | value-index(e:this, reff:i8, paren:bool, v:Value, ok:bool&) @case.value() @inline { 45 | var expr:ExprIndex = e.ptr(); 46 | v.type = expr.left-val.type; 47 | v.info.init(); 48 | v.info.copy-from(expr.left-val.info); 49 | v.info.array-c -= 1; 50 | c! = v.info.ref-v[v.info.array-c]; 51 | v.reff = (c + 2) - reff; 52 | v.info.ref-v[v.info.array-c] = reff - 1; 53 | v.info.count(); 54 | if v.reff == 1 { 55 | v.paren = false; 56 | } else { 57 | v.paren = paren; 58 | } 59 | ok = true; 60 | } 61 | process-index(expr:Expr, ok:bool&) @case.process() @inline { 62 | var e:ExprIndex = expr; 63 | if !e.left.value(1, true, e.left-val) { 64 | return; 65 | } 66 | if !e.right.value(1, true, e.right-val) { 67 | return; 68 | } 69 | ok = true; 70 | } 71 | } 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /Cp1/int.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | enum ExprInt[#i32, #u32, #f32, #oct, #hex, #u64]:u8; 5 | expr-int(value:i32, type:ExprInt):ExprI { 6 | var e:ExprIntData; 7 | quick-alloc-one(e); 8 | e-idx! = expr-push(e.base, #int); 9 | e.value.ii32 = value; 10 | e.type = type; 11 | return e-idx; 12 | } 13 | expr-int64(value:i64, type:ExprInt):ExprI { 14 | var e:ExprIntData; 15 | quick-alloc-one(e); 16 | e-idx! = expr-push(e.base, #int); 17 | e.value.uu64 = value; 18 | e.type = type; 19 | return e-idx; 20 | } 21 | expr-f32(value:f32):ExprI { 22 | var e:ExprIntData; 23 | quick-alloc-one(e); 24 | e-idx! = expr-push(e.base, #int); 25 | e.value.ff32 = value; 26 | e.type = #f32; 27 | return e-idx; 28 | } 29 | using ExprI { 30 | wr-int(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 31 | var e:ExprIntData = expr; 32 | w.n1(e.type:base); 33 | switch e.type { 34 | case #i32 { 35 | w.i(e.value.ii32); 36 | } 37 | case #f32 { 38 | var n:u32[] = &e.value.ff32; 39 | w.n4(n[0]); 40 | } 41 | case #u64 { 42 | w.N(e.value.uu64); 43 | } 44 | default { 45 | w.n(e.value.uu32); 46 | } 47 | } 48 | } 49 | rd-int(e-idx:ExprI, r:Rdr) @case.rd() @inline { 50 | var e:ExprIntData; 51 | quick-alloc-one(e); 52 | e-idx.set(e.base, #int); 53 | e.type = r.n1():ExprInt; 54 | switch e.type { 55 | case #i32 { 56 | e.value.ii32 = r.i(); 57 | } 58 | case #f32 { 59 | n! = r.n4(); 60 | var nv:f32[] = &n; 61 | e.value.ff32 = nv[0]; 62 | } 63 | case #u64 { 64 | .include-stdint = true; 65 | e.value.uu64 = r.N(); 66 | } 67 | default { 68 | e.value.uu32 = r.n(); 69 | } 70 | } 71 | } 72 | write-int(expr:Expr) @case.write() @inline { 73 | var e:ExprIntData = expr; 74 | switch e.type { 75 | case #i32 { 76 | output{e.value.ii32} 77 | } 78 | case #u32 { 79 | output{e.value.uu32 ''u} 80 | } 81 | case #f32 { 82 | output{e.value.ff32 ''f} 83 | } 84 | case #oct { 85 | output{''0 e.value.uu32, #oct} 86 | } 87 | case #hex { 88 | output{"0x" e.value.uu32, #hex} 89 | } 90 | case #u64 { 91 | "#ifdef _LP64"; 92 | output{"UINT64_C(" e.value.uu64 "u)"} 93 | "#else"; 94 | output{"UINT64_C(" e.value.uu64 "lu)"} 95 | "#endif"; 96 | } 97 | } 98 | } 99 | process-int(expr:Expr, ok:bool&) @case.process() @inline { 100 | ok = true; 101 | } 102 | type-int(expr:Expr, at:At&) @case.type() @inline { 103 | var e:ExprIntData = expr; 104 | switch e.type { 105 | case #i32 { 106 | at = basic-type(#i32); 107 | } 108 | case #f32 { 109 | at = basic-type(#f32); 110 | } 111 | case #u64 { 112 | at = basic-type(#u64); 113 | } 114 | default { 115 | at = basic-type(#u32); 116 | } 117 | } 118 | } 119 | value-int(le:this, reff:i32, paren:bool, v:Value, ok:bool&) @case.value() @inline { 120 | var e:ExprIntData = le.ptr(); 121 | switch e.type { 122 | case #i32 { 123 | v.type = basic-type(#i32); 124 | } 125 | case #f32 { 126 | v.type = basic-type(#f32); 127 | } 128 | case #u64 { 129 | v.type = basic-type(#u64); 130 | } 131 | default { 132 | v.type = basic-type(#u32); 133 | } 134 | } 135 | v.info.init(); 136 | v.info.array-c = 0; 137 | v.info.ref-v[0] = ''\0; 138 | v.info.star-c = 0; 139 | v.reff = 1; 140 | v.paren = false; 141 | ok = true; 142 | } 143 | } 144 | 145 | 146 | } 147 | -------------------------------------------------------------------------------- /Cp1/loop.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | union Nest[do:StmtLoop, reff:ref]; 5 | var nest-stack-ptr-v:Nest.[64]; 6 | var nest-stack-id-v:i32[64]; 7 | var nest-stack-c:u8; 8 | var nest-id:i32; 9 | using StmtSpace { 10 | wr-loop(stmt:Stmt, w:Wtr, header:bool) @case.wr() @inline { 11 | var s:StmtLoop = stmt; 12 | s.expr.wr(w, header); 13 | if s.continu != null { 14 | w.b(true); 15 | s.continu.wr(w, header); 16 | } else { 17 | w.b(false); 18 | } 19 | } 20 | rd-loop(space:StmtSpace, r:Rdr) @case.rd() @inline { 21 | var s:StmtLoop; 22 | quick-alloc-one(s); 23 | s.expr.rd(r); 24 | space.stmt-push(s.base, .ctx-begin-row, .ctx-begin-col, .ctx-end-row, .ctx-end-col, #loop); 25 | if r.b() { 26 | var space2:StmtSpace; 27 | quick-alloc-one(space2); 28 | s.continu = space2; 29 | space2.rd(r, space); 30 | } 31 | .nest-stack-id-v[.nest-stack-c] = .nest-id++; 32 | .nest-stack-ptr-v[.nest-stack-c].do = s; 33 | .nest-stack-c++; 34 | } 35 | wr-loop-end(stmt:Stmt, w:Wtr, header:bool) @case.wr() @inline { 36 | } 37 | rd-loop-end(space:StmtSpace, r:Rdr) @case.rd() @inline { 38 | do! = .nest-stack-ptr-v[.nest-stack-c -= 1].do; 39 | var s:StmtLoopEnd; 40 | quick-alloc-one(s); 41 | s.do = do; 42 | do.end = s; 43 | space.stmt-push(s.base, 0, 0, 0, 0, #loop-end); 44 | } 45 | } 46 | using Stmt { 47 | write-loop(stmt:Stmt) @case.write() @inline { 48 | var s:StmtLoop = stmt; 49 | .nest-stack-id-v[.nest-stack-c] = .nest-id++; 50 | .nest-stack-ptr-v[.nest-stack-c].do = s; 51 | .nest-stack-c++; 52 | if s.expr == #nil { 53 | output{"while(1) {\n"} 54 | } else { 55 | if (&&, s.val.type == basic-type(#bool), s.val.info.star-c == 0) { 56 | output{"while("} 57 | s.expr.write-value(s.val); 58 | output{") {\n"} 59 | } else { 60 | output{"for(int i = "} 61 | s.expr.write-value(s.val); 62 | output{"; i > 0; ) {\ni --;\n"} 63 | } 64 | } 65 | } 66 | process-loop(stmt:Stmt, ok:bool&) @case.process() @inline { 67 | var s:StmtLoop = stmt; 68 | if s.expr != #nil { 69 | if !s.expr.value(1, false, s.val) { 70 | return; 71 | } 72 | } 73 | ok = true; 74 | } 75 | write-loop-end(stmt:Stmt) @case.write() @inline { 76 | id! = .nest-stack-id-v[.nest-stack-c -= 1]; 77 | var s:StmtLoopEnd = stmt; 78 | output{"continue_" id ":;\n"} 79 | continu! = s.do.continu; 80 | if continu != null { 81 | continu.write(); 82 | } 83 | output{"}\nbreak_" id ":;\n"} 84 | } 85 | process-loop-end(stmt:Stmt, ok:bool&) @case.process() @inline { 86 | var s:StmtLoopEnd = stmt; 87 | continu! = s.do.continu; 88 | if continu != null { 89 | continu.process(); 90 | } 91 | ok = true; 92 | } 93 | } 94 | stmt-loop-begin() { 95 | stmt-space-begin(); 96 | .decl-func-ctx-space.flags |= #skip-lvar-decl; 97 | } 98 | struct StmtLoop[ 99 | base:Stmt., 100 | expr:ExprI, 101 | val:Value., 102 | continu:StmtSpace, 103 | end:StmtLoopEnd, 104 | ]; 105 | struct StmtLoopEnd[ 106 | base:Stmt., 107 | do:StmtLoop, 108 | ]; 109 | stmt-loop-set(expr:ExprI, begin-row:u32, begin-col:u32, end-row:u32, end-col:u32, continu:StmtSpace) { 110 | var s:StmtLoop; 111 | quick-alloc-one(s); 112 | .nest-stack-id-v[.nest-stack-c] = .nest-id++; 113 | .nest-stack-ptr-v[.nest-stack-c].do = s; 114 | .nest-stack-c++; 115 | s.expr = expr; 116 | s.continu = continu; 117 | stmt-push(s.base, begin-row, begin-col, end-row, end-col, #loop); 118 | stmt-space-begin(); 119 | } 120 | stmt-loop-end() { 121 | .nest-stack-c -= 1; 122 | stmt-space-end(); 123 | var s:StmtLoopEnd; 124 | quick-alloc-one(s); 125 | stmt-push(s.base, 0, 0, 0, 0, #loop-end); 126 | stmt-space-end(); 127 | } 128 | 129 | 130 | } 131 | -------------------------------------------------------------------------------- /Cp1/lvar.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | enum Lvar[#nil = -1, #0]:i32 { 5 | rd(l:this&, r:Rdr) @inline { 6 | l = (r.n() - 1):Lvar; 7 | } 8 | wr(l:this, w:Wtr) @inline { 9 | w.n(l:base + 1); 10 | } 11 | process(l:this):bool @inline { 12 | lvar! = l.ptr(); 13 | if (lvar.flags & #processed) != #0 { return true } 14 | lvar.flags |= #processed; 15 | at-i! = lvar.decl.type; 16 | if at-i == #nil { 17 | if lvar.decl.name == .id-blank { 18 | // let it be, it is a compile-time generated variable that wasn't used 19 | return true; 20 | } 21 | // if (lvar.flags & #set-expr) != #0 { 22 | // if !lvar.set-expr.value(1, false, v!!) { return false } 23 | // lvar.decl.type = v.type; 24 | // lvar.decl.type-info.init(); 25 | // lvar.decl.type-info.copy-from(v.info); 26 | // } else { 27 | C1.stdout{.ctx-func.file '': lvar.row '': lvar.col ": local variable '" lvar.decl.name "' doesn't have a type or a value\n"} 28 | return false; 29 | // } 30 | // return true; 31 | } 32 | return lvar.decl.process(.ctx-func.file, lvar.row, lvar.col, .ctx-func.at); 33 | } 34 | } 35 | enum LvarFlags[ 36 | #0, 37 | #set-expr = 1, 38 | #processed = 2, 39 | ]:u8 { 40 | rd(f:this&, r:Rdr) @inline { 41 | f = r.n1():LvarFlags; 42 | } 43 | wr(f:this, w:Wtr) @inline { 44 | w.n1(f:base); 45 | } 46 | } 47 | struct LvarData[ 48 | row:u32, 49 | col:u32, 50 | decl:DeclVarData., 51 | flags:LvarFlags, 52 | // set-expr:ExprI, 53 | ]; 54 | expr-lvar(name:Id, decl:u8, row:u32, col:u32):ExprI { 55 | if .decl-func-ctx-space == null { 56 | C1.stdout{.input-path '': row '': row ": Use of local variables are now allowed here\n"} 57 | C.exit(#failure); 58 | } 59 | if decl == 0 { 60 | space! = .decl-func-ctx-space; 61 | loop { 62 | v! = space.lvar-v; 63 | found! = Lvar#nil; 64 | loop i = 0; space.lvar-c; i++ { 65 | lvar! = v[i]; 66 | if lvar.name() == name { 67 | found = lvar; 68 | break; 69 | } 70 | } 71 | if found != #nil { 72 | var e:ExprLvar; 73 | quick-alloc-one(e); 74 | e-idx! = expr-push(e.base, #lvar); 75 | e.lvar = found; 76 | return e-idx; 77 | } 78 | space = space.parent; 79 | if space == null { break } 80 | } 81 | C1.stdout{.input-path '': row '': col ": local variable '" name "' was not found\n"} 82 | C.exit(#failure); 83 | return #nil; 84 | } else { 85 | space! = .decl-func-ctx-space; 86 | var e:ExprLvar; 87 | quick-alloc-one(e); 88 | e-idx! = expr-push(e.base, #lvar); 89 | e.lvar = space.lvar-new(name, row, col); 90 | lvar! = e.lvar.ptr(); 91 | .decl-var.name = name; 92 | if decl == 1 { 93 | lvar.flags |= #set-expr; 94 | e.decl = true; 95 | } 96 | lvar.decl.copy-from(.decl-var); 97 | return e-idx; 98 | } 99 | } 100 | using ExprI { 101 | write-lvar(expr:Expr) @case.write() @inline { 102 | var e:ExprLvar = expr; 103 | e.lvar.ptr().decl.write-lvar(e.lvar); 104 | } 105 | type-lvar(expr:Expr, at:At&) @case.type() @inline { 106 | var e:ExprLvar = expr; 107 | lvar! = e.lvar.ptr(); 108 | at = lvar.decl.type; 109 | } 110 | value-lvar(e:this, reff:i8, paren:bool, v:Value, ok:bool&) @case.value() @inline { 111 | var expr:ExprLvar = e.ptr(); 112 | lvar! = expr.lvar.ptr(); 113 | v.set(reff, paren, lvar.decl.type, lvar.decl.type-info); 114 | if v.reff == 1 { 115 | v.paren = false; 116 | } 117 | ok = true; 118 | } 119 | wr-lvar(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 120 | var e:ExprLvar = expr; 121 | e.lvar.wr(w); 122 | w.b(e.decl); 123 | } 124 | rd-lvar(e-idx:ExprI, r:Rdr) @case.rd() @inline { 125 | var e:ExprLvar; 126 | quick-alloc-one(e); 127 | e-idx.set(e.base, #lvar); 128 | e.lvar.rd(r); 129 | e.decl = r.b(); 130 | } 131 | process-lvar(expr:Expr, ok:bool&) @case.process() @inline { 132 | var e:ExprLvar = expr; 133 | if !e.lvar.process() { return } 134 | ok = true; 135 | } 136 | } 137 | 138 | 139 | } 140 | -------------------------------------------------------------------------------- /Cp1/meta.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using u32 { 4 | jscode(val:this, jc:Cp1.JsCode) @inline { 5 | Cp1.jscode-u32(val); 6 | } 7 | } 8 | using char { 9 | jscode(val:this, jc:Cp1.JsCode) @inline { 10 | Cp1.jscode-char(val); 11 | } 12 | jscode-arr(str:this[], jc:Cp1.JsCode) @inline { 13 | Cp1.jscode-bytes(str, C.strlen(str)); 14 | } 15 | jscode-arr(str:this[], len:u32, jc:Cp1.JsCode) @inline { 16 | Cp1.jscode-bytes(str, len); 17 | } 18 | } 19 | using Cp1 { 20 | using At { 21 | jscode-write-name(at-idx:this) { 22 | at! = at-idx.ptr(); 23 | if at.type == #basic { 24 | jscode{at.name.basic.cp1-name()} 25 | } else { 26 | at.parent.jscode-write-name-dot(); 27 | jscode{at.name.id} 28 | } 29 | } 30 | jscode-write-name-dot(at-idx:this) { 31 | if at-idx == #root { 32 | } elif at-idx == #relative { 33 | jscode{".."} 34 | } else { 35 | at! = at-idx.ptr(); 36 | at.parent.jscode-write-name-dot(); 37 | jscode{at.name.id ''.} 38 | } 39 | } 40 | jscode-write(at-idx:this) { 41 | jscode{"{\n\ttypev:["} 42 | loop at2-idx = 2:At; .at-c - 2:At; at2-idx++ { 43 | at2! = at2-idx.ptr(); 44 | if at2.parent == at-idx { 45 | if at2.type == #basic { 46 | jscode{''" at2.name.basic.cp1-name() '<",>} 47 | } else { 48 | jscode{''" at2.name.id '<",>} 49 | } 50 | } 51 | } 52 | jscode{"],\n\ttype:"} 53 | at! = at-idx.ptr(); 54 | var method-c, method-v; 55 | if at.type == #basic { 56 | t! = .basic-type[at.name.basic]; 57 | method-c = t.method-c; 58 | method-v = t.method-v; 59 | jscode{'<"basic">} 60 | } else { 61 | if at.def == #struct { 62 | t! = at.decl.structt.ptr(); 63 | method-c = t.method-c; 64 | method-v = t.method-v; 65 | jscode{'<"struct">} 66 | } elif at.def == #enum { 67 | t! = at.decl.enumm.ptr(); 68 | method-c = t.method-c; 69 | method-v = t.method-v; 70 | jscode{'<"struct">} 71 | } else { 72 | jscode{'<"">} 73 | } 74 | } 75 | jscode{",\n\tfunctionv:["} 76 | loop i = 0; at.func-c; i++ { 77 | f-idx! = at.func-v[i]; 78 | f! = f-idx.ptr(); 79 | jscode{"\n\t\t{name:\"" f.decl.name '<",argvv:[>} 80 | loop j = 0, i = 0; f.group-c; j++ { 81 | jscode{''[} 82 | loop f.group-v[j] { 83 | fa! = f.farg-v[i++]; 84 | jscode{"{name:\"" fa.decl.name "\",type:\""} 85 | fa.decl.type.jscode-write-name(); 86 | jscode{"\"},"} 87 | } 88 | jscode{"],"} 89 | } 90 | jscode{'<],type:">} 91 | if f.decl.type != #nil { 92 | f.decl.type.jscode-write-name(); 93 | } 94 | if f.this-idx == -1 { 95 | jscode{'<",this:-1},>} 96 | } else { 97 | jscode{'<",this:> f.this-idx:u32 '<},>} 98 | } 99 | } 100 | jscode{"]}"} 101 | } 102 | } 103 | var jscode-buf-data:char[]; 104 | var jscode-buf-cap:u32; 105 | var jscode-buf-len:u32; 106 | jscode-reserve(len:u32) { 107 | space! = .jscode-buf-cap - .jscode-buf-len; 108 | if space < len { 109 | .jscode-buf-cap += .jscode-buf-cap; 110 | space = .jscode-buf-cap - .jscode-buf-len; 111 | loop space < len { 112 | .jscode-buf-cap += .jscode-buf-cap; 113 | space = .jscode-buf-cap - .jscode-buf-len; 114 | } 115 | C.realloc-arr(.jscode-buf-data, .jscode-buf-cap); 116 | } 117 | } 118 | jscode-char(val:char) @inline { 119 | jscode-reserve(1); 120 | .jscode-buf-data[.jscode-buf-len++] = val; 121 | } 122 | jscode-cstr(str:char[]) @inline { 123 | jscode-bytes(str, C.strlen(str)); 124 | } 125 | jscode(jc:JsCode) @meta(jscode end) @inline { 126 | } 127 | jscode-u32(val:u32) { 128 | jscode-reserve(10); 129 | if val == 0 { 130 | .jscode-buf-data[.jscode-buf-len++] = ''0; 131 | } else { 132 | // integer to string, count the digits 133 | var data:char[]; 134 | data = &.jscode-buf-data[.jscode-buf-len]; 135 | digits! = 0; 136 | loop { 137 | data[digits++] = (val % 10) + ''0; 138 | val /= 10; 139 | if val == 0 { break } 140 | } 141 | // reverse the string 142 | start! = 0; 143 | end! = digits - 1; 144 | loop start < end { 145 | tmp! = data[start]; 146 | data[start] = data[end]; 147 | data[end] = tmp; 148 | start++; 149 | end--; 150 | } 151 | .jscode-buf-len += digits; 152 | } 153 | } 154 | struct JsCode[] { 155 | jscode-cstr(jc:this, str:char[], len:u32) @inline { 156 | jscode-bytes(str, len); 157 | } 158 | jscode-end(jc:this) @inline { 159 | } 160 | } 161 | jscode-bytes(data:ref, size:usz) @inline { 162 | jscode-reserve(size); 163 | C.memcpy(&.jscode-buf-data[.jscode-buf-len], data, size); 164 | .jscode-buf-len += size; 165 | } 166 | include-add(include-len:u8, include-str:char[]):Include { 167 | found! = .include-map.get-or-insert(include-str, include-len, .include-c); 168 | // C1.stdout{"include-add " include-str " = " found ''\n} 169 | if found == -1 { 170 | include-idx! = .include-c++; 171 | if .include-cap <= .include-c { 172 | old-cap! = .include-cap; 173 | grow(.include-cap, .include-c); 174 | realloc(.include-len-v, .include-cap, old-cap); 175 | realloc(.include-str-v, .include-cap, old-cap); 176 | } 177 | .include-len-v[include-idx] = include-len; 178 | .include-str-v[include-idx] = include-str; 179 | // C1.stdout{"include " include-str " is " include-idx ''\n} 180 | return include-idx:Include; 181 | } else { 182 | // C1.stdout{"include " include-str " is " found ''\n} 183 | return found:Include; 184 | } 185 | } 186 | var template-inst-new-c:TemplateInst; 187 | template-inst(ti:TemplateInstData) { 188 | loop j = 0; .template-inst-c { 189 | ti2! = .template-inst-v[j++]; 190 | if (ti2.name == ti.name) && (ti2.at == ti.at) && (ti2.arg-crc32c == ti.arg-crc32c) { 191 | return; 192 | } 193 | } 194 | if true { 195 | i! = .template-inst-c++; 196 | if .template-inst-cap < .template-inst-c { 197 | .template-inst-cap = grow(.template-inst-c:base):TemplateInst; 198 | C.realloc-arr(.template-inst-v, .template-inst-cap:base); 199 | } 200 | C.memcpy(.template-inst-v[i], ti, TemplateInstData[usz]); 201 | } 202 | if true { 203 | .template-inst-new-c++; 204 | } 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /Cp1/null.cp1: -------------------------------------------------------------------------------- 1 | using Cp1 { 2 | expr-null():ExprI { 3 | var e:ExprNull; 4 | quick-alloc-one(e); 5 | e-idx! = expr-push(e.base, #null); 6 | return e-idx; 7 | } 8 | using ExprI { 9 | wr-null(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 10 | var e:ExprNull = expr; 11 | } 12 | rd-null(e-idx:ExprI, r:Rdr) @case.rd() @inline { 13 | var e:ExprNull; 14 | quick-alloc-one(e); 15 | e-idx.set(e.base, #null); 16 | } 17 | write-null(expr:Expr) @case.write() @inline { 18 | var e:ExprNull = expr; 19 | output{"NULL"} 20 | } 21 | process-null(expr:Expr, ok:bool&) @case.process() @inline { 22 | .include-stddef = true; 23 | ok = true; 24 | } 25 | type-null(expr:Expr, at:At&) @case.type() @inline { 26 | at = basic-type(#ref); 27 | } 28 | value-null(le:this, reff:i32, paren:bool, v:Value, ok:bool&) @case.value() @inline { 29 | v.type = basic-type(#ref); 30 | v.info.init(); 31 | v.info.array-c = 0; 32 | v.info.ref-v[0] = ''\0; 33 | v.info.star-c = 0; 34 | v.reff = 1; 35 | v.paren = false; 36 | ok = true; 37 | } 38 | } 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Cp1/rdr.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | union Rdr[ 5 | reff:ref, 6 | pos:usz, 7 | p1:u8[], 8 | charr:char[], 9 | p4:u32[], 10 | ] { 11 | n1(r:this):u8 @inline { 12 | val! = r.p1[0]; 13 | r.pos++; 14 | return val; 15 | } 16 | n2(r:this):u32 @inline { 17 | val! = r.p1[0]:u32; 18 | val |= r.p1[1]:u32 << 8; 19 | r.pos += 2; 20 | return val; 21 | } 22 | n4(r:this):u32 @inline { 23 | val! = r.p1[0]:u32; 24 | val |= r.p1[1]:u32 << 8; 25 | val |= r.p1[2]:u32 << 16; 26 | val |= r.p1[3]:u32 << 24; 27 | r.pos += 4; 28 | return val; 29 | } 30 | id(r:this):Id @inline { 31 | return r.n(); 32 | } 33 | include "num.c" { 34 | n(r:this):u32 @real-name(Fgetnum) @no-decl; 35 | i(r:this):i32 @real-name(Fgetint) @no-decl; 36 | N(r:this):u32 @real-name(Fgetlnum) @no-decl; 37 | I(r:this):i32 @real-name(Fgetlint) @no-decl; 38 | } 39 | tok(r:this):Token @inline { 40 | return r.n1(); 41 | } 42 | copy(r:this, data:ref, size:i32) @inline { 43 | C.memcpy(data, r.reff, size); 44 | r.pos += size; 45 | } 46 | b(r:this):bool @inline { 47 | return r.n1() != 0; 48 | } 49 | set(r:this, reff:ref) @inline { 50 | r.reff = reff; 51 | } 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /Cp1/ref.cp1: -------------------------------------------------------------------------------- 1 | using Cp1 { 2 | expr-ref(expr:ExprI):ExprI { 3 | var e:ExprRef; 4 | quick-alloc-one(e); 5 | e-idx! = expr-push(e.base, #ref); 6 | e.expr = expr; 7 | return e-idx; 8 | } 9 | using ExprI { 10 | wr-ref(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 11 | var e:ExprRef = expr; 12 | e.expr.wr(w, header); 13 | } 14 | rd-ref(e-idx:ExprI, r:Rdr) @case.rd() @inline { 15 | var e:ExprRef; 16 | quick-alloc-one(e); 17 | e-idx.set(e.base, #ref); 18 | e.expr.rd(r); 19 | } 20 | write-ref(expr:Expr) @case.write() @inline { 21 | var e:ExprRef = expr; 22 | e.expr.write-value(e.val); 23 | } 24 | value-ref(e:this, reff:i8, paren:bool, v:Value, ok:bool&) @case.value() @inline { 25 | var expr:ExprRef = e.ptr(); 26 | v.type = basic-type(#ref); 27 | v.info.init(); 28 | v.info.array-c = 0; 29 | v.info.ref-v[0] = 1; 30 | v.info.star-c = 1; 31 | v.reff = 1; 32 | ok = true; 33 | } 34 | type-ref(expr:Expr, at:At&) @case.type() @inline { 35 | at = basic-type(#ref); 36 | } 37 | process-ref(expr:Expr, ok:bool&) @case.process() @inline { 38 | var e:ExprRef = expr; 39 | if !e.expr.value(2, false, e.val) { 40 | return; 41 | } 42 | ok = true; 43 | } 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /Cp1/return.cp1: -------------------------------------------------------------------------------- 1 | using Cp1 { 2 | stmt-return(e:ExprI, begin-row:u32, begin-col:u32, end-row:u32, end-col:u32) { 3 | var s:StmtReturn; 4 | quick-alloc-one(s); 5 | stmt-push(s.base, begin-row, begin-col, end-row, end-col, #return); 6 | s.expr = e; 7 | } 8 | using StmtSpace { 9 | wr-return(stmt:Stmt, w:Wtr, header:bool) @case.wr() @inline { 10 | var s:StmtReturn = stmt; 11 | s.expr.wr(w, header); 12 | } 13 | rd-return(space:StmtSpace, r:Rdr) @case.rd() @inline { 14 | var s:StmtReturn; 15 | quick-alloc-one(s); 16 | s.expr.rd(r); 17 | space.stmt-push(s.base, .ctx-begin-row, .ctx-begin-col, .ctx-end-row, .ctx-end-col, #return); 18 | } 19 | } 20 | using Stmt { 21 | write-return(stmt:Stmt) @case.write() @inline { 22 | var s:StmtReturn = stmt; 23 | if s.expr == #nil { 24 | output{"return;\n"} 25 | } else { 26 | output{"return "} 27 | s.expr.write-value(s.val); 28 | output{";\n"} 29 | } 30 | } 31 | process-return(stmt:Stmt, ok:bool&) @case.process() @inline { 32 | var s:StmtReturn = stmt; 33 | if s.expr != #nil { 34 | s.expr.try-deduce(.ctx-func.decl.type); 35 | if !s.expr.value(1 + .ctx-func.decl.type-info.ref-v[.ctx-func.decl.type-info.array-c], false, s.val) { 36 | return; 37 | } 38 | } 39 | ok = true; 40 | } 41 | } 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Cp1/size.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | expr-size-of-type(at:At):ExprI { 5 | var e:ExprSizeOfType; 6 | quick-alloc-one(e); 7 | e-idx! = expr-push(e.base, #size-of-type); 8 | e.type = at; 9 | return e-idx; 10 | } 11 | using ExprI { 12 | wr-size-of-type(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 13 | var e:ExprSizeOfType = expr; 14 | e.type.wr(w, header); 15 | } 16 | rd-size-of-type(e-idx:ExprI, r:Rdr) @case.rd() @inline { 17 | var e:ExprSizeOfType; 18 | quick-alloc-one(e); 19 | e-idx.set(e.base, #size-of-type); 20 | e.type.rd(r); 21 | } 22 | write-size-of-type(expr:Expr) @case.write() @inline { 23 | var e:ExprSizeOfType = expr; 24 | output{"sizeof("} 25 | e.type.write(); 26 | output{'')} 27 | } 28 | process-size-of-type(expr:Expr, ok:bool&) @case.process() @inline { 29 | var e:ExprSizeOfType = expr; 30 | e.type = at-validate(e.type, .ctx-func.at, .ctx-func.file, .ctx-begin-row, .ctx-begin-col); 31 | if e.type == #nil { 32 | return; 33 | } 34 | at! = e.type.ptr(); 35 | if (&&, at.type != #basic, at.decl.structt == #nil) { 36 | C1.stdout{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col ": Error, the type '" at.name.id "' used in [usz] was not defined\n"} 37 | return; 38 | } 39 | e.type.output(.ctx-func.file, .ctx-begin-row, .ctx-begin-col); 40 | ok = true; 41 | } 42 | type-size-of-type(expr:Expr, at:At&) @case.type() @inline { 43 | at = basic-type(#usz); 44 | } 45 | value-size-of-type(le:this, reff:i32, paren:bool, v:Value, ok:bool&) @case.value() @inline { 46 | v.type = basic-type(#usz); 47 | v.info.init(); 48 | v.info.array-c = 0; 49 | v.info.ref-v[0] = ''\0; 50 | v.info.star-c = 0; 51 | v.reff = 1; 52 | v.paren = false; 53 | ok = true; 54 | } 55 | } 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Cp1/soa.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | expr-soa-field(expr:ExprI, group:Id, field:Id, row:u32, col:u32):ExprI { 5 | if .decl-func-ctx-space == null { 6 | C1.stdout{.input-path '': row '': row ": Use of SOA member variables are now allowed here\n"} 7 | C.exit(#failure); 8 | } 9 | var e:ExprSoaField; 10 | quick-alloc-one(e); 11 | e-idx! = expr-push(e.base, #soa-field); 12 | e.expr = expr; 13 | e.group = group; 14 | e.field = field; 15 | return e-idx; 16 | } 17 | using ExprI { 18 | wr-soa-field(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 19 | var e:ExprSoaField = expr; 20 | e.expr.wr(w, header); 21 | e.group.wr(w, header); 22 | e.field.wr(w, header); 23 | } 24 | rd-soa-field(e-idx:ExprI, r:Rdr) @case.rd() @inline { 25 | var e:ExprSoaField; 26 | quick-alloc-one(e); 27 | e-idx.set(e.base, #soa-field); 28 | e.expr.rd(r); 29 | e.group.rd(r); 30 | e.field.rd(r); 31 | } 32 | type-soa-field(expr:Expr, at:At&) @case.type() @inline { 33 | var e:ExprSoaField = expr; 34 | type-index(e.expr2.ptr(), at); 35 | } 36 | value-soa-field(expr:this, reff:i8, paren:bool, v:Value, ok:bool&) @case.value() @inline { 37 | var e:ExprSoaField = expr.ptr(); 38 | value-index(e.expr2, reff, paren, v, ok); 39 | } 40 | write-soa-field(expr:Expr) @case.write() @inline { 41 | var e:ExprSoaField = expr; 42 | write-index(e.expr2.ptr()); 43 | } 44 | process-soa-field(expr:Expr, ok:bool&) @case.process() @inline { 45 | var e:ExprSoaField = expr; 46 | type-i! = e.expr.type(); 47 | if type-i == #nil { 48 | C1.stdout{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col " - " .ctx-end-row '': .ctx-end-col ": Cannot get structure-of-array field member ." e.field.str() " from an expression of unknown type\n"} 49 | return; 50 | } 51 | type! = type-i.ptr(); 52 | if type.def != #enum { 53 | C1.stdout{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col " - " .ctx-end-row '': .ctx-end-col ": Cannot get structure-of-array field member ." e.field.str() " because its type is not an enum\n"} 54 | return; 55 | } 56 | enumm! = type.decl.enumm; 57 | enumd! = enumm.ptr(); 58 | if (enumd.flags & #soa-field) != #0 { 59 | gvar-e-idx! = ExprI.alloc(); 60 | gvar-e-idx.set-gvar(enumd.soa-field-gvar-at, enumd.soa-field-gvar-id); 61 | fvar-e-idx! = ExprI.alloc(); 62 | fvar-e-idx.set-fvar(gvar-e-idx, e.field); 63 | index-e-idx! = ExprI.alloc(); 64 | index-e-idx.set-index(fvar-e-idx, e.expr); 65 | process-index(index-e-idx.ptr(), ok); 66 | e.expr2 = index-e-idx; 67 | } else { 68 | C1.stdout{.ctx-func.file '': .ctx-begin-row '': .ctx-begin-col " - " .ctx-end-row '': .ctx-end-col ": Cannot get structure-of-array field member ." e.field.str() " because the enum has no @soa-field attribute\n"} 69 | return; 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Cp1/stmt.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | enum StmtType[ 5 | #space, #if, #if-elif, #if-else, #if-end, 6 | #loop, #loop-end, #while, #while-end, 7 | #expr, #return, #continue, #break, 8 | #switch, #case, #default, #case-end, #default-end, #switch-end, 9 | #nil = 255, 10 | ]:u8 { 11 | wr(s:this, w:Wtr) @inline { 12 | w.n1(s:base); 13 | } 14 | rd(s:this&, r:Rdr) @inline { 15 | s = r.n1():StmtType; 16 | } 17 | cp1-name(e:this):char[] @cp1-name; 18 | } 19 | struct Stmt[ 20 | begin-row:u32, 21 | begin-col:u32, 22 | end-row:u32, 23 | end-col:u32, 24 | type:StmtType, 25 | stmt-next:Stmt, 26 | ] { 27 | write(s:this) { 28 | // C1.stdout{ 29 | // '= printf("%s %d\n", __FILE__, __LINE__); 30 | // } 31 | switch.write(s) s.type { 32 | default { 33 | C1.stdout{"write() not yet implemented in stmt #" s.type.cp1-name() ''\n} 34 | C.exit(#failure); 35 | } 36 | } 37 | } 38 | process(s:this):bool { 39 | ok! = false; 40 | .ctx-begin-row = s.begin-row; 41 | .ctx-begin-col = s.begin-col; 42 | .ctx-end-row = s.end-row; 43 | .ctx-end-col = s.end-col; 44 | switch.process(s, ok) s.type { 45 | default { 46 | C1.stdout{.ctx-func.file '': s.begin-row '': s.begin-col " - " s.end-row '': s.end-col ": process() is not implemented in statement #" s.type.cp1-name() ''\n} 47 | } 48 | } 49 | if !ok { 50 | C1.stdout{.ctx-func.file '': s.begin-row '': s.begin-col " - " s.end-row '': s.end-col ": Processing of statement #" s.type.cp1-name() " failed\n"} 51 | } 52 | return ok; 53 | } 54 | } 55 | struct StmtExpr[ 56 | base:Stmt., 57 | expr:ExprI, 58 | ]; 59 | struct StmtReturn[ 60 | base:Stmt., 61 | expr:ExprI, 62 | val:Value., 63 | ]; 64 | stmt-push(s:Stmt, begin-row:u32, begin-col:u32, end-row:u32, end-col:u32, type:StmtType) { 65 | s.begin-row = begin-row; 66 | s.begin-col = begin-col; 67 | s.end-row = end-row; 68 | s.end-col = end-col; 69 | s.type = type; 70 | func-stmt-add(s); 71 | } 72 | func-stmt-add(s:Stmt) { 73 | s.stmt-next = null; 74 | if .decl-func-ctx-space.stmt-last == null { 75 | .decl-func-ctx-space.stmt-first = s; 76 | .decl-func-ctx-space.stmt-last = s; 77 | } else { 78 | .decl-func-ctx-space.stmt-last.stmt-next = s; 79 | .decl-func-ctx-space.stmt-last = s; 80 | } 81 | } 82 | expr2stmt(e-idx:ExprI, begin-row:u32, begin-col:u32, end-row:u32, end-col:u32) { 83 | var s:StmtExpr; 84 | quick-alloc-one(s); 85 | stmt-push(s.base, begin-row, begin-col, end-row, end-col, #expr); 86 | s.expr = e-idx; 87 | e! = e-idx.ptr(); 88 | if e.type == #assign { 89 | var assign:ExprAssign = e; 90 | assign.is-stmt = true; 91 | } 92 | } 93 | stmt-lvar-add(name:Id, set:ExprI, row:u32, col:u32) { 94 | lvar-i! = .decl-func-ctx-space.lvar-new(name, row, col); 95 | lvar! = lvar-i.ptr(); 96 | .decl-var.name = name; 97 | lvar.decl.copy-from(.decl-var); 98 | if set == -2:ExprI { 99 | lvar.flags |= #set-expr; 100 | } elif set != #nil { 101 | e2! = expr-lvar(name, 0, row, col); 102 | var expr2:ExprLvar = e2.ptr(); 103 | expr2.decl = true; 104 | e! = expr-assign(e2, set, #eq); 105 | expr2stmt(e, row, col, row, col); 106 | } 107 | } 108 | stmt-lvar-end(end-row:u32, end-col:u32) { 109 | } 110 | 111 | 112 | } 113 | -------------------------------------------------------------------------------- /Cp1/str.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | enum Str[#nil = -1, #0]:i32; 5 | var str-c:i32; 6 | var str-cap:i32; 7 | var str-ptr:ref[]; 8 | var str-len:i32[]; 9 | var string-buf:char[] @extern; 10 | var string-len:i32 @extern; 11 | expr-str(prev:ExprI):ExprI { 12 | len! = .string-len; 13 | var n:ExprStrNode; 14 | quick-alloc-plus(n, len + 1); 15 | n.len = len; 16 | C.memcpy(n.buf, .string-buf, len); 17 | n.buf[len] = ''\0; 18 | n.next = null; 19 | if prev == #nil { 20 | var e:ExprStr; 21 | quick-alloc-one(e); 22 | e-idx! = expr-push(e.base, #str); 23 | e.node-c = 1; 24 | e.first = n; 25 | e.last = n; 26 | return e-idx; 27 | } else { 28 | var e:ExprStr = prev.ptr(); 29 | e.node-c++; 30 | e.last.next = n; 31 | e.last = n; 32 | return prev; 33 | } 34 | } 35 | write-str-node(len:i32, ptr:ref); 36 | using ExprI { 37 | wr-str(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 38 | var e:ExprStr = expr; 39 | w.n(e.node-c); 40 | n! = e.first; 41 | loop { 42 | w.n(n.len); 43 | w.copy(n.buf, n.len); 44 | n = n.next; 45 | if n == null { break } 46 | } 47 | } 48 | rd-str(e-idx:ExprI, r:Rdr) @case.rd() @inline { 49 | node-c! = r.n(); 50 | var e:ExprStr; 51 | quick-alloc-one(e); 52 | e-idx.set(e.base, #str); 53 | first! = true; 54 | loop node-c { 55 | len! = r.n(); 56 | var n:ExprStrNode; 57 | quick-alloc-plus(n, len + 1); 58 | n.len = len; 59 | r.copy(n.buf, len); 60 | n.buf[len] = 0; 61 | n.next = null; 62 | if first { 63 | first = false; 64 | e.first = n; 65 | e.last = n; 66 | } else { 67 | e.last.next = n; 68 | e.last = n; 69 | } 70 | } 71 | } 72 | write-str(expr:Expr) @case.write() @inline { 73 | var e:ExprStr = expr; 74 | n! = e.first; 75 | loop { 76 | output-reserve(n.len << 1); 77 | n = n.next; 78 | if n == null { break } 79 | } 80 | n = e.first; 81 | loop { 82 | write-str-node(n.len, n.buf); 83 | n = n.next; 84 | if n == null { break } 85 | output{''\n} 86 | } 87 | } 88 | value-str(s:this, reff:i32, paren:bool, v:Value, ok:bool&) @case.value() @inline { 89 | v.type = basic-type(#char); 90 | v.info.init(); 91 | v.info.const = true; 92 | v.info.array-c = 1; 93 | v.info.ref-v[0] = ''\0; 94 | v.info.ref-v[1] = ''\0; 95 | v.info.star-c = 1; 96 | v.reff = 1; 97 | ok = true; 98 | } 99 | process-str(expr:Expr, ok:bool&) @case.process() @inline { 100 | ok = true; 101 | } 102 | } 103 | 104 | 105 | } 106 | -------------------------------------------------------------------------------- /Cp1/struct.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | enum Struct[#nil = -1, #0, #1]:i32 { 5 | wr(s:this, w:Wtr) @inline { 6 | w.n(s + #1); 7 | } 8 | rd(s:this&, r:Rdr) @inline { 9 | s = (r.n() - #1):Func; 10 | } 11 | ptr(s:this):StructData @inline { 12 | return .struct-v[s]; 13 | } 14 | output(s-i:this) { 15 | num! = s-i:u32; 16 | n3! = num >> 3; 17 | n17! = 1 << (num & 7); 18 | if (.struct-is-outputted[n3] & n17) != 0 { return } 19 | .struct-is-outputted[n3] |= n17; 20 | s! = s-i.ptr(); 21 | s-at! = s.at; 22 | s-file! = s.file; 23 | s-row! = s.begin-row; 24 | s-col! = s.begin-col; 25 | loop i = 0; s.fvar-c; i++ { 26 | // s.fvar-v[i].decl.type.output(s.file, row, col); 27 | // if !s.fvar-v[i].decl.type.finalize(s.fvar-v[i].decl.type-info, row, col) { return } 28 | s.fvar-v[i].decl.type = at-validate(s.fvar-v[i].decl.type, s-at, s-file, s-row, s-col); 29 | if !s.fvar-v[i].decl.process(s-file, s-row, s-col, s-at) { 30 | C.exit(#failure); 31 | return; 32 | } 33 | } 34 | 35 | if s.include != #nil { 36 | s.include.output(); 37 | } 38 | 39 | if (s.flags & #no-decl) == #0 { 40 | .struct-outputted-v[.struct-outputted-c++] = s-i; 41 | } 42 | } 43 | } 44 | struct FvarData[ 45 | decl:DeclVarData., 46 | ] { 47 | rd(f:this, r:Rdr) { 48 | f.decl.rd(r); 49 | } 50 | wr(f:this, w:Wtr, header:bool) { 51 | f.decl.wr(w, header); 52 | } 53 | } 54 | var struct-c:Struct; 55 | var struct-cap:Struct; 56 | var struct-v:StructData[]; 57 | var decl-struct-row:u32; 58 | var decl-struct-col:u32; 59 | var decl-struct-at:At; 60 | var decl-struct-real-name:Id; 61 | var decl-struct-aligned:u32; 62 | enum StructFlags[ 63 | #0, 64 | #real-name = 1, 65 | #no-decl = 2, 66 | #union = 4, 67 | #aligned = 8, 68 | ]:u8 { 69 | wr(f:this, w:Wtr) @inline { 70 | w.n1(f:base); 71 | } 72 | rd(f:this&, r:Rdr) @inline { 73 | f = r.n1():StructFlags; 74 | } 75 | } 76 | var decl-struct-flags:StructFlags; 77 | var decl-fvar-c:u32; 78 | var decl-fvar-cap:u32; 79 | var decl-fvar-v:DeclVarData.[]; 80 | decl-var-as-fvar() { 81 | fvar! = .decl-fvar-c++; 82 | if .decl-fvar-cap <= .decl-fvar-c { 83 | old-cap! = .decl-fvar-cap; 84 | grow(.decl-fvar-cap, .decl-fvar-c); 85 | realloc(.decl-fvar-v, .decl-fvar-cap, old-cap); 86 | } 87 | .decl-fvar-v[fvar].copy-from(.decl-var); 88 | } 89 | decl-at-begin-struct(name:Id, row:u32, col:u32) { 90 | .decl-struct-row = row; 91 | .decl-struct-col = col; 92 | .build-at = .decl-at; 93 | old-at-c! = .at-c; 94 | decl-at-add(name, #struct-enum, row, col); 95 | .decl-at-v[.decl-at-c++] = .decl-at; 96 | .decl-at = .build-at; 97 | .decl-struct-at = .build-at; 98 | .decl-fvar-c = 0; 99 | .decl-struct-real-name = #nil; 100 | .decl-struct-flags = #0; 101 | } 102 | decl-struct-end(row:u32, col:u32) { 103 | s-idx! = .struct-c++; 104 | if .struct-cap <= .struct-c { 105 | old-cap! = .struct-cap; 106 | .struct-cap = grow(.struct-c:base):Struct; 107 | realloc(.struct-v, .struct-cap:base, old-cap:base); 108 | } 109 | var s:StructData; 110 | quick-alloc-plus(s, FvarData[usz] * .decl-fvar-c); 111 | .struct-v[s-idx] = s; 112 | s.begin-row = .decl-struct-row; 113 | s.begin-col = .decl-struct-col; 114 | s.end-row = row; 115 | s.end-col = col; 116 | s.include = .decl-include; 117 | s.at = .decl-struct-at; 118 | s.flags = .decl-struct-flags; 119 | // s.name = .decl-struct-name; 120 | s.fvar-c = .decl-fvar-c; 121 | loop i = 0; .decl-fvar-c; i++ { 122 | a! = s.fvar-v[i]; 123 | a.decl.copy-from(.decl-fvar-v[i]); 124 | } 125 | s.real-name = .decl-struct-real-name; 126 | s.aligned = .decl-struct-aligned; 127 | } 128 | struct-attr-real-name(name:Id) { 129 | if (.decl-struct-flags & #real-name) != #0 { 130 | C1.stdout{.input-path '': .last-row '': .last-col ": error @real-name specified more than once\n"} 131 | C.exit(#failure); 132 | } 133 | .decl-struct-flags |= #real-name; 134 | .decl-struct-real-name = name; 135 | } 136 | struct-attr-aligned(aligned:u32) { 137 | if (.decl-struct-flags & #aligned) != #0 { 138 | C1.stdout{.input-path '': .last-row '': .last-col ": error @aligned specified more than once\n"} 139 | C.exit(#failure); 140 | } 141 | .decl-struct-flags |= #aligned; 142 | .decl-struct-aligned = aligned; 143 | } 144 | struct-attr-no-decl() { 145 | if (.decl-struct-flags & #no-decl) != #0 { 146 | C1.stdout{.input-path '': .last-row '': .last-col ": error @no-decl specified more than once\n"} 147 | C.exit(#failure); 148 | } 149 | .decl-struct-flags |= #no-decl; 150 | } 151 | struct-attr-union() { 152 | .decl-struct-flags |= #union; 153 | } 154 | 155 | 156 | } 157 | -------------------------------------------------------------------------------- /Cp1/unary.cp1: -------------------------------------------------------------------------------- 1 | using Cp1 { 2 | enum Unary[#neg, #inc, #dec, #not]:u8 { 3 | rd(u:this&, r:Rdr) @inline { 4 | u = r.n1():Unary; 5 | } 6 | wr(u:this, w:Wtr) @inline { 7 | w.n1(u:base); 8 | } 9 | } 10 | expr-unary(expr:ExprI, type:Unary):ExprI { 11 | var e:ExprUnary; 12 | quick-alloc-one(e); 13 | e-idx! = expr-push(e.base, #unary); 14 | e.expr = expr; 15 | e.type = type; 16 | return e-idx; 17 | } 18 | using ExprI { 19 | wr-unary(expr:Expr, w:Wtr, header:bool) @case.wr() @inline { 20 | var e:ExprUnary = expr; 21 | e.expr.wr(w, header); 22 | e.type.wr(w); 23 | } 24 | rd-unary(e-idx:ExprI, r:Rdr) @case.rd() @inline { 25 | var e:ExprUnary; 26 | quick-alloc-one(e); 27 | e-idx.set(e.base, #unary); 28 | e.expr.rd(r); 29 | e.type.rd(r); 30 | } 31 | write-unary(expr:Expr) @case.write() @inline { 32 | var e:ExprUnary = expr; 33 | switch e.type { 34 | case #neg { 35 | output{''-} 36 | e.expr.write-value(e.val); 37 | } 38 | case #inc { 39 | e.expr.write-value(e.val); 40 | output{"++"} 41 | } 42 | case #dec { 43 | e.expr.write-value(e.val); 44 | output{"--"} 45 | } 46 | case #not { 47 | output{''!} 48 | e.expr.write-value(e.val); 49 | } 50 | } 51 | } 52 | value-unary(e:this, reff:i8, paren:bool, v:Value, ok:bool&) @case.value() @inline { 53 | var expr:ExprUnary = e.ptr(); 54 | v.type = expr.expr.type(); 55 | v.info.init(); 56 | v.info.array-c = 0; 57 | v.info.ref-v[0] = 0; 58 | v.info.star-c = 0; 59 | v.reff = 1; 60 | ok = true; 61 | } 62 | type-unary(expr:Expr, at:At&) @case.type() @inline { 63 | var e:ExprUnary = expr; 64 | at = e.expr.type(); 65 | } 66 | process-unary(expr:Expr, ok:bool&) @case.process() @inline { 67 | var e:ExprUnary = expr; 68 | if !e.expr.value(1, true, e.val) { 69 | return; 70 | } 71 | ok = true; 72 | } 73 | } 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /Cp1/wtr.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using C1 = LibCp1; 3 | using Cp1 { 4 | union Wtr[ 5 | reff:ref, 6 | pos:usz, 7 | p1:u8[], 8 | p4:u32[], 9 | ] { 10 | n1(w:this, n:u8) @inline { 11 | w.p1[0] = n; 12 | w.pos++; 13 | } 14 | n2(w:this, n:u32) @inline { 15 | w.p1[0] = n; 16 | w.p1[1] = n >> 8; 17 | w.pos += 2; 18 | } 19 | n4(w:this, n:u32) @inline { 20 | w.p1[0] = n; 21 | w.p1[1] = n >> 8; 22 | w.p1[2] = n >> 16; 23 | w.p1[3] = n >> 24; 24 | w.pos += 4; 25 | } 26 | include "num.c" { 27 | n(w:this, n:u32) @real-name(Fputnum) @no-decl; 28 | i(w:this, n:i32) @real-name(Fputint) @no-decl; 29 | N(w:this, n:u64) @real-name(Fputlnum) @no-decl; 30 | I(w:this, n:i64) @real-name(Fputlint) @no-decl; 31 | } 32 | copy(w:this, data:ref, size:i32) @inline { 33 | C.memcpy(w.reff, data, size); 34 | w.pos += size; 35 | } 36 | b(w:this, val:bool) @inline { 37 | if val { w.n1(1) } 38 | else { w.n1(0) } 39 | } 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Galileo Lajara 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile-clang: -------------------------------------------------------------------------------- 1 | all: bin/cp1-parse bin/cp1-compile bin/cp1-run bin/cp1-qjs 2 | 3 | out: 4 | mkdir $@ 5 | 6 | bin: 7 | mkdir $@ 8 | 9 | out/parse.cp1.c.o: parse.cp1.c | out 10 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 11 | 12 | out/parse.c.o: parse.c 13 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 14 | 15 | out/compile.cp1.c.o: compile.cp1.c | out 16 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 17 | 18 | out/compile.c.o: compile.c 19 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 20 | 21 | out/hashtable.c.o: hashtable.c 22 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 23 | 24 | out/cp1-qjs.c.o: cp1-qjs.c 25 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 26 | 27 | out/quickjs.c.o: qjs/quickjs.c 28 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 29 | 30 | out/quickjs-libc.c.o: qjs/quickjs-libc.c 31 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 32 | 33 | out/cutils.c.o: qjs/cutils.c 34 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 35 | 36 | out/libregexp.c.o: qjs/libregexp.c 37 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 38 | 39 | out/libbf.c.o: qjs/libbf.c 40 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 41 | 42 | out/libunicode.c.o: qjs/libunicode.c 43 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 44 | 45 | bin/cp1-parse: out/parse.cp1.c.o out/parse.c.o out/hashtable.c.o | bin 46 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ 47 | 48 | bin/cp1-compile: out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o | bin 49 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ 50 | 51 | bin/cp1-run: run.cp1.c | bin 52 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ 53 | 54 | bin/cp1-qjs: out/cp1-qjs.c.o out/quickjs.c.o out/quickjs-libc.c.o out/cutils.c.o out/libregexp.c.o out/libbf.c.o out/libunicode.c.o | bin 55 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ -lm 56 | -------------------------------------------------------------------------------- /Makefile-gcc: -------------------------------------------------------------------------------- 1 | all: bin/cp1-parse bin/cp1-compile bin/cp1-run bin/cp1-qjs 2 | 3 | out: 4 | mkdir $@ 5 | 6 | bin: 7 | mkdir $@ 8 | 9 | out/parse.cp1.c.o: parse.cp1.c | out 10 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 11 | 12 | out/parse.c.o: parse.c 13 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 14 | 15 | out/compile.cp1.c.o: compile.cp1.c | out 16 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 17 | 18 | out/compile.c.o: compile.c 19 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 20 | 21 | out/hashtable.c.o: hashtable.c 22 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 23 | 24 | out/cp1-qjs.c.o: cp1-qjs.c 25 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 26 | 27 | out/quickjs.c.o: qjs/quickjs.c 28 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 29 | 30 | out/quickjs-libc.c.o: qjs/quickjs-libc.c 31 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 32 | 33 | out/cutils.c.o: qjs/cutils.c 34 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 35 | 36 | out/libregexp.c.o: qjs/libregexp.c 37 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 38 | 39 | out/libbf.c.o: qjs/libbf.c 40 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 41 | 42 | out/libunicode.c.o: qjs/libunicode.c 43 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 44 | 45 | bin/cp1-parse: out/parse.cp1.c.o out/parse.c.o out/hashtable.c.o | bin 46 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ 47 | 48 | bin/cp1-compile: out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o | bin 49 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ 50 | 51 | bin/cp1-run: run.cp1.c | bin 52 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ 53 | 54 | bin/cp1-qjs: out/cp1-qjs.c.o out/quickjs.c.o out/quickjs-libc.c.o out/cutils.c.o out/libregexp.c.o out/libbf.c.o out/libunicode.c.o | bin 55 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ -lm 56 | -------------------------------------------------------------------------------- /Makefile-tcc: -------------------------------------------------------------------------------- 1 | all: bin/cp1-parse bin/cp1-compile bin/cp1-run bin/cp1-qjs 2 | 3 | out: 4 | mkdir $@ 5 | 6 | bin: 7 | mkdir $@ 8 | 9 | out/parse.cp1.c.o: parse.cp1.c | out 10 | tcc $(flags) -w -I. -c $^ -o $@ 11 | 12 | out/parse.c.o: parse.c 13 | tcc $(flags) -w -I. -c $^ -o $@ 14 | 15 | out/compile.cp1.c.o: compile.cp1.c | out 16 | tcc $(flags) -w -I. -c $^ -o $@ 17 | 18 | out/compile.c.o: compile.c 19 | tcc $(flags) -w -I. -c $^ -o $@ 20 | 21 | out/hashtable.c.o: hashtable.c 22 | tcc $(flags) -w -I. -c $^ -o $@ 23 | 24 | out/cp1-qjs.c.o: cp1-qjs.c 25 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 26 | 27 | out/quickjs.c.o: qjs/quickjs.c 28 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 29 | 30 | out/quickjs-libc.c.o: qjs/quickjs-libc.c 31 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 32 | 33 | out/cutils.c.o: qjs/cutils.c 34 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 35 | 36 | out/libregexp.c.o: qjs/libregexp.c 37 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 38 | 39 | out/libbf.c.o: qjs/libbf.c 40 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 41 | 42 | out/libunicode.c.o: qjs/libunicode.c 43 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 44 | 45 | bin/cp1-parse: out/parse.cp1.c.o out/parse.c.o out/hashtable.c.o | bin 46 | tcc $(flags) -w -I. $^ -o $@ 47 | 48 | bin/cp1-compile: out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o | bin 49 | tcc $(flags) -w -I. $^ -o $@ 50 | 51 | bin/cp1-run: run.cp1.c | bin 52 | tcc $(flags) -w -I. $^ -o $@ 53 | 54 | bin/cp1-qjs: out/cp1-qjs.c.o out/quickjs.c.o out/quickjs-libc.c.o out/cutils.c.o out/libregexp.c.o out/libbf.c.o out/libunicode.c.o | bin 55 | tcc $(flags) -w -I. $^ -o $@ -lm 56 | -------------------------------------------------------------------------------- /Makefile-template: -------------------------------------------------------------------------------- 1 | all: bin/cp1-parse bin/cp1-compile bin/cp1-run bin/cp1-qjs 2 | 3 | out: 4 | mkdir $@ 5 | 6 | bin: 7 | mkdir $@ 8 | 9 | out/parse.cp1.c.o: parse.cp1.c | out 10 | tcc $(flags) -w -I. -c $^ -o $@ 11 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 12 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 13 | 14 | out/parse.c.o: parse.c 15 | tcc $(flags) -w -I. -c $^ -o $@ 16 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 17 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 18 | 19 | out/compile.cp1.c.o: compile.cp1.c | out 20 | tcc $(flags) -w -I. -c $^ -o $@ 21 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 22 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 23 | 24 | out/compile.c.o: compile.c 25 | tcc $(flags) -w -I. -c $^ -o $@ 26 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 27 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 28 | 29 | out/hashtable.c.o: hashtable.c 30 | tcc $(flags) -w -I. -c $^ -o $@ 31 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 32 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. -c $^ -o $@ 33 | 34 | out/cp1-qjs.c.o: cp1-qjs.c 35 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 36 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 37 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 38 | 39 | out/quickjs.c.o: qjs/quickjs.c 40 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 41 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 42 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 43 | 44 | out/quickjs-libc.c.o: qjs/quickjs-libc.c 45 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 46 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 47 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 48 | 49 | out/cutils.c.o: qjs/cutils.c 50 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 51 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 52 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 53 | 54 | out/libregexp.c.o: qjs/libregexp.c 55 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 56 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 57 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 58 | 59 | out/libbf.c.o: qjs/libbf.c 60 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 61 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 62 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 63 | 64 | out/libunicode.c.o: qjs/libunicode.c 65 | tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $@ -c $^ -Iqjs 66 | clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 67 | gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $@ -c $^ -Iqjs 68 | 69 | bin/cp1-parse: out/parse.cp1.c.o out/parse.c.o out/hashtable.c.o | bin 70 | tcc $(flags) -w -I. $^ -o $@ 71 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ 72 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ 73 | 74 | bin/cp1-compile: out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o | bin 75 | tcc $(flags) -w -I. $^ -o $@ 76 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ 77 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ 78 | 79 | bin/cp1-run: run.cp1.c | bin 80 | tcc $(flags) -w -I. $^ -o $@ 81 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ 82 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ 83 | 84 | bin/cp1-qjs: out/cp1-qjs.c.o out/quickjs.c.o out/quickjs-libc.c.o out/cutils.c.o out/libregexp.c.o out/libbf.c.o out/libunicode.c.o | bin 85 | tcc $(flags) -w -I. $^ -o $@ -lm 86 | clang $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ -lm 87 | gcc $(flags) -Werror=format -Wno-incompatible-pointer-types -I. $^ -o $@ -lm 88 | -------------------------------------------------------------------------------- /Makefile.py: -------------------------------------------------------------------------------- 1 | out = [] 2 | for line in open("Makefile-template", "r"): 3 | if line.startswith("\tclang "): continue 4 | if line.startswith("\tgcc "): continue 5 | out.append(line) 6 | f = open("Makefile-tcc", "wb") 7 | f.write("".join(out).encode("ascii")) 8 | f.close() 9 | 10 | out = [] 11 | for line in open("Makefile-template", "r"): 12 | if line.startswith("\ttcc "): continue 13 | if line.startswith("\tgcc "): continue 14 | out.append(line) 15 | f = open("Makefile-clang", "wb") 16 | f.write("".join(out).encode("ascii")) 17 | f.close() 18 | 19 | out = [] 20 | for line in open("Makefile-template", "r"): 21 | if line.startswith("\ttcc "): continue 22 | if line.startswith("\tclang "): continue 23 | out.append(line) 24 | f = open("Makefile-gcc", "wb") 25 | f.write("".join(out).encode("ascii")) 26 | f.close() 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## What does Hello World (with Metaprogramming) look like? 2 | ![hello](/images/helloworld-2025-02-26.5.png) 3 | 4 | How to use? 5 | - 6 | ``` 7 | git clone https://github.com/galileolajara/cp1 8 | cd cp1 9 | 10 | # On Windows, no need to build. Pre-built .exe are in the bin folder 11 | 12 | # On Linux, macOS, or BSD, run one of the following: 13 | make -f Makefile-tcc # to build using TCC 14 | make -f Makefile-clang # to build using Clang 15 | make -f Makefile-gcc # to build using GCC 16 | ``` 17 | 18 | Then checkout the examples: 19 | ``` 20 | # On Windows: 21 | bin\cp1-run examples/01-hello.cp1 # To run hello world 22 | bin\cp1-compile -c hello.c examples/01-hello.cp1 # To see the C code 23 | 24 | # On Linux, macOS, or BSD: 25 | bin/cp1-run examples/01-hello.cp1 # To run hello world 26 | bin/cp1-compile -c hello.c examples/01-hello.cp1 # To see the C code 27 | ``` 28 | 29 | On Linux, macOS or BSD, if you want to build Cp1 using the .cp1 files, you need ninja and re2c installed. Then run one of the following: 30 | ``` 31 | ninja -f build-tcc.ninja # to build using TCC 32 | ninja -f build-clang.ninja # to build using Clang 33 | ninja -f build-gcc.ninja # to build using GCC 34 | ``` 35 | Top 1 Feature: Easy-to-use yet powerful metaprogramming system 36 | - 37 | - Metaprogramming is just as easy as *string intepolation*. Uses QuickJS of Fabrice Bellard (who made TCC). 38 | - Metaprograms are cached and have few or *zero overhead*. 39 | - Debugging metaprograms is *easier* because you can see the output of metaprograms in the cache folder. 40 | 41 | Top 2 Feature: Fast compilation speeds 42 | - 43 | - Took *incremental compilation* seriously. Up to 125K lines of codes per second on Macbook M2. 44 | - Codes are *cached and never parsed again*. 45 | - Cp1 can build itself in *0.1 seconds* using TCC on Macbook M2. 46 | 47 | Top 3 Feature: Shorter codes 48 | - 49 | - *Function arguments* can be used to declare variables. 50 | - Enums, primitive types and literals *also have methods*. 51 | - Meta-methods can help you *implement printf-like functionality* easily. 52 | 53 | Cp1 means C+1 or C plus 1, named just like C++ or C plus plus 54 | - 55 | - Cp1 is a very thin abstraction on top of C. Think of it as a TypeScript for C. The +1 in the name suggests that the thin abstraction is just the bare essentials to equip C some of the modern features today such as support for metaprogramming, methods on enums, structs and even the primitive types, support for C++'s auto keyword for variables, namespaces, modules and more. 56 | - Cp1 is vastly different from Zig, Odin, C3, Rust, Vlang because Cp1 aims to maintain only few features but these few features are carefully selected to allow you to do a lot of things when these features are combined. 57 | - Also, Cp1's top priority is compilation speed, similar to Vlang. Cloning the repo and building it for the first time using build-tcc.ninja takes 0.1s on Macbook Pro M2 with Fedora Asahi Remix (Linux OS). Editing a source file of Cp1 then recompiling (incremental compilation) takes 0.05s. 58 | 59 | Join us on Discord! 60 | - 61 | [![Discord](https://dcbadge.vercel.app/api/server/qBtunCNyUS)](https://discord.gg/qBtunCNyUS) 62 | -------------------------------------------------------------------------------- /bin/cp1-compile.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galileolajara/cp1/e8f66aad5d34db3201b8a43ef09658c4b1bb5c42/bin/cp1-compile.exe -------------------------------------------------------------------------------- /bin/cp1-parse.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galileolajara/cp1/e8f66aad5d34db3201b8a43ef09658c4b1bb5c42/bin/cp1-parse.exe -------------------------------------------------------------------------------- /bin/cp1-qjs.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galileolajara/cp1/e8f66aad5d34db3201b8a43ef09658c4b1bb5c42/bin/cp1-qjs.exe -------------------------------------------------------------------------------- /bin/cp1-run.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galileolajara/cp1/e8f66aad5d34db3201b8a43ef09658c4b1bb5c42/bin/cp1-run.exe -------------------------------------------------------------------------------- /build-clang-debug.ninja: -------------------------------------------------------------------------------- 1 | rule c 2 | command = clang $flags -fsanitize=undefined -ggdb -Werror=format -Wno-incompatible-pointer-types -I. -c $in -o $out 3 | 4 | #rule objredef 5 | # command = objcopy --redefine-syms=$redefs $in $out 6 | 7 | rule ld-c 8 | command = clang -Werror=format -Wno-incompatible-pointer-types -I. $in -o $out $flags -fsanitize=undefined -ggdb 9 | 10 | rule crc32c 11 | command = bin/crc32c $in $out 12 | 13 | build out/parse.cp1.c.o: c parse.cp1.c 14 | #build out/parse-redef.cp1.c.o: objredef out/parse.cp1.c.o | redefs 15 | # redefs = redefs 16 | build out/parse.c.o: c parse.c | export.h lex.c cp1_parse.c 17 | build out/compile.cp1.c.o: c compile.cp1.c 18 | build out/compile.c.o: c compile.c 19 | build bin/cp1-parse: ld-c out/parse.cp1.c.o out/parse.c.o out/hashtable.c.o | build-crc32c.h 20 | build bin/cp1-compile: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o 21 | # out/parse-redef.cp1.c.o out/parse.c.o 22 | #build bin/cp1-compile-redef-output: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o out/parse.cp1.c.o out/parse.c.o 23 | build bin/cp1-run: ld-c run.cp1.c 24 | build bin/crc32c: ld-c crc32c.c | crc32c.h 25 | build out/hashtable.c.o: c hashtable2.c 26 | 27 | rule cjs 28 | command = clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $out -c $in -Iqjs 29 | 30 | build bin/cp1-qjs: ld-c out/cp1-qjs.c.o out/quickjs.c.o out/quickjs-libc.c.o out/cutils.c.o out/libregexp.c.o out/libbf.c.o out/libunicode.c.o 31 | flags = -lm 32 | build out/cp1-qjs.c.o: cjs cp1-qjs.c 33 | build out/quickjs.c.o: cjs qjs/quickjs.c 34 | build out/quickjs-libc.c.o: cjs qjs/quickjs-libc.c 35 | build out/cutils.c.o: cjs qjs/cutils.c 36 | build out/libregexp.c.o: cjs qjs/libregexp.c 37 | build out/libbf.c.o: cjs qjs/libbf.c 38 | build out/libunicode.c.o: cjs qjs/libunicode.c 39 | 40 | rule c2 41 | command = clang $flags -fsanitize=undefined -ggdb -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. -c $in -o $out 42 | 43 | rule ld-c2 44 | command = clang $flags -fsanitize=undefined -ggdb -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out 45 | 46 | #rule ld-c2-redef 47 | # command = gcc $flags -ggdb -O0 -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out.tmp 2> redefs2.txt || true && node redefs.js redefs2.txt redefs2 && touch $out 48 | 49 | rule re2c 50 | command = re2c --input-encoding utf8 --utf8 $in -o $out 51 | 52 | rule ld-lemon 53 | command = clang -I. $in -o $out 54 | 55 | rule lemon 56 | restat = true 57 | command = out/lemon -dout $in 58 | 59 | rule compile 60 | command = bin/cp1-compile -w $in -c $out $flags 61 | 62 | rule run 63 | command = $in $out 64 | 65 | build out/hash-table-size: ld-c2 hashtable2.c 66 | flags = -DCP1_GET_SIZE 67 | build out/hash-table-size.cp1: run out/hash-table-size 68 | 69 | build out/token.cp1.c: compile token.cp1 | include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 70 | build out/token: ld-c2 out/token.cp1.c 71 | build out/token.cp1: run out/token out/cp1_parse.h 72 | build out/run2.cp1.c: compile Cp1/run.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 73 | build out/parse2.cp1.c: compile Cp1/parse.cp1 out/token.cp1 Cp1/break.cp1 Cp1/math.cp1 Cp1/bools.cp1 Cp1/str.cp1 Cp1/cvar.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/index.cp1 Cp1/switch.cp1 Cp1/if.cp1 Cp1/loop.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/call.cp1 Cp1/null.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/assign.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/continue.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/var.cp1 Cp1/func.cp1 Cp1/lvar.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/common.cp1 Cp1/struct.cp1 Cp1/file.cp1 out/hash-table-size.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 74 | build out/compile2.cp1.c: compile Cp1/compile.cp1 Cp1/meta.cp1 Cp1/common.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/func.cp1 Cp1/struct.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/var.cp1 Cp1/assign.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/math.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/lvar.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/cvar.cp1 Cp1/bools.cp1 Cp1/call.cp1 Cp1/str.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/null.cp1 Cp1/index.cp1 Cp1/if.cp1 Cp1/switch.cp1 Cp1/loop.cp1 Cp1/continue.cp1 Cp1/break.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 out/hash-table-size.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 75 | build out/export.cp1.c: compile export.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 76 | build out/export: ld-c2 out/export.cp1.c 77 | build out/export.h: run out/export out/parse2.cp1.c 78 | build out/lex.c: re2c lex-re2c.c 79 | build out/lemon: ld-lemon lemon.c 80 | build out/cp1_parse.c out/cp1_parse.h: lemon cp1_parse.y | out/lemon 81 | build out/cp1-run: ld-c2 out/run2.cp1.c 82 | build out/parse2.cp1.c.o: c2 out/parse2.cp1.c 83 | build out/parse2.c.o: c2 parse2.c | out/export.h out/lex.c out/cp1_parse.c 84 | #build out/parse2-redef.cp1.c.o: objredef out/parse2.cp1.c.o | redefs2 85 | # redefs = redefs2 86 | build out/hashtable2.c.o: c2 hashtable2.c 87 | build out/build-crc32c.h: crc32c out/compile2.cp1.c out/parse2.cp1.c compile2.c parse2.c lex-re2c.c | bin/crc32c 88 | build out/compile2.cp1.c.o: c2 out/compile2.cp1.c | out/build-crc32c.h 89 | build out/compile2.c.o: c2 compile2.c | out/build-crc32c.h 90 | build out/cp1-parse: ld-c2 out/parse2.cp1.c.o out/parse2.c.o out/hashtable.c.o 91 | build out/cp1-compile: ld-c2 out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o 92 | #build out/cp1-compile-redef-output | redefs2: ld-c2-redef out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o out/parse2.cp1.c.o out/parse2.c.o 93 | -------------------------------------------------------------------------------- /build-clang-release.ninja: -------------------------------------------------------------------------------- 1 | rule c 2 | command = clang $flags -O3 -flto -Werror=format -Wno-incompatible-pointer-types -I. -c $in -o $out 3 | 4 | #rule objredef 5 | # command = objcopy --redefine-syms=$redefs $in $out 6 | 7 | rule ld-c 8 | command = clang -Werror=format -Wno-incompatible-pointer-types -I. $in -o $out $flags -O3 -flto 9 | 10 | rule crc32c 11 | command = bin/crc32c $in $out 12 | 13 | build out/parse.cp1.c.o: c parse.cp1.c 14 | #build out/parse-redef.cp1.c.o: objredef out/parse.cp1.c.o | redefs 15 | # redefs = redefs 16 | build out/parse.c.o: c parse.c | export.h lex.c cp1_parse.c 17 | build out/compile.cp1.c.o: c compile.cp1.c 18 | build out/compile.c.o: c compile.c 19 | build bin/cp1-parse: ld-c out/parse.cp1.c.o out/parse.c.o out/hashtable.c.o | build-crc32c.h 20 | build bin/cp1-compile: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o 21 | # out/parse-redef.cp1.c.o out/parse.c.o 22 | #build bin/cp1-compile-redef-output: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o out/parse.cp1.c.o out/parse.c.o 23 | build bin/cp1-run: ld-c run.cp1.c 24 | build bin/crc32c: ld-c crc32c.c | crc32c.h 25 | build out/hashtable.c.o: c hashtable2.c 26 | 27 | rule cjs 28 | command = clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $out -c $in -Iqjs 29 | 30 | build bin/cp1-qjs: ld-c out/cp1-qjs.c.o out/quickjs.c.o out/quickjs-libc.c.o out/cutils.c.o out/libregexp.c.o out/libbf.c.o out/libunicode.c.o 31 | flags = -lm 32 | build out/cp1-qjs.c.o: cjs cp1-qjs.c 33 | build out/quickjs.c.o: cjs qjs/quickjs.c 34 | build out/quickjs-libc.c.o: cjs qjs/quickjs-libc.c 35 | build out/cutils.c.o: cjs qjs/cutils.c 36 | build out/libregexp.c.o: cjs qjs/libregexp.c 37 | build out/libbf.c.o: cjs qjs/libbf.c 38 | build out/libunicode.c.o: cjs qjs/libunicode.c 39 | 40 | rule c2 41 | command = clang $flags -O3 -flto -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. -c $in -o $out 42 | 43 | rule ld-c2 44 | command = clang $flags -O3 -flto -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out 45 | 46 | #rule ld-c2-redef 47 | # command = gcc $flags -ggdb -O0 -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out.tmp 2> redefs2.txt || true && node redefs.js redefs2.txt redefs2 && touch $out 48 | 49 | rule re2c 50 | command = re2c --input-encoding utf8 --utf8 $in -o $out 51 | 52 | rule ld-lemon 53 | command = clang -I. $in -o $out 54 | 55 | rule lemon 56 | restat = true 57 | command = out/lemon -dout $in 58 | 59 | rule compile 60 | command = bin/cp1-compile -w $in -c $out $flags 61 | 62 | rule run 63 | command = $in $out 64 | 65 | build out/hash-table-size: ld-c2 hashtable2.c 66 | flags = -DCP1_GET_SIZE 67 | build out/hash-table-size.cp1: run out/hash-table-size 68 | 69 | build out/token.cp1.c: compile token.cp1 | include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 70 | build out/token: ld-c2 out/token.cp1.c 71 | build out/token.cp1: run out/token out/cp1_parse.h 72 | build out/run2.cp1.c: compile Cp1/run.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 73 | build out/parse2.cp1.c: compile Cp1/parse.cp1 out/token.cp1 Cp1/break.cp1 Cp1/math.cp1 Cp1/bools.cp1 Cp1/str.cp1 Cp1/cvar.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/index.cp1 Cp1/switch.cp1 Cp1/if.cp1 Cp1/loop.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/call.cp1 Cp1/null.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/assign.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/continue.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/var.cp1 Cp1/func.cp1 Cp1/lvar.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/common.cp1 Cp1/struct.cp1 Cp1/file.cp1 out/hash-table-size.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 74 | build out/compile2.cp1.c: compile Cp1/compile.cp1 Cp1/meta.cp1 Cp1/common.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/func.cp1 Cp1/struct.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/var.cp1 Cp1/assign.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/math.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/lvar.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/cvar.cp1 Cp1/bools.cp1 Cp1/call.cp1 Cp1/str.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/null.cp1 Cp1/index.cp1 Cp1/if.cp1 Cp1/switch.cp1 Cp1/loop.cp1 Cp1/continue.cp1 Cp1/break.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 out/hash-table-size.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 75 | build out/export.cp1.c: compile export.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 76 | build out/export: ld-c2 out/export.cp1.c 77 | build out/export.h: run out/export out/parse2.cp1.c 78 | build out/lex.c: re2c lex-re2c.c 79 | build out/lemon: ld-lemon lemon.c 80 | build out/cp1_parse.c out/cp1_parse.h: lemon cp1_parse.y | out/lemon 81 | build out/cp1-run: ld-c2 out/run2.cp1.c 82 | build out/parse2.cp1.c.o: c2 out/parse2.cp1.c 83 | build out/parse2.c.o: c2 parse2.c | out/export.h out/lex.c out/cp1_parse.c 84 | #build out/parse2-redef.cp1.c.o: objredef out/parse2.cp1.c.o | redefs2 85 | # redefs = redefs2 86 | build out/hashtable2.c.o: c2 hashtable2.c 87 | build out/build-crc32c.h: crc32c out/compile2.cp1.c out/parse2.cp1.c compile2.c parse2.c lex-re2c.c | bin/crc32c 88 | build out/compile2.cp1.c.o: c2 out/compile2.cp1.c | out/build-crc32c.h 89 | build out/compile2.c.o: c2 compile2.c | out/build-crc32c.h 90 | build out/cp1-parse: ld-c2 out/parse2.cp1.c.o out/parse2.c.o out/hashtable.c.o 91 | build out/cp1-compile: ld-c2 out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o 92 | #build out/cp1-compile-redef-output | redefs2: ld-c2-redef out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o out/parse2.cp1.c.o out/parse2.c.o 93 | -------------------------------------------------------------------------------- /build-clang.ninja: -------------------------------------------------------------------------------- 1 | rule c 2 | command = clang $flags -Werror=format -Wno-incompatible-pointer-types -I. -c $in -o $out 3 | 4 | #rule objredef 5 | # command = objcopy --redefine-syms=$redefs $in $out 6 | 7 | rule ld-c 8 | command = clang -Werror=format -Wno-incompatible-pointer-types -I. $in -o $out $flags 9 | 10 | rule crc32c 11 | command = bin/crc32c $in $out 12 | 13 | build out/parse.cp1.c.o: c parse.cp1.c 14 | #build out/parse-redef.cp1.c.o: objredef out/parse.cp1.c.o | redefs 15 | # redefs = redefs 16 | build out/parse.c.o: c parse.c | export.h lex.c cp1_parse.c 17 | build out/compile.cp1.c.o: c compile.cp1.c 18 | build out/compile.c.o: c compile.c 19 | build bin/cp1-parse: ld-c out/parse.cp1.c.o out/parse.c.o out/hashtable.c.o | build-crc32c.h 20 | build bin/cp1-compile: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o 21 | # out/parse-redef.cp1.c.o out/parse.c.o 22 | #build bin/cp1-compile-redef-output: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o out/parse.cp1.c.o out/parse.c.o 23 | build bin/cp1-run: ld-c run.cp1.c 24 | build bin/crc32c: ld-c crc32c.c | crc32c.h 25 | build out/hashtable.c.o: c hashtable2.c 26 | 27 | rule cjs 28 | command = clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $out -c $in -Iqjs 29 | 30 | build bin/cp1-qjs: ld-c out/cp1-qjs.c.o out/quickjs.c.o out/quickjs-libc.c.o out/cutils.c.o out/libregexp.c.o out/libbf.c.o out/libunicode.c.o 31 | flags = -lm 32 | build out/cp1-qjs.c.o: cjs cp1-qjs.c 33 | build out/quickjs.c.o: cjs qjs/quickjs.c 34 | build out/quickjs-libc.c.o: cjs qjs/quickjs-libc.c 35 | build out/cutils.c.o: cjs qjs/cutils.c 36 | build out/libregexp.c.o: cjs qjs/libregexp.c 37 | build out/libbf.c.o: cjs qjs/libbf.c 38 | build out/libunicode.c.o: cjs qjs/libunicode.c 39 | 40 | rule c2 41 | command = clang $flags -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. -c $in -o $out 42 | 43 | rule ld-c2 44 | command = clang $flags -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out 45 | 46 | #rule ld-c2-redef 47 | # command = gcc $flags -ggdb -O0 -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out.tmp 2> redefs2.txt || true && node redefs.js redefs2.txt redefs2 && touch $out 48 | 49 | rule re2c 50 | command = re2c --input-encoding utf8 --utf8 $in -o $out 51 | 52 | rule ld-lemon 53 | command = clang -I. $in -o $out 54 | 55 | rule lemon 56 | restat = true 57 | command = out/lemon -dout $in 58 | 59 | rule compile 60 | command = bin/cp1-compile -w $in -c $out $flags 61 | 62 | rule run 63 | command = $in $out 64 | 65 | build out/hash-table-size: ld-c2 hashtable2.c 66 | flags = -DCP1_GET_SIZE 67 | build out/hash-table-size.cp1: run out/hash-table-size 68 | 69 | build out/token.cp1.c: compile token.cp1 | include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 70 | build out/token: ld-c2 out/token.cp1.c 71 | build out/token.cp1: run out/token out/cp1_parse.h 72 | build out/run2.cp1.c: compile Cp1/run.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 73 | build out/parse2.cp1.c: compile Cp1/parse.cp1 out/token.cp1 Cp1/break.cp1 Cp1/math.cp1 Cp1/bools.cp1 Cp1/str.cp1 Cp1/cvar.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/index.cp1 Cp1/switch.cp1 Cp1/if.cp1 Cp1/loop.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/call.cp1 Cp1/null.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/assign.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/continue.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/var.cp1 Cp1/func.cp1 Cp1/lvar.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/common.cp1 Cp1/struct.cp1 Cp1/file.cp1 out/hash-table-size.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 74 | build out/compile2.cp1.c: compile Cp1/compile.cp1 Cp1/meta.cp1 Cp1/common.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/func.cp1 Cp1/struct.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/var.cp1 Cp1/assign.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/math.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/lvar.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/cvar.cp1 Cp1/bools.cp1 Cp1/call.cp1 Cp1/str.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/null.cp1 Cp1/index.cp1 Cp1/if.cp1 Cp1/switch.cp1 Cp1/loop.cp1 Cp1/continue.cp1 Cp1/break.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 out/hash-table-size.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 75 | build out/export.cp1.c: compile export.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 76 | build out/export: ld-c2 out/export.cp1.c 77 | build out/export.h: run out/export out/parse2.cp1.c 78 | build out/lex.c: re2c lex-re2c.c 79 | build out/lemon: ld-lemon lemon.c 80 | build out/cp1_parse.c out/cp1_parse.h: lemon cp1_parse.y | out/lemon 81 | build out/cp1-run: ld-c2 out/run2.cp1.c 82 | build out/parse2.cp1.c.o: c2 out/parse2.cp1.c 83 | build out/parse2.c.o: c2 parse2.c | out/export.h out/lex.c out/cp1_parse.c 84 | #build out/parse2-redef.cp1.c.o: objredef out/parse2.cp1.c.o | redefs2 85 | # redefs = redefs2 86 | build out/hashtable2.c.o: c2 hashtable2.c 87 | build out/build-crc32c.h: crc32c out/compile2.cp1.c out/parse2.cp1.c compile2.c parse2.c lex-re2c.c | bin/crc32c 88 | build out/compile2.cp1.c.o: c2 out/compile2.cp1.c | out/build-crc32c.h 89 | build out/compile2.c.o: c2 compile2.c | out/build-crc32c.h 90 | build out/cp1-parse: ld-c2 out/parse2.cp1.c.o out/parse2.c.o out/hashtable.c.o 91 | build out/cp1-compile: ld-c2 out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o 92 | #build out/cp1-compile-redef-output | redefs2: ld-c2-redef out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o out/parse2.cp1.c.o out/parse2.c.o 93 | -------------------------------------------------------------------------------- /build-crc32c.c: -------------------------------------------------------------------------------- 1 | #ifdef CP1_NEW 2 | #include "out/build-crc32c.h" 3 | #else 4 | #include "build-crc32c.h" 5 | #endif 6 | -------------------------------------------------------------------------------- /build-crc32c.h: -------------------------------------------------------------------------------- 1 | #define _NCp1_Pbuild_crc32c_0() 0xa7435b44 2 | -------------------------------------------------------------------------------- /build-gcc-debug.ninja: -------------------------------------------------------------------------------- 1 | rule c 2 | command = gcc $flags -fsanitize=undefined -ggdb -Werror=format -Wno-incompatible-pointer-types -I. -c $in -o $out 3 | 4 | #rule objredef 5 | # command = objcopy --redefine-syms=$redefs $in $out 6 | 7 | rule ld-c 8 | command = gcc -Werror=format -Wno-incompatible-pointer-types -I. $in -o $out $flags -fsanitize=undefined -ggdb 9 | 10 | rule crc32c 11 | command = bin/crc32c $in $out 12 | 13 | build out/parse.cp1.c.o: c parse.cp1.c 14 | #build out/parse-redef.cp1.c.o: objredef out/parse.cp1.c.o | redefs 15 | # redefs = redefs 16 | build out/parse.c.o: c parse.c | export.h lex.c cp1_parse.c 17 | build out/compile.cp1.c.o: c compile.cp1.c 18 | build out/compile.c.o: c compile.c 19 | build bin/cp1-parse: ld-c out/parse.cp1.c.o out/parse.c.o out/hashtable.c.o | build-crc32c.h 20 | build bin/cp1-compile: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o 21 | # out/parse-redef.cp1.c.o out/parse.c.o 22 | #build bin/cp1-compile-redef-output: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o out/parse.cp1.c.o out/parse.c.o 23 | build bin/cp1-run: ld-c run.cp1.c 24 | build bin/crc32c: ld-c crc32c.c | crc32c.h 25 | build out/hashtable.c.o: c hashtable2.c 26 | 27 | rule cjs 28 | command = gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $out -c $in -Iqjs 29 | 30 | build bin/cp1-qjs: ld-c out/cp1-qjs.c.o out/quickjs.c.o out/quickjs-libc.c.o out/cutils.c.o out/libregexp.c.o out/libbf.c.o out/libunicode.c.o 31 | flags = -lm 32 | build out/cp1-qjs.c.o: cjs cp1-qjs.c 33 | build out/quickjs.c.o: cjs qjs/quickjs.c 34 | build out/quickjs-libc.c.o: cjs qjs/quickjs-libc.c 35 | build out/cutils.c.o: cjs qjs/cutils.c 36 | build out/libregexp.c.o: cjs qjs/libregexp.c 37 | build out/libbf.c.o: cjs qjs/libbf.c 38 | build out/libunicode.c.o: cjs qjs/libunicode.c 39 | 40 | rule c2 41 | command = gcc $flags -fsanitize=undefined -ggdb -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. -c $in -o $out 42 | 43 | rule ld-c2 44 | command = gcc $flags -fsanitize=undefined -ggdb -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out 45 | 46 | #rule ld-c2-redef 47 | # command = gcc $flags -ggdb -O0 -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out.tmp 2> redefs2.txt || true && node redefs.js redefs2.txt redefs2 && touch $out 48 | 49 | rule re2c 50 | command = re2c --input-encoding utf8 --utf8 $in -o $out 51 | 52 | rule ld-lemon 53 | command = gcc -I. $in -o $out 54 | 55 | rule lemon 56 | restat = true 57 | command = out/lemon -dout $in 58 | 59 | rule compile 60 | command = bin/cp1-compile -w $in -c $out $flags 61 | 62 | rule run 63 | command = $in $out 64 | 65 | build out/hash-table-size: ld-c2 hashtable2.c 66 | flags = -DCP1_GET_SIZE 67 | build out/hash-table-size.cp1: run out/hash-table-size 68 | 69 | build out/token.cp1.c: compile token.cp1 | include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 70 | build out/token: ld-c2 out/token.cp1.c 71 | build out/token.cp1: run out/token out/cp1_parse.h 72 | build out/run2.cp1.c: compile Cp1/run.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 73 | build out/parse2.cp1.c: compile Cp1/parse.cp1 out/token.cp1 Cp1/break.cp1 Cp1/math.cp1 Cp1/bools.cp1 Cp1/str.cp1 Cp1/cvar.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/index.cp1 Cp1/switch.cp1 Cp1/if.cp1 Cp1/loop.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/call.cp1 Cp1/null.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/assign.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/continue.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/var.cp1 Cp1/func.cp1 Cp1/lvar.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/common.cp1 Cp1/struct.cp1 Cp1/file.cp1 out/hash-table-size.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 74 | build out/compile2.cp1.c: compile Cp1/compile.cp1 Cp1/meta.cp1 Cp1/common.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/func.cp1 Cp1/struct.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/var.cp1 Cp1/assign.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/math.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/lvar.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/cvar.cp1 Cp1/bools.cp1 Cp1/call.cp1 Cp1/str.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/null.cp1 Cp1/index.cp1 Cp1/if.cp1 Cp1/switch.cp1 Cp1/loop.cp1 Cp1/continue.cp1 Cp1/break.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 out/hash-table-size.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 75 | build out/export.cp1.c: compile export.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 76 | build out/export: ld-c2 out/export.cp1.c 77 | build out/export.h: run out/export out/parse2.cp1.c 78 | build out/lex.c: re2c lex-re2c.c 79 | build out/lemon: ld-lemon lemon.c 80 | build out/cp1_parse.c out/cp1_parse.h: lemon cp1_parse.y | out/lemon 81 | build out/cp1-run: ld-c2 out/run2.cp1.c 82 | build out/parse2.cp1.c.o: c2 out/parse2.cp1.c 83 | build out/parse2.c.o: c2 parse2.c | out/export.h out/lex.c out/cp1_parse.c 84 | #build out/parse2-redef.cp1.c.o: objredef out/parse2.cp1.c.o | redefs2 85 | # redefs = redefs2 86 | build out/hashtable2.c.o: c2 hashtable2.c 87 | build out/build-crc32c.h: crc32c out/compile2.cp1.c out/parse2.cp1.c compile2.c parse2.c lex-re2c.c | bin/crc32c 88 | build out/compile2.cp1.c.o: c2 out/compile2.cp1.c | out/build-crc32c.h 89 | build out/compile2.c.o: c2 compile2.c | out/build-crc32c.h 90 | build out/cp1-parse: ld-c2 out/parse2.cp1.c.o out/parse2.c.o out/hashtable.c.o 91 | build out/cp1-compile: ld-c2 out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o 92 | #build out/cp1-compile-redef-output | redefs2: ld-c2-redef out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o out/parse2.cp1.c.o out/parse2.c.o 93 | -------------------------------------------------------------------------------- /build-gcc-release.ninja: -------------------------------------------------------------------------------- 1 | rule c 2 | command = gcc $flags -O3 -flto -Werror=format -Wno-incompatible-pointer-types -I. -c $in -o $out 3 | 4 | #rule objredef 5 | # command = objcopy --redefine-syms=$redefs $in $out 6 | 7 | rule ld-c 8 | command = gcc -Werror=format -Wno-incompatible-pointer-types -I. $in -o $out $flags -O3 -flto 9 | 10 | rule crc32c 11 | command = bin/crc32c $in $out 12 | 13 | build out/parse.cp1.c.o: c parse.cp1.c 14 | #build out/parse-redef.cp1.c.o: objredef out/parse.cp1.c.o | redefs 15 | # redefs = redefs 16 | build out/parse.c.o: c parse.c | export.h lex.c cp1_parse.c 17 | build out/compile.cp1.c.o: c compile.cp1.c 18 | build out/compile.c.o: c compile.c 19 | build bin/cp1-parse: ld-c out/parse.cp1.c.o out/parse.c.o out/hashtable.c.o | build-crc32c.h 20 | build bin/cp1-compile: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o 21 | # out/parse-redef.cp1.c.o out/parse.c.o 22 | #build bin/cp1-compile-redef-output: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o out/parse.cp1.c.o out/parse.c.o 23 | build bin/cp1-run: ld-c run.cp1.c 24 | build bin/crc32c: ld-c crc32c.c | crc32c.h 25 | build out/hashtable.c.o: c hashtable2.c 26 | 27 | rule cjs 28 | command = gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $out -c $in -Iqjs 29 | 30 | build bin/cp1-qjs: ld-c out/cp1-qjs.c.o out/quickjs.c.o out/quickjs-libc.c.o out/cutils.c.o out/libregexp.c.o out/libbf.c.o out/libunicode.c.o 31 | flags = -lm 32 | build out/cp1-qjs.c.o: cjs cp1-qjs.c 33 | build out/quickjs.c.o: cjs qjs/quickjs.c 34 | build out/quickjs-libc.c.o: cjs qjs/quickjs-libc.c 35 | build out/cutils.c.o: cjs qjs/cutils.c 36 | build out/libregexp.c.o: cjs qjs/libregexp.c 37 | build out/libbf.c.o: cjs qjs/libbf.c 38 | build out/libunicode.c.o: cjs qjs/libunicode.c 39 | 40 | rule c2 41 | command = gcc $flags -O3 -flto -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. -c $in -o $out 42 | 43 | rule ld-c2 44 | command = gcc $flags -O3 -flto -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out 45 | 46 | #rule ld-c2-redef 47 | # command = gcc $flags -ggdb -O0 -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out.tmp 2> redefs2.txt || true && node redefs.js redefs2.txt redefs2 && touch $out 48 | 49 | rule re2c 50 | command = re2c --input-encoding utf8 --utf8 $in -o $out 51 | 52 | rule ld-lemon 53 | command = gcc -I. $in -o $out 54 | 55 | rule lemon 56 | restat = true 57 | command = out/lemon -dout $in 58 | 59 | rule compile 60 | command = bin/cp1-compile -w $in -c $out $flags 61 | 62 | rule run 63 | command = $in $out 64 | 65 | build out/hash-table-size: ld-c2 hashtable2.c 66 | flags = -DCP1_GET_SIZE 67 | build out/hash-table-size.cp1: run out/hash-table-size 68 | 69 | build out/token.cp1.c: compile token.cp1 | include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 70 | build out/token: ld-c2 out/token.cp1.c 71 | build out/token.cp1: run out/token out/cp1_parse.h 72 | build out/run2.cp1.c: compile Cp1/run.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 73 | build out/parse2.cp1.c: compile Cp1/parse.cp1 out/token.cp1 Cp1/break.cp1 Cp1/math.cp1 Cp1/bools.cp1 Cp1/str.cp1 Cp1/cvar.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/index.cp1 Cp1/switch.cp1 Cp1/if.cp1 Cp1/loop.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/call.cp1 Cp1/null.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/assign.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/continue.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/var.cp1 Cp1/func.cp1 Cp1/lvar.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/common.cp1 Cp1/struct.cp1 Cp1/file.cp1 out/hash-table-size.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 74 | build out/compile2.cp1.c: compile Cp1/compile.cp1 Cp1/meta.cp1 Cp1/common.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/func.cp1 Cp1/struct.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/var.cp1 Cp1/assign.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/math.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/lvar.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/cvar.cp1 Cp1/bools.cp1 Cp1/call.cp1 Cp1/str.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/null.cp1 Cp1/index.cp1 Cp1/if.cp1 Cp1/switch.cp1 Cp1/loop.cp1 Cp1/continue.cp1 Cp1/break.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 out/hash-table-size.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 75 | build out/export.cp1.c: compile export.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 76 | build out/export: ld-c2 out/export.cp1.c 77 | build out/export.h: run out/export out/parse2.cp1.c 78 | build out/lex.c: re2c lex-re2c.c 79 | build out/lemon: ld-lemon lemon.c 80 | build out/cp1_parse.c out/cp1_parse.h: lemon cp1_parse.y | out/lemon 81 | build out/cp1-run: ld-c2 out/run2.cp1.c 82 | build out/parse2.cp1.c.o: c2 out/parse2.cp1.c 83 | build out/parse2.c.o: c2 parse2.c | out/export.h out/lex.c out/cp1_parse.c 84 | #build out/parse2-redef.cp1.c.o: objredef out/parse2.cp1.c.o | redefs2 85 | # redefs = redefs2 86 | build out/hashtable2.c.o: c2 hashtable2.c 87 | build out/build-crc32c.h: crc32c out/compile2.cp1.c out/parse2.cp1.c compile2.c parse2.c lex-re2c.c | bin/crc32c 88 | build out/compile2.cp1.c.o: c2 out/compile2.cp1.c | out/build-crc32c.h 89 | build out/compile2.c.o: c2 compile2.c | out/build-crc32c.h 90 | build out/cp1-parse: ld-c2 out/parse2.cp1.c.o out/parse2.c.o out/hashtable.c.o 91 | build out/cp1-compile: ld-c2 out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o 92 | #build out/cp1-compile-redef-output | redefs2: ld-c2-redef out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o out/parse2.cp1.c.o out/parse2.c.o 93 | -------------------------------------------------------------------------------- /build-gcc.ninja: -------------------------------------------------------------------------------- 1 | rule c 2 | command = gcc $flags -Werror=format -Wno-incompatible-pointer-types -I. -c $in -o $out 3 | 4 | #rule objredef 5 | # command = objcopy --redefine-syms=$redefs $in $out 6 | 7 | rule ld-c 8 | command = gcc -Werror=format -Wno-incompatible-pointer-types -I. $in -o $out $flags 9 | 10 | rule crc32c 11 | command = bin/crc32c $in $out 12 | 13 | build out/parse.cp1.c.o: c parse.cp1.c 14 | #build out/parse-redef.cp1.c.o: objredef out/parse.cp1.c.o | redefs 15 | # redefs = redefs 16 | build out/parse.c.o: c parse.c | export.h lex.c cp1_parse.c 17 | build out/compile.cp1.c.o: c compile.cp1.c 18 | build out/compile.c.o: c compile.c 19 | build bin/cp1-parse: ld-c out/parse.cp1.c.o out/parse.c.o out/hashtable.c.o | build-crc32c.h 20 | build bin/cp1-compile: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o 21 | # out/parse-redef.cp1.c.o out/parse.c.o 22 | #build bin/cp1-compile-redef-output: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o out/parse.cp1.c.o out/parse.c.o 23 | build bin/cp1-run: ld-c run.cp1.c 24 | build bin/crc32c: ld-c crc32c.c | crc32c.h 25 | build out/hashtable.c.o: c hashtable2.c 26 | 27 | rule cjs 28 | command = gcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $out -c $in -Iqjs 29 | 30 | build bin/cp1-qjs: ld-c out/cp1-qjs.c.o out/quickjs.c.o out/quickjs-libc.c.o out/cutils.c.o out/libregexp.c.o out/libbf.c.o out/libunicode.c.o 31 | flags = -lm 32 | build out/cp1-qjs.c.o: cjs cp1-qjs.c 33 | build out/quickjs.c.o: cjs qjs/quickjs.c 34 | build out/quickjs-libc.c.o: cjs qjs/quickjs-libc.c 35 | build out/cutils.c.o: cjs qjs/cutils.c 36 | build out/libregexp.c.o: cjs qjs/libregexp.c 37 | build out/libbf.c.o: cjs qjs/libbf.c 38 | build out/libunicode.c.o: cjs qjs/libunicode.c 39 | 40 | rule c2 41 | command = gcc $flags -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. -c $in -o $out 42 | 43 | rule ld-c2 44 | command = gcc $flags -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out 45 | 46 | #rule ld-c2-redef 47 | # command = gcc $flags -ggdb -O0 -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out.tmp 2> redefs2.txt || true && node redefs.js redefs2.txt redefs2 && touch $out 48 | 49 | rule re2c 50 | command = re2c --input-encoding utf8 --utf8 $in -o $out 51 | 52 | rule ld-lemon 53 | command = gcc -I. $in -o $out 54 | 55 | rule lemon 56 | restat = true 57 | command = out/lemon -dout $in 58 | 59 | rule compile 60 | command = bin/cp1-compile -w $in -c $out $flags 61 | 62 | rule run 63 | command = $in $out 64 | 65 | build out/hash-table-size: ld-c2 hashtable2.c 66 | flags = -DCP1_GET_SIZE 67 | build out/hash-table-size.cp1: run out/hash-table-size 68 | 69 | build out/token.cp1.c: compile token.cp1 | include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 70 | build out/token: ld-c2 out/token.cp1.c 71 | build out/token.cp1: run out/token out/cp1_parse.h 72 | build out/run2.cp1.c: compile Cp1/run.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 73 | build out/parse2.cp1.c: compile Cp1/parse.cp1 out/token.cp1 Cp1/break.cp1 Cp1/math.cp1 Cp1/bools.cp1 Cp1/str.cp1 Cp1/cvar.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/index.cp1 Cp1/switch.cp1 Cp1/if.cp1 Cp1/loop.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/call.cp1 Cp1/null.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/assign.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/continue.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/var.cp1 Cp1/func.cp1 Cp1/lvar.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/common.cp1 Cp1/struct.cp1 Cp1/file.cp1 out/hash-table-size.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 74 | build out/compile2.cp1.c: compile Cp1/compile.cp1 Cp1/meta.cp1 Cp1/common.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/func.cp1 Cp1/struct.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/var.cp1 Cp1/assign.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/math.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/lvar.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/cvar.cp1 Cp1/bools.cp1 Cp1/call.cp1 Cp1/str.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/null.cp1 Cp1/index.cp1 Cp1/if.cp1 Cp1/switch.cp1 Cp1/loop.cp1 Cp1/continue.cp1 Cp1/break.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 out/hash-table-size.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 75 | build out/export.cp1.c: compile export.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 76 | build out/export: ld-c2 out/export.cp1.c 77 | build out/export.h: run out/export out/parse2.cp1.c 78 | build out/lex.c: re2c lex-re2c.c 79 | build out/lemon: ld-lemon lemon.c 80 | build out/cp1_parse.c out/cp1_parse.h: lemon cp1_parse.y | out/lemon 81 | build out/cp1-run: ld-c2 out/run2.cp1.c 82 | build out/parse2.cp1.c.o: c2 out/parse2.cp1.c 83 | build out/parse2.c.o: c2 parse2.c | out/export.h out/lex.c out/cp1_parse.c 84 | #build out/parse2-redef.cp1.c.o: objredef out/parse2.cp1.c.o | redefs2 85 | # redefs = redefs2 86 | build out/hashtable2.c.o: c2 hashtable2.c 87 | build out/build-crc32c.h: crc32c out/compile2.cp1.c out/parse2.cp1.c compile2.c parse2.c lex-re2c.c | bin/crc32c 88 | build out/compile2.cp1.c.o: c2 out/compile2.cp1.c | out/build-crc32c.h 89 | build out/compile2.c.o: c2 compile2.c | out/build-crc32c.h 90 | build out/cp1-parse: ld-c2 out/parse2.cp1.c.o out/parse2.c.o out/hashtable.c.o 91 | build out/cp1-compile: ld-c2 out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o 92 | #build out/cp1-compile-redef-output | redefs2: ld-c2-redef out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o out/parse2.cp1.c.o out/parse2.c.o 93 | -------------------------------------------------------------------------------- /build-qjs.ninja: -------------------------------------------------------------------------------- 1 | rule c 2 | command = clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $out -c $in -Iqjs 3 | 4 | rule ld 5 | command = clang $in -o $out -lm 6 | 7 | build bin/cp1-qjs: ld out/cp1-qjs.c.o out/quickjs.c.o out/quickjs-libc.c.o out/cutils.c.o out/libregexp.c.o out/libbf.c.o out/libunicode.c.o 8 | build out/cp1-qjs.c.o: c cp1-qjs.c 9 | build out/quickjs.c.o: c qjs/quickjs.c 10 | build out/quickjs-libc.c.o: c qjs/quickjs-libc.c 11 | build out/cutils.c.o: c qjs/cutils.c 12 | build out/libregexp.c.o: c qjs/libregexp.c 13 | build out/libbf.c.o: c qjs/libbf.c 14 | build out/libunicode.c.o: c qjs/libunicode.c 15 | -------------------------------------------------------------------------------- /build-tcc.ninja: -------------------------------------------------------------------------------- 1 | rule c 2 | command = tcc $flags -w -I. -c $in -o $out 3 | 4 | #rule objredef 5 | # command = objcopy --redefine-syms=$redefs $in $out 6 | 7 | rule ld-c 8 | command = tcc -w -I. $in -o $out $flags 9 | 10 | rule crc32c 11 | command = bin/crc32c $in $out 12 | 13 | build out/parse.cp1.c.o: c parse.cp1.c 14 | #build out/parse-redef.cp1.c.o: objredef out/parse.cp1.c.o | redefs 15 | # redefs = redefs 16 | build out/parse.c.o: c parse.c | export.h lex.c cp1_parse.c 17 | build out/compile.cp1.c.o: c compile.cp1.c 18 | build out/compile.c.o: c compile.c 19 | build bin/cp1-parse: ld-c out/parse.cp1.c.o out/parse.c.o out/hashtable.c.o | build-crc32c.h 20 | build bin/cp1-compile: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o 21 | # out/parse-redef.cp1.c.o out/parse.c.o 22 | #build bin/cp1-compile-redef-output: ld-c out/compile.cp1.c.o out/compile.c.o out/hashtable.c.o out/parse.cp1.c.o out/parse.c.o 23 | build bin/cp1-run: ld-c run.cp1.c 24 | build bin/crc32c: ld-c crc32c.c | crc32c.h 25 | build out/hashtable.c.o: c hashtable2.c 26 | 27 | rule cjs 28 | command = tcc -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -o $out -c $in -Iqjs 29 | 30 | build bin/cp1-qjs: ld-c out/cp1-qjs.c.o out/quickjs.c.o out/quickjs-libc.c.o out/cutils.c.o out/libregexp.c.o out/libbf.c.o out/libunicode.c.o 31 | flags = -lm 32 | build out/cp1-qjs.c.o: cjs cp1-qjs.c 33 | build out/quickjs.c.o: cjs qjs/quickjs.c 34 | build out/quickjs-libc.c.o: cjs qjs/quickjs-libc.c 35 | build out/cutils.c.o: cjs qjs/cutils.c 36 | build out/libregexp.c.o: cjs qjs/libregexp.c 37 | build out/libbf.c.o: cjs qjs/libbf.c 38 | build out/libunicode.c.o: cjs qjs/libunicode.c 39 | 40 | rule c2 41 | command = tcc $flags -w -DCP1_NEW -I. -c $in -o $out 42 | 43 | rule ld-c2 44 | command = tcc $flags -w -DCP1_NEW -I. $in -o $out 45 | 46 | #rule ld-c2-redef 47 | # command = gcc $flags -ggdb -O0 -Werror=format -Wno-incompatible-pointer-types -DCP1_NEW -I. $in -o $out.tmp 2> redefs2.txt || true && node redefs.js redefs2.txt redefs2 && touch $out 48 | 49 | rule re2c 50 | command = re2c --input-encoding utf8 --utf8 $in -o $out 51 | 52 | rule ld-lemon 53 | command = tcc -I. $in -o $out 54 | 55 | rule lemon 56 | restat = true 57 | command = out/lemon -dout $in 58 | 59 | rule compile 60 | command = bin/cp1-compile -w $in -c $out $flags 61 | 62 | rule run 63 | command = $in $out 64 | 65 | build out/hash-table-size: ld-c2 hashtable2.c 66 | flags = -DCP1_GET_SIZE 67 | build out/hash-table-size.cp1: run out/hash-table-size 68 | 69 | build out/token.cp1.c: compile token.cp1 | include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 70 | build out/token: ld-c2 out/token.cp1.c 71 | build out/token.cp1: run out/token out/cp1_parse.h 72 | build out/run2.cp1.c: compile Cp1/run.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 73 | build out/parse2.cp1.c: compile Cp1/parse.cp1 out/token.cp1 Cp1/break.cp1 Cp1/math.cp1 Cp1/bools.cp1 Cp1/str.cp1 Cp1/cvar.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/index.cp1 Cp1/switch.cp1 Cp1/if.cp1 Cp1/loop.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/call.cp1 Cp1/null.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/assign.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/continue.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/var.cp1 Cp1/func.cp1 Cp1/lvar.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/common.cp1 Cp1/struct.cp1 Cp1/file.cp1 out/hash-table-size.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 include/Posix/stat.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 74 | build out/compile2.cp1.c: compile Cp1/compile.cp1 Cp1/meta.cp1 Cp1/common.cp1 Cp1/rdr.cp1 Cp1/wtr.cp1 Cp1/func.cp1 Cp1/struct.cp1 Cp1/enum.cp1 Cp1/expr.cp1 Cp1/stmt.cp1 Cp1/var.cp1 Cp1/assign.cp1 Cp1/compare.cp1 Cp1/bool.cp1 Cp1/char.cp1 Cp1/math.cp1 Cp1/unary.cp1 Cp1/ref.cp1 Cp1/cast.cp1 Cp1/lvar.cp1 Cp1/fvar.cp1 Cp1/soa.cp1 Cp1/gvar.cp1 Cp1/cvar.cp1 Cp1/bools.cp1 Cp1/call.cp1 Cp1/str.cp1 Cp1/int.cp1 Cp1/size.cp1 Cp1/null.cp1 Cp1/index.cp1 Cp1/if.cp1 Cp1/switch.cp1 Cp1/loop.cp1 Cp1/continue.cp1 Cp1/break.cp1 Cp1/return.cp1 Cp1/space.cp1 Cp1/export.cp1 out/hash-table-size.cp1 Cp1/file.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/Posix/fcntl.cp1 include/LibC/stdlib.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 75 | build out/export.cp1.c: compile export.cp1 | include/LibCp1/stdout.cp1 include/LibC/stdio.cp1 include/LibC/stdlib.cp1 include/Posix/fcntl.cp1 include/Posix/unistd.cp1 include/LibC/string.cp1 bin/cp1-compile bin/cp1-parse bin/cp1-qjs 76 | build out/export: ld-c2 out/export.cp1.c 77 | build out/export.h: run out/export out/parse2.cp1.c 78 | build out/lex.c: re2c lex-re2c.c 79 | build out/lemon: ld-lemon lemon.c 80 | build out/cp1_parse.c out/cp1_parse.h: lemon cp1_parse.y | out/lemon 81 | build out/cp1-run: ld-c2 out/run2.cp1.c 82 | build out/parse2.cp1.c.o: c2 out/parse2.cp1.c 83 | build out/parse2.c.o: c2 parse2.c | out/export.h out/lex.c out/cp1_parse.c 84 | #build out/parse2-redef.cp1.c.o: objredef out/parse2.cp1.c.o | redefs2 85 | # redefs = redefs2 86 | build out/hashtable2.c.o: c2 hashtable2.c 87 | build out/build-crc32c.h: crc32c out/compile2.cp1.c out/parse2.cp1.c compile2.c parse2.c lex-re2c.c | bin/crc32c 88 | build out/compile2.cp1.c.o: c2 out/compile2.cp1.c | out/build-crc32c.h 89 | build out/compile2.c.o: c2 compile2.c | out/build-crc32c.h 90 | build out/cp1-parse: ld-c2 out/parse2.cp1.c.o out/parse2.c.o out/hashtable.c.o 91 | build out/cp1-compile: ld-c2 out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o 92 | #build out/cp1-compile-redef-output | redefs2: ld-c2-redef out/compile2.cp1.c.o out/compile2.c.o out/hashtable.c.o out/parse2.cp1.c.o out/parse2.c.o 93 | -------------------------------------------------------------------------------- /build-windows.ninja: -------------------------------------------------------------------------------- 1 | rule c 2 | command = clang -O0 -Werror=format -Wno-incompatible-pointer-types -I. -c $in -o $out $flags 3 | 4 | rule ld-c 5 | command = clang -O0 -Werror=format -Wno-incompatible-pointer-types -I. $in -o $out $flags 6 | 7 | build out/parse.cp1.c.obj: c parse.cp1.c 8 | build out/parse.c.obj: c parse.c | export.h lex.c cp1_parse.c 9 | build bin/cp1-parse.exe: ld-c out/parse.cp1.c.obj out/parse.c.obj out/hashtable.c.obj 10 | build out/compile.cp1.c.obj: c compile.cp1.c 11 | build out/compile.c.obj: c compile.c 12 | build bin/cp1-compile.exe: ld-c out/compile.cp1.c.obj out/compile.c.obj out/hashtable.c.obj 13 | build bin/cp1-run.exe: ld-c run.cp1.c 14 | build out/hashtable.c.obj: c hashtable.c 15 | 16 | rule cjs 17 | command = clang -D_GNU_SOURCE -DCONFIG_VERSION=\"2024-01-13\" -DCONFIG_BIGNUM -Wno-implicit-const-int-float-conversion -o $out -c $in -Iqjs 18 | 19 | build bin/cp1-qjs.exe: ld-c out/cp1-qjs.c.obj out/quickjs.c.obj out/quickjs-libc.c.obj out/cutils.c.obj out/libregexp.c.obj out/libbf.c.obj out/libunicode.c.obj 20 | flags = -lm -pthread 21 | build out/cp1-qjs.c.obj: cjs cp1-qjs.c 22 | build out/quickjs.c.obj: cjs qjs/quickjs.c 23 | build out/quickjs-libc.c.obj: cjs qjs/quickjs-libc.c 24 | build out/cutils.c.obj: cjs qjs/cutils.c 25 | build out/libregexp.c.obj: cjs qjs/libregexp.c 26 | build out/libbf.c.obj: cjs qjs/libbf.c 27 | build out/libunicode.c.obj: cjs qjs/libunicode.c 28 | -------------------------------------------------------------------------------- /build.ninja.py: -------------------------------------------------------------------------------- 1 | out = [] 2 | for line in open("build-template.ninja", "r"): 3 | if line.startswith(" command = clang "): continue 4 | if line.startswith(" command = gcc "): continue 5 | out.append(line) 6 | f = open("build-tcc.ninja", "wb") 7 | f.write("".join(out).encode("ascii")) 8 | f.close() 9 | 10 | out = [] 11 | for line in open("build-template.ninja", "r"): 12 | if line.startswith(" command = tcc "): continue 13 | if line.startswith(" command = gcc "): continue 14 | out.append(line) 15 | f = open("build-clang.ninja", "wb") 16 | f.write("".join(out).encode("ascii")) 17 | f.close() 18 | 19 | out = [] 20 | for line in open("build-template.ninja", "r"): 21 | if line.startswith(" command = tcc "): continue 22 | if line.startswith(" command = gcc "): continue 23 | if line.startswith(" command = clang "): 24 | line = "$flags -fsanitize=undefined -ggdb".join(line.split("$flags")) 25 | out.append(line) 26 | f = open("build-clang-debug.ninja", "wb") 27 | f.write("".join(out).encode("ascii")) 28 | f.close() 29 | 30 | out = [] 31 | for line in open("build-template.ninja", "r"): 32 | if line.startswith(" command = tcc "): continue 33 | if line.startswith(" command = gcc "): continue 34 | if line.startswith(" command = clang "): 35 | line = "$flags -O3 -flto".join(line.split("$flags")) 36 | out.append(line) 37 | f = open("build-clang-release.ninja", "wb") 38 | f.write("".join(out).encode("ascii")) 39 | f.close() 40 | 41 | out = [] 42 | for line in open("build-template.ninja", "r"): 43 | if line.startswith(" command = tcc "): continue 44 | if line.startswith(" command = clang "): continue 45 | out.append(line) 46 | f = open("build-gcc.ninja", "wb") 47 | f.write("".join(out).encode("ascii")) 48 | f.close() 49 | 50 | out = [] 51 | for line in open("build-template.ninja", "r"): 52 | if line.startswith(" command = tcc "): continue 53 | if line.startswith(" command = clang "): continue 54 | if line.startswith(" command = gcc "): 55 | line = "$flags -fsanitize=undefined -ggdb".join(line.split("$flags")) 56 | out.append(line) 57 | f = open("build-gcc-debug.ninja", "wb") 58 | f.write("".join(out).encode("ascii")) 59 | f.close() 60 | 61 | out = [] 62 | for line in open("build-template.ninja", "r"): 63 | if line.startswith(" command = tcc "): continue 64 | if line.startswith(" command = clang "): continue 65 | if line.startswith(" command = gcc "): 66 | line = "$flags -O3 -flto".join(line.split("$flags")) 67 | out.append(line) 68 | f = open("build-gcc-release.ninja", "wb") 69 | f.write("".join(out).encode("ascii")) 70 | f.close() 71 | -------------------------------------------------------------------------------- /cp1.vim: -------------------------------------------------------------------------------- 1 | syntax match Number /0u\?/ 2 | syntax match Number /[1-9][0-9]*u\?/ 3 | syntax match Number /[0-9]\+\.[0-9]\+f\?/ 4 | syntax match Number /0o[0-7]\+/ 5 | syntax match Number /0x[0-9a-fA-F]\+/ 6 | syntax match Number /#\([a-zA-Z]\|_\+[a-zA-Z0-9]\|[0-9]\)[_a-zA-Z0-9]*\(-[_a-zA-Z0-9]\+\)*/ 7 | syntax match Default /\([a-zA-Z]\|_\+[a-zA-Z0-9]\)[_a-zA-Z0-9]*\(-[_a-zA-Z0-9]\+\)*/ 8 | syntax match Structure /[A-Z][_a-zA-Z0-9]*\(-[_a-zA-Z0-9]\+\)*/ 9 | syntax match Function /\([a-zA-Z]\|_\+[a-zA-Z0-9]\)[_a-zA-Z0-9]*\(-[_a-zA-Z0-9]\+\)*[({]\@=/ 10 | syntax match Operator /\(true\|false\|null\|return\|continue\|break\|using\|if\|elif\|else\|switch\|case\|default\|var\|loop\|ref\|bool\|char\|intc\|i8\|u8\|i16\|u16\|i32\|u32\|i64\|u64\|isz\|usz\|f32\|f64\|this\|enum\|struct\|union\|meta\|:base\)[a-zA-Z0-9-_]\@!/ 11 | syntax match Operator /@\(const\|inline\|main\|case\|process\|real-name\|meta\|glc-name\|no-decl\|no-name\|no-body\|decl\|extern\|var-args\|soa-field\|cp1-name\|fall-through\|reflection\|no-cache\|aligned\|overload-get\|overload-set\|overload-math\)/ 12 | syntax match Operator /\(import\|require\)[ ]\+"\@=/ 13 | syntax match String /[ \n]\+\$[ \n]\+/ 14 | syntax match String /#\?include "[^"]*"/ 15 | syntax match String /#\?include <[^>]*>/ 16 | syntax match String /"\(\\[^\n]\|[^\\\"\n]\)*"/ 17 | syntax match String /'[-=] [^\n]*/ 18 | syntax match String /'"[^"]*"/ 19 | syntax match String /'<[^>]*>/ 20 | syntax match String /'\[[^\]]*\]/ 21 | syntax match String /'{[^}]*}/ 22 | syntax match String /'([^)]*)/ 23 | syntax match String /''[^\\]/ 24 | syntax match String /''\\[abfnrtv\\'0]/ 25 | syntax match Comment /\/\/ .*$/ 26 | syntax match Comment /^[ ]*#if(.*$/ 27 | syntax match Comment /^[ ]*#if!(.*$/ 28 | syntax match Comment /^[ ]*#endif\( .*\|\)$/ 29 | "syntax match Operator /\(;\|(\|)\|+\|,\|{\|}\|\[\|\]\)/ 30 | -------------------------------------------------------------------------------- /crc32c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "crc32c.h" 7 | 8 | int main(int argc, char** argv) { 9 | int32_t sum = 0; 10 | for (int i = 1; i < argc - 1; i++) { 11 | int fd = open(argv[i], 12 | O_RDONLY 13 | #ifdef _WIN32 14 | | O_BINARY 15 | #endif 16 | ); 17 | size_t len = lseek(fd, 0, SEEK_END); 18 | lseek(fd, 0, SEEK_SET); 19 | void* mem = malloc(len); 20 | read(fd, mem, len); 21 | close(fd); 22 | sum = crc32c(sum, mem, len); 23 | } 24 | FILE* f = fopen(argv[argc - 1], "wb"); 25 | fprintf(f, "#define _NCp1_Pbuild_crc32c_0() 0x%x\n", sum); 26 | fclose(f); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /crc32c.h: -------------------------------------------------------------------------------- 1 | // Copied from https://github.com/qemu/qemu/blob/master/util/crc32c.c 2 | /* 3 | * Castagnoli CRC32C Checksum Algorithm 4 | * 5 | * Polynomial: 0x11EDC6F41 6 | * 7 | * Castagnoli93: Guy Castagnoli and Stefan Braeuer and Martin Herrman 8 | * "Optimization of Cyclic Redundancy-Check Codes with 24 9 | * and 32 Parity Bits",IEEE Transactions on Communication, 10 | * Volume 41, Number 6, June 1993 11 | * 12 | * Copyright (c) 2013 Red Hat, Inc., 13 | * 14 | * Authors: 15 | * Jeff Cody 16 | * 17 | * Based on the Linux kernel cryptographic crc32c module, 18 | * 19 | * Copyright (c) 2004 Cisco Systems, Inc. 20 | * Copyright (c) 2008 Herbert Xu 21 | * 22 | * This program is free software; you can redistribute it and/or modify it 23 | * under the terms of the GNU General Public License as published by the Free 24 | * Software Foundation; either version 2 of the License, or (at your option) 25 | * any later version. 26 | * 27 | */ 28 | 29 | static const uint32_t crc32c_table[256] = { 30 | 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 31 | 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 32 | 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, 33 | 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, 34 | 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, 35 | 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 36 | 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 37 | 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, 38 | 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, 39 | 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, 40 | 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 41 | 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 42 | 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, 43 | 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, 44 | 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, 45 | 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 46 | 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 47 | 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, 48 | 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, 49 | 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, 50 | 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 51 | 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 52 | 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, 53 | 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, 54 | 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, 55 | 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 56 | 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 57 | 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, 58 | 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, 59 | 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, 60 | 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 61 | 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 62 | 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, 63 | 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, 64 | 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, 65 | 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 66 | 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 67 | 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, 68 | 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, 69 | 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, 70 | 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 71 | 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 72 | 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, 73 | 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, 74 | 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, 75 | 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 76 | 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 77 | 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, 78 | 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, 79 | 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, 80 | 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 81 | 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 82 | 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, 83 | 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, 84 | 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, 85 | 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 86 | 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 87 | 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, 88 | 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, 89 | 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, 90 | 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 91 | 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 92 | 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, 93 | 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L 94 | }; 95 | 96 | 97 | uint32_t crc32c(uint32_t crc, void *pdata, unsigned int length) 98 | { 99 | crc = ~crc; 100 | uint8_t* data = pdata; 101 | while (length--) { 102 | crc = crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8); 103 | } 104 | return ~crc; 105 | } 106 | -------------------------------------------------------------------------------- /examples/01-hello.cp1: -------------------------------------------------------------------------------- 1 | require "LibCp1/stdout.cp1"; 2 | using C1 = LibCp1; 3 | 4 | // Create a metaprogram with access to reflection data 5 | meta #CreateHelloFunction @reflection { 6 | using C1 = LibCp1; 7 | hello-${arg.suffix}() { 8 | C1.stdout{"Hello ${arg.suffix} from metaprogram!\n"} 9 | loop i = 0; ${arg.count}; i++ { 10 | C1.stdout{"Counting... " i ''\n} 11 | } 12 | // Do some reflection 13 | C1.stdout{"Have a struct called 'Cat'? ${'Cat' in cp1_refl.root.types}\n"} 14 | C1.stdout{"Have a struct called 'Dog'? ${'Dog' in cp1_refl.root.types}\n"} 15 | # print("Another hello world, but in compile time! " + os.now()); 16 | } 17 | } 18 | 19 | // Use the metaprogram 20 | #CreateHelloFunction{suffix:"world",count:3} 21 | #CreateHelloFunction{suffix:"five",count:5,cp1_no_cache:true} // disable caching 22 | 23 | struct Dog[bark-times:i32] { 24 | init(dog:this) { 25 | } 26 | bark(dog:this) { 27 | dog.bark-times++; 28 | C1.stdout{"arf!! " dog.bark-times "x bark\n"} 29 | } 30 | } 31 | 32 | main():intc { // intc is for C compatibility, use i32 elsewhere 33 | C1.stdout{"Hello world!\n"} 34 | hello-world(); // This calls the function from metaprogram at line 20 35 | hello-five(); // This calls the function from metaprogram at line 21 36 | 37 | // Declare a variable via function argument's type using '!' syntax 38 | // The dog variable is allocated on the stack 39 | Dog.init(dog!); 40 | dog.bark(); dog.bark(); dog.bark(); // Bark 3 times 41 | 42 | one! = 1; // '!' declares 'one' as a new variable 43 | seven! = 7; 44 | C1.stdout{one " + " seven " = " one + seven ''\n} 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /examples/02-methods.cp1: -------------------------------------------------------------------------------- 1 | require "LibCp1/stdout.cp1"; 2 | 3 | using C1 = LibCp1; 4 | 5 | struct Coord[x:i32, y:i32] { // a struct 6 | init(s:this) { // a method 7 | s.x = 0; 8 | s.y = 0; 9 | } 10 | walk(s:this, dir:Dir) { // a method 11 | dir.print(); 12 | switch dir { 13 | case #left { 14 | s.x++; 15 | } 16 | case #up { 17 | s.y++; 18 | } 19 | case #right { 20 | s.x--; 21 | } 22 | case #down { 23 | s.y--; 24 | } 25 | } 26 | } 27 | } 28 | 29 | enum Dir[#left, #up, #right, #down]:u8 { // an 8-bit enum 30 | print(d:this) { // a method 31 | switch d { 32 | case #left { 33 | C1.stdout{"Going left...\n"} 34 | } 35 | case #up { 36 | C1.stdout{"Going up...\n"} 37 | } 38 | case #right { 39 | C1.stdout{"Going right...\n"} 40 | } 41 | case #down { 42 | C1.stdout{"Going down...\n"} 43 | } 44 | } 45 | } 46 | } 47 | 48 | using i32 { // access the namespace of 32-bit int, then add a "print" and "increment" method 49 | print(i:this) { 50 | C1.stdout{"Int's value is " i "\n"} 51 | } 52 | inc(i:this&) { 53 | i++; 54 | } 55 | } 56 | main():intc { 57 | Coord.init(s!); // s is automatically declared as a coord allocated in the stack 58 | s.walk(#left); 59 | s.walk(#down); 60 | C1.stdout{"The location is at (" s.x ", " s.y ")\n"} 61 | i! = 7:i32; 62 | i.print(); 63 | i.inc(); 64 | i.print(); 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /examples/03-loops.cp1: -------------------------------------------------------------------------------- 1 | require "LibCp1/stdout.cp1"; 2 | 3 | using C1 = LibCp1; 4 | 5 | do-after-continue() { 6 | C1.stdout{"This will run after the loop 'continue's or iteratates again\n"} 7 | } 8 | 9 | main():intc { 10 | loop i = 0; { 11 | C1.stdout{"This is a forever loop unless you break;\n"} 12 | i++; 13 | if i == 5 { break; } 14 | } 15 | loop count = 1; 3; count++ { 16 | C1.stdout{"This is a loop that will run 3 times. " count "...\n"} 17 | } 18 | loop i = 0; i < 4; i++ { 19 | C1.stdout{"This is a loop that will run 4 times\n"} 20 | } 21 | loop 2 { 22 | C1.stdout{"Declaring variables are optional. This will loop two times.\n"} 23 | } 24 | loop i = 0; 3; i++; do-after-continue() { 25 | C1.stdout{"Hello\n"} 26 | if i == 1 { continue } 27 | C1.stdout{"World\n"} 28 | } 29 | var limit = 7; 30 | loop { 31 | C1.stdout{"parenthesis on loop statement is optional if you want to loop forever\n"} 32 | limit--; 33 | if limit == 0 { break; } 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /examples/04-variables.cp1: -------------------------------------------------------------------------------- 1 | require "LibCp1/stdout.cp1"; 2 | 3 | using C = LibC; 4 | using C1 = LibCp1; 5 | 6 | struct Struct[x:i32, y:i32] { 7 | init(s:this) { 8 | s.x = 0; 9 | s.y = 0; 10 | } 11 | } 12 | 13 | main():intc { 14 | an-integer! = 1; 15 | var also-an-integer:i32 = 8; 16 | 17 | var pointer-to-struct:Struct; 18 | pointer-to-struct = C.malloc(Struct[usz]); // allocate the struct on heap 19 | 20 | var pointer-to-another-struct:Struct; 21 | C.malloc-one(pointer-to-another-struct); // malloc-one automatically computes the size needed 22 | 23 | var struct-in-the-stack:Struct.; // notice the dot '.' symbol, means allocated on the stack 24 | struct-in-the-stack.x = 7; 25 | 26 | // Array of structs, and NOT an array of pointer to structs 27 | var structs:Struct.[]; 28 | C.malloc-arr(structs, 7); // allocates 7 structs 29 | 30 | // No '.' symbol after "Struct" means Array of POINTERs to structs 31 | var pointer-to-structs:Struct[]; 32 | C.malloc-arr(pointer-to-structs, 7); // which means allocate 7 pointers to struct 33 | C.malloc-one(pointer-to-structs[0]); // allocate the first struct 34 | 35 | Struct.init(another-struct-in-the-stack!); 36 | C1.stdout{"This must be zero and zero: " another-struct-in-the-stack.x ", " another-struct-in-the-stack.y ''\n} 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /examples/05-virtual.cp1: -------------------------------------------------------------------------------- 1 | // This is to emulate the C++'s virtual functions 2 | require "LibCp1/stdout.cp1"; 3 | 4 | using C1 = LibCp1; 5 | 6 | enum AnimalType[#cat, #dog]:u8; // 8-bit enum 7 | 8 | struct Animal[type:AnimalType] { // a struct with a method 9 | make-sound(a:this) { 10 | // a switch statement that collects methods that 11 | // begins with "emit-sound-" then automatically 12 | // puts a case below for each match 13 | switch.emit-sound(a) a.type { 14 | } 15 | } 16 | } 17 | 18 | // For example, in another file, you can: 19 | using Animal { 20 | emit-sound-cat(a:this) @case.emit-sound() { 21 | C1.stdout{"meow!\n"} 22 | } 23 | emit-sound-dog(a:this) @case.emit-sound() { 24 | C1.stdout{"arf!\n"} 25 | } 26 | } 27 | 28 | main(arg-c:intc, arg-v:char[][]):intc { 29 | var animal:Animal.; // create an animal object, '.' symbol allocates on stack 30 | animal.type = #cat; 31 | animal.make-sound(); 32 | animal.type = #dog; 33 | animal.make-sound(); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | To run the examples: 2 | 3 | - ../bin/cp1 run 01-hello.cp1 4 | - ../bin/cp1 run 02-methods.cp1 5 | - ../bin/cp1 run 03-loops.cp1 6 | - ../bin/cp1 run 04-variables.cp1 7 | 8 | To see the C codes of examples: 9 | - ../bin/cp1 c hello.c examples/01-hello.cp1 10 | - ../bin/cp1 c methods.c examples/02-methods.cp1 11 | - ../bin/cp1 c loops.c examples/03-loops.cp1 12 | - ../bin/cp1 c variables.c examples/04-variables.cp1 13 | -------------------------------------------------------------------------------- /export.cp1: -------------------------------------------------------------------------------- 1 | require "LibCp1/stdout.cp1"; 2 | require "LibC/stdio.cp1"; 3 | require "LibC/stdlib.cp1"; 4 | require "LibC/string.cp1"; 5 | require "Posix/fcntl.cp1"; 6 | require "Posix/unistd.cp1"; 7 | using C = LibC; 8 | using C1 = LibCp1; 9 | using X = Posix; 10 | main(arg-c:intc, arg-v:char[][]):intc { 11 | if arg-c != 3 { 12 | C.printf("Usage: %s [.c input file] [.h output file]\n", arg-v[0]); 13 | C.exit(#failure); 14 | } 15 | var in-fd; 16 | if !X.Fd.open(in-fd, arg-v[1], #rdonly) { 17 | C.printf("Cannot open file for reading: %s\n", arg-v[1]); 18 | C.exit(#failure); 19 | } 20 | in-size! = in-fd.seek(0, #end); 21 | in-fd.seek(0, #set); 22 | var in-data:char[] = C.malloc(in-size); 23 | in-fd.read(in-data, in-size); 24 | in-fd.close(); 25 | if !(&&, in-size > 0, in-data[in-size - 1] == ''\n) { 26 | C.printf("Error, file '%s' does not end with a new line\n", arg-v[1]); 27 | C.exit(#failure); 28 | } 29 | pos! = 0; 30 | get! = false; 31 | var func-name-v:char[256][]; 32 | var func-len-v:u8[256]; 33 | func-c! = 0; 34 | loop pos < in-size { 35 | start! = pos; 36 | loop { 37 | if in-data[pos] == ''\n { 38 | break; 39 | } 40 | pos++; 41 | } 42 | len! = pos - start; 43 | var line:char[] = &in-data[start]; 44 | if get { 45 | if line[0] == ''} { 46 | break; 47 | } 48 | lparen! = -1; 49 | loop i = 0; len; i++ { 50 | if line[i] == ''( { 51 | lparen = i; 52 | break; 53 | } 54 | } 55 | // C.printf("[%.*s]\n", lparen, line); 56 | func-name-v[func-c] = line; 57 | func-len-v[func-c] = lparen; 58 | func-c++; 59 | } elif (&&, len == 24, C.memcmp("void _NCp1_Pexport_0() {", line, 24) == 0) { 60 | get = true; 61 | } 62 | pos++; 63 | } 64 | out-f! = C.fopen(arg-v[2], "w"); 65 | pos = 0; 66 | indent! = 0; 67 | loop pos < in-size { 68 | start! = pos; 69 | loop { 70 | if in-data[pos] == ''\n { 71 | break; 72 | } 73 | pos++; 74 | } 75 | len! = pos - start; 76 | var line:char[] = &in-data[start]; 77 | if len > 0 { 78 | if line[len - 1] == ''{ { 79 | indent++; 80 | } elif (||, line[len - 1] == ''}, (&&, line[len - 2] == ''}, line[len - 1] == '';)) { 81 | indent--; 82 | } elif indent == 0 { 83 | if (&&, line[len - 2] == ''), line[len - 1] == '';) { 84 | lparen! = -1; 85 | loop i = 0; len; i++ { 86 | if line[i] == ''( { 87 | lparen = i; 88 | break; 89 | } 90 | } 91 | name! = lparen; 92 | loop line[name - 1] != '' { 93 | name--; 94 | } 95 | func-len! = lparen - name; 96 | var func:char[] = &line[name]; 97 | loop i = 0; func-c; i++ { 98 | if (&&, func-len == func-len-v[i], C.memcmp(func, func-name-v[i], func-len) == 0) { 99 | out-f.printf("%.*s\n", len, line); 100 | break; 101 | } 102 | } 103 | } 104 | } 105 | } 106 | pos++; 107 | } 108 | out-f.close(); 109 | return 0; 110 | } 111 | -------------------------------------------------------------------------------- /file.cp1.h: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include 3 | #endif 4 | -------------------------------------------------------------------------------- /hashtable.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "crc32c.h" 5 | 6 | #define HASH_KEY_COUNT 256 7 | #define BUCKET_SIZE 128 8 | 9 | struct key_t { 10 | struct key_t* prev; 11 | uint32_t sums[BUCKET_SIZE]; 12 | uint8_t lens[BUCKET_SIZE]; 13 | uint8_t* strs[BUCKET_SIZE]; 14 | uint32_t vals[BUCKET_SIZE]; 15 | uint8_t valc; 16 | }; 17 | 18 | struct map_t { 19 | struct key_t* keys[HASH_KEY_COUNT]; // last 20 | }; 21 | 22 | struct at_key_t { 23 | struct at_key_t* prev; 24 | uint32_t names[BUCKET_SIZE]; 25 | uint32_t parent_and_types[BUCKET_SIZE]; 26 | uint32_t vals[BUCKET_SIZE]; 27 | uint8_t valc; 28 | }; 29 | 30 | struct at_map_t { 31 | struct at_key_t* keys[HASH_KEY_COUNT]; // last 32 | }; 33 | 34 | #ifdef CP1_GET_SIZE 35 | #include 36 | int main(int argc, char** argv) { 37 | FILE* fp = fopen(argv[1], "w"); 38 | fprintf(fp, "using Cp1 {\n#hash-table-size:usz = %zu;\n}\n", sizeof(struct map_t)); 39 | fclose(fp); 40 | return 0; 41 | } 42 | #else 43 | void _NCp1_NMap_Pinit_1(struct map_t* map) { 44 | for (int i = 0; i < HASH_KEY_COUNT; i++) { 45 | map->keys[i] = NULL; 46 | } 47 | } 48 | void* qalloc(int32_t size); 49 | int32_t _NCp1_NMap_Pget_or_insert_4(struct map_t* map, uint8_t* str, uint8_t len, uint32_t val) { 50 | uint32_t sum = crc32c(0, str, len); 51 | uint8_t hk = sum & 0xff; 52 | struct key_t* last_key = map->keys[hk]; 53 | struct key_t* key = last_key; 54 | while (key != NULL) { 55 | uint8_t valc = key->valc; 56 | for (int i = 0; i < valc; i++) { 57 | if (key->sums[i] == sum && key->lens[i] == len && memcmp(str, key->strs[i], len) == 0) { 58 | return key->vals[i]; 59 | } 60 | } 61 | key = key->prev; 62 | } 63 | uint8_t* s = qalloc(len); 64 | memcpy(s, str, len); 65 | if (last_key != NULL && last_key->valc < BUCKET_SIZE) { 66 | uint8_t i = last_key->valc++; 67 | last_key->sums[i] = sum; 68 | last_key->vals[i] = val; 69 | last_key->strs[i] = s; 70 | last_key->lens[i] = len; 71 | return -1; 72 | } 73 | key = qalloc(sizeof(struct key_t)); 74 | key->prev = last_key; 75 | map->keys[hk] = key; 76 | key->sums[0] = sum; 77 | key->vals[0] = val; 78 | key->strs[0] = s; 79 | key->lens[0] = len; 80 | key->valc = 1; 81 | return -1; 82 | } 83 | void _NCp1_NAtMap_Pinit_1(struct at_map_t* map) { 84 | for (int i = 0; i < HASH_KEY_COUNT; i++) { 85 | map->keys[i] = NULL; 86 | } 87 | } 88 | int32_t _NCp1_NAtMap_Pget_or_insert_4(struct at_map_t* map, uint32_t parent_and_type, uint32_t name, uint32_t val) { 89 | uint32_t v[2]; 90 | v[0] = name; 91 | v[1] = parent_and_type; 92 | uint32_t sum = crc32c(0, (uint8_t*)v, sizeof(v)); 93 | uint8_t hk = sum & 0xff; 94 | struct at_key_t* last_key = map->keys[hk]; 95 | struct at_key_t* key = last_key; 96 | while (key != NULL) { 97 | uint8_t valc = key->valc; 98 | for (int i = 0; i < valc; i++) { 99 | if (key->names[i] == name && key->parent_and_types[i] == parent_and_type) { 100 | return key->vals[i]; 101 | } 102 | } 103 | key = key->prev; 104 | } 105 | if (last_key != NULL && last_key->valc < BUCKET_SIZE) { 106 | uint8_t i = last_key->valc++; 107 | last_key->names[i] = name; 108 | last_key->parent_and_types[i] = parent_and_type; 109 | last_key->vals[i] = val; 110 | return -1; 111 | } 112 | key = qalloc(sizeof(struct at_key_t)); 113 | key->prev = last_key; 114 | map->keys[hk] = key; 115 | key->names[0] = name; 116 | key->parent_and_types[0] = parent_and_type; 117 | key->vals[0] = val; 118 | key->valc = 1; 119 | return -1; 120 | } 121 | #endif 122 | -------------------------------------------------------------------------------- /hashtable2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "crc32c.h" 5 | 6 | #define HASH_KEY_COUNT 256 7 | #define BUCKET_SIZE 128 8 | 9 | struct key_t { 10 | struct key_t* prev; 11 | uint32_t sums[BUCKET_SIZE]; 12 | uint8_t lens[BUCKET_SIZE]; 13 | uint8_t* strs[BUCKET_SIZE]; 14 | uint32_t vals[BUCKET_SIZE]; 15 | uint8_t valc; 16 | }; 17 | 18 | struct map_t { 19 | struct key_t* keys[HASH_KEY_COUNT]; // last 20 | }; 21 | 22 | struct at_key_t { 23 | struct at_key_t* prev; 24 | uint32_t names[BUCKET_SIZE]; 25 | uint32_t parent_and_types[BUCKET_SIZE]; 26 | uint32_t vals[BUCKET_SIZE]; 27 | uint8_t valc; 28 | }; 29 | 30 | struct at_map_t { 31 | struct at_key_t* keys[HASH_KEY_COUNT]; // last 32 | }; 33 | 34 | #ifdef CP1_GET_SIZE 35 | #include 36 | int main(int argc, char** argv) { 37 | FILE* fp = fopen(argv[1], "w"); 38 | fprintf(fp, "using Cp1 {\n#hash-table-size:usz = %zu;\n}\n", sizeof(struct map_t)); 39 | fclose(fp); 40 | return 0; 41 | } 42 | #else 43 | void _NCp1_NMap_Pinit_1(struct map_t* map) { 44 | for (int i = 0; i < HASH_KEY_COUNT; i++) { 45 | map->keys[i] = NULL; 46 | } 47 | } 48 | void* qalloc(int32_t size); 49 | int32_t _NCp1_NMap_Pget_or_insert_4(struct map_t* map, uint8_t* str, uint8_t len, uint32_t val) { 50 | uint32_t sum = crc32c(0, str, len); 51 | uint8_t hk = sum & 0xff; 52 | struct key_t* last_key = map->keys[hk]; 53 | struct key_t* key = last_key; 54 | while (key != NULL) { 55 | uint8_t valc = key->valc; 56 | for (int i = 0; i < valc; i++) { 57 | if (key->sums[i] == sum && key->lens[i] == len && memcmp(str, key->strs[i], len) == 0) { 58 | return key->vals[i]; 59 | } 60 | } 61 | key = key->prev; 62 | } 63 | uint8_t* s = qalloc(len); 64 | memcpy(s, str, len); 65 | if (last_key != NULL && last_key->valc < BUCKET_SIZE) { 66 | uint8_t i = last_key->valc++; 67 | last_key->sums[i] = sum; 68 | last_key->vals[i] = val; 69 | last_key->strs[i] = s; 70 | last_key->lens[i] = len; 71 | return -1; 72 | } 73 | key = qalloc(sizeof(struct key_t)); 74 | key->prev = last_key; 75 | map->keys[hk] = key; 76 | key->sums[0] = sum; 77 | key->vals[0] = val; 78 | key->strs[0] = s; 79 | key->lens[0] = len; 80 | key->valc = 1; 81 | return -1; 82 | } 83 | void _NCp1_NAtMap_Pinit_1(struct at_map_t* map) { 84 | for (int i = 0; i < HASH_KEY_COUNT; i++) { 85 | map->keys[i] = NULL; 86 | } 87 | } 88 | int32_t _NCp1_NAtMap_Pget_or_insert_4(struct at_map_t* map, uint32_t parent_and_type, uint32_t name, uint32_t val) { 89 | uint32_t v[2]; 90 | v[0] = name; 91 | v[1] = parent_and_type; 92 | uint32_t sum = crc32c(0, (uint8_t*)v, sizeof(v)); 93 | uint8_t hk = sum & 0xff; 94 | struct at_key_t* last_key = map->keys[hk]; 95 | struct at_key_t* key = last_key; 96 | while (key != NULL) { 97 | uint8_t valc = key->valc; 98 | for (int i = 0; i < valc; i++) { 99 | if (key->names[i] == name && key->parent_and_types[i] == parent_and_type) { 100 | return key->vals[i]; 101 | } 102 | } 103 | key = key->prev; 104 | } 105 | if (last_key != NULL && last_key->valc < BUCKET_SIZE) { 106 | uint8_t i = last_key->valc++; 107 | last_key->names[i] = name; 108 | last_key->parent_and_types[i] = parent_and_type; 109 | last_key->vals[i] = val; 110 | return -1; 111 | } 112 | key = qalloc(sizeof(struct at_key_t)); 113 | key->prev = last_key; 114 | map->keys[hk] = key; 115 | key->names[0] = name; 116 | key->parent_and_types[0] = parent_and_type; 117 | key->vals[0] = val; 118 | key->valc = 1; 119 | return -1; 120 | } 121 | #endif 122 | -------------------------------------------------------------------------------- /images/helloworld-2025-02-26.5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/galileolajara/cp1/e8f66aad5d34db3201b8a43ef09658c4b1bb5c42/images/helloworld-2025-02-26.5.png -------------------------------------------------------------------------------- /include/LibC/float.cp1: -------------------------------------------------------------------------------- 1 | include { 2 | using f32 { 3 | #max:f32 @no-decl(FLT_MAX); 4 | #min = -f32#max; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /include/LibC/limits.cp1: -------------------------------------------------------------------------------- 1 | include { 2 | using u32 { 3 | #max:u32 @no-decl(UINT32_MAX); 4 | } 5 | using u64 { 6 | #max:u64 @no-decl(UINT64_MAX); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /include/LibC/math.cp1: -------------------------------------------------------------------------------- 1 | include { 2 | using C = LibC; 3 | using LibC { 4 | sqrtf(val:f32):f32 @no-decl @real-name; 5 | } 6 | using f32 { 7 | sqr(val:this):f32 @inline { 8 | return val * val; 9 | } 10 | sqrt(val:this):f32 @no-decl(sqrtf); 11 | abs(val:this):f32 @no-decl(fabsf); 12 | round(val:this):f32 @no-decl(roundf); 13 | round-i32(val:this):i32 @no-decl(lroundf); 14 | min(a:this, b:f32):f32 @no-decl(fminf); 15 | max(a:this, b:f32):f32 @no-decl(fmaxf); 16 | atan2(y:this, x:f32):f32 @no-decl(atan2f); 17 | cos(rad:this):f32 @no-decl(cosf); 18 | sin(rad:this):f32 @no-decl(sinf); 19 | floor(val:this):f32 @no-decl(floorf); 20 | ceil(val:this):f32 @no-decl(ceilf); 21 | 22 | #pi:f32 @no-decl(M_PI); 23 | radian(f:this):f32 @inline { 24 | return f * (#pi / 180.0f); 25 | } 26 | degree(f:this):f32 @inline { 27 | return f * (180.0f / #pi); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /include/LibC/stdio.cp1: -------------------------------------------------------------------------------- 1 | include { 2 | using C = LibC; 3 | using X = Posix; 4 | using LibC { 5 | printf(fmt:char @const[]):intc @var-args @no-decl @real-name; 6 | sprintf(str:char[], fmt:char @const[]):intc @var-args @no-decl @real-name; 7 | scanf(fmt:char @const[]):intc @var-args @no-decl @real-name; 8 | sscanf(str:char[], fmt:char @const[]):intc @var-args @no-decl @real-name; 9 | 10 | var in:File @no-decl(stdin); 11 | var out:File @no-decl(stdout); 12 | struct File[] @no-decl(FILE) { 13 | printf(f:this, str:char @const[]):intc @var-args @no-decl(fprintf); 14 | flush(f:this):intc @no-decl(fflush); 15 | write(f:this, buf:ref, size:usz):usz @inline { 16 | return fwrite(buf, 1, size, f); 17 | } 18 | putc(c:intc, f:this):intc @no-decl(fputc); 19 | gets(line:char[], size:intc, f:this):char[] @no-decl(fgets); 20 | close(f:this):intc @no-decl(fclose); 21 | } 22 | rename(old:char[], new:char[]):intc @no-decl @real-name; 23 | fopen(path:char[], mode:char[]):File @no-decl @real-name; 24 | fdopen(fd:X.Fd, mode:char[]):File @no-decl @real-name; 25 | fclose(f:File):intc @no-decl @real-name; 26 | fwrite(buf:ref, size1:usz, size2:usz, f:File):usz @no-decl @real-name; 27 | tempnam(dir:char[], pfx:char[]):char[] @no-decl @real-name; 28 | perror(str:char @const[]) @no-decl @real-name; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /include/LibC/stdlib.cp1: -------------------------------------------------------------------------------- 1 | include { 2 | using C = LibC; 3 | using LibC { 4 | malloc(size:usz):ref @no-decl(malloc); 5 | malloc-one(val:ref) @decl('<#define _NLibC_Pmalloc_one_1(var) var = malloc(sizeof(var[0]))>); 6 | malloc-arr(val:ref, count:usz) @decl('<#define _NLibC_Pmalloc_arr_2(var, c) var = malloc(sizeof(var[0]) * (c))>); 7 | realloc(size:ref, new-usz:usz):ref @real-name @no-decl; 8 | realloc-arr(size:ref, count:usz) @decl('<#define _NLibC_Prealloc_arr_2(var, c) var = realloc(var, sizeof(var[0]) * (c))>); 9 | realloc-memset-arr(size:ref, old-count:usz, count:usz) @decl('<#define _NLibC_Prealloc_memset_arr_3(var, oldc, c) var = realloc(var, sizeof(var[0]) * (c)); memset(var + oldc, 0, sizeof(var[0]) * (c - oldc));>); 10 | free(ptr:ref) @no-decl(free); 11 | system(command:char[]):intc @no-decl @real-name; 12 | exit(code:Exit) @real-name @no-decl; 13 | getenv(name:char[]):char[] @real-name @no-decl; 14 | realpath(pathname:char[], resolved:char[]):char[] @real-name @no-decl; 15 | atoi(str:char[]):intc @real-name @no-decl; 16 | rand():intc @real-name @no-decl; 17 | srand(seed:u32) @real-name @no-decl; 18 | enum Exit[#success, #failure]:intc; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /include/LibC/string.cp1: -------------------------------------------------------------------------------- 1 | include { 2 | using LibC { 3 | strlen(str:char[]):usz @real-name @no-decl; 4 | strcmp(s1:char[], s2:char[]):intc @real-name @no-decl; 5 | strcpy(s1:char[], s2:char[]):char[] @real-name @no-decl; 6 | strtok(s:char[], sep:char[]):char[] @real-name @no-decl; 7 | strdup(s:char[]):char[] @real-name @no-decl; 8 | strrchr(s:char[], c:intc):char[] @real-name @no-decl; 9 | memcpy(dst:ref, src:ref, n:usz):ref @real-name @no-decl; 10 | memmove(dst:ref, src:ref, n:usz):ref @real-name @no-decl; 11 | memcmp(s1:ref, s2:ref, n:usz):intc @real-name @no-decl; 12 | memset(dst:ref, c:intc, n:usz):ref @real-name @no-decl; 13 | memset(dst:ref):ref @decl('{# memset(dst, 0, sizeof(dst[0]))}); 14 | memset-arr(dst:ref, c:intc):ref @decl('{# memset(dst, 0, (c) * sizeof(dst[0]))}); 15 | 16 | strerror(e:intc):char[] @real-name @no-decl; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /include/LibC/time.cp1: -------------------------------------------------------------------------------- 1 | using LibC { 2 | include { 3 | enum ClockId[ 4 | #monotonic @no-decl @real-name(CLOCK_MONOTONIC), 5 | ]:intc; 6 | struct ITimerspec[ 7 | interval:Timespec. @real-name(it_interval), 8 | value:Timespec. @real-name(it_value), 9 | ] @no-decl(struct itimerspec); 10 | struct Timespec[ 11 | sec:u32 @real-name(tv_sec), 12 | nsec:u32 @real-name(tv_nsec), 13 | ] @no-decl(struct timespec); 14 | time(time:usz&):usz @no-decl @real-name; 15 | time():usz @inline { 16 | return time(null); 17 | } 18 | nanosleep(duration:Timespec, rem:Timespec):intc @no-decl @real-name; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /include/Posix/fcntl.cp1: -------------------------------------------------------------------------------- 1 | require "LibC/stdio.cp1"; 2 | require "Posix/stat.cp1"; 3 | include { 4 | using C = LibC; 5 | using X = Posix; 6 | using Posix { 7 | enum Fd[#in, #out, #nil = -1]:intc { 8 | open(file:this&, path:char[], flags:OpenFlags):bool @inline { 9 | fd! = X.open(path, flags); 10 | if fd != #nil { 11 | file = fd; 12 | return true; 13 | } else { 14 | return false; 15 | } 16 | } 17 | open(file:this&, path:char[], flags:OpenFlags, mode:intc):bool @inline { 18 | fd! = X.open(path, flags, mode); 19 | if fd != #nil { 20 | file = fd; 21 | return true; 22 | } else { 23 | return false; 24 | } 25 | } 26 | fopen(file:this, mode:char[]):C.File @inline { 27 | return C.fdopen(file, mode); 28 | } 29 | stat(file:this, stat:X.Stat):intc @inline { 30 | return X.fstat(file:base, stat); 31 | } 32 | } 33 | enum OpenFlags[ 34 | #rdonly @no-decl(O_RDONLY), 35 | #create @no-decl(O_CREAT), 36 | #wronly @no-decl(O_WRONLY), 37 | #binary @no-decl(O_BINARY), // For windows only 38 | #rdwr @no-decl(O_RDWR), 39 | #truncate @no-decl(O_TRUNC), 40 | #excl @no-decl(O_EXCL), 41 | ]:intc; 42 | open(path:char[], flags:OpenFlags):Fd @decl("#ifdef _WIN32\n#define _NPosix_Popen_2(p, f) open(p, f | O_BINARY)\n#else\n#define _NPosix_Popen_2(p, f) open(p, f)\n#endif"); 43 | open(path:char[], flags:OpenFlags, mode:intc):Fd @decl("#ifdef _WIN32\n#define _NPosix_Popen_3(p, f, m) open(p, f | O_BINARY, m)\n#else\n#define _NPosix_Popen_3(p, f, m) open(p, f, m)\n#endif"); 44 | close(fd:Fd):intc @real-name @no-decl; 45 | enum FcntlOp[ 46 | #getfl @no-decl(F_GETFL), 47 | #setfl @no-decl(F_SETFL), 48 | ]:intc; 49 | enum FcntlVal[ 50 | #0, 51 | #nonblock @no-decl(O_NONBLOCK), 52 | ]:intc; 53 | fcntl(fd:Fd, op:FcntlOp, val:FcntlVal):intc @no-decl @real-name; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /include/Posix/stat.cp1: -------------------------------------------------------------------------------- 1 | require "LibC/time.cp1"; 2 | include { 3 | using C = LibC; 4 | using X = Posix; 5 | using Posix { 6 | struct Stat[ 7 | mtimespec:C.Timespec. @real-name(st_mtimespec), 8 | mtim:C.Timespec. @real-name(st_mtim), 9 | ] @real-name(struct stat) @no-decl; 10 | mkdir(path:char[], mode:intc):intc @real-name @no-decl; 11 | fstat(file:intc, stat:Stat):intc @real-name @no-decl; 12 | stat(file:char[], stat:Stat):intc @real-name @no-decl; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /include/Posix/timerfd.cp1: -------------------------------------------------------------------------------- 1 | using C = LibC; 2 | using X = Posix; 3 | require "Posix/fcntl.cp1"; // For Posix.Fd 4 | include { 5 | using Posix { 6 | timerfd-create(clock-id:C.ClockId, flags:intc):X.Fd @real-name(timerfd_create); 7 | timerfd-settime(fd:X.Fd, flags:intc, timer:C.ITimerspec @const, old-timer:C.ITimerspec) @no-decl @real-name(timerfd_settime); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /include/Posix/unistd.cp1: -------------------------------------------------------------------------------- 1 | require "Posix/fcntl.cp1"; 2 | include [ 3 | #ifndef _WIN32 4 | #include 5 | #else 6 | #include 7 | #endif 8 | ] { 9 | using X = Posix; 10 | using Posix { 11 | using Fd { 12 | seek(fd:this, offset:usz, seek:Seek):isz @no-decl(lseek); 13 | read(fd:this, buf:ref, size:usz):isz @no-decl @real-name; 14 | close(fd:this):intc @no-decl @real-name; 15 | write(fd:this, buf:ref, size:usz):isz @no-decl @real-name; 16 | } 17 | enum Seek[ 18 | #set @no-decl(SEEK_SET), 19 | #end @no-decl(SEEK_END), 20 | ]:intc; 21 | seek(fd:intc, offset:usz, seek:Seek):usz @no-decl(lseek); 22 | mkstemp(template:char[]):Fd @no-decl @real-name; 23 | getcwd(buf:char[], size:usz):char[] @no-decl @real-name; 24 | getpid():intc @no-decl @real-name; 25 | unlink(path:char[]):intc @no-decl @real-name; 26 | sleep(seconds:u32):u32 @no-decl @real-name; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /parse.c: -------------------------------------------------------------------------------- 1 | #ifdef __APPLE__ 2 | #include 3 | #endif 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | struct _NCp1_NTokenDataI32 { 13 | uint32_t row; 14 | uint32_t col; 15 | int32_t id; 16 | int32_t id2; 17 | int32_t id3; 18 | }; 19 | struct _NCp1_NTokenDataF32 { 20 | uint32_t row; 21 | uint32_t col; 22 | float f32; 23 | }; 24 | struct _NCp1_NTokenDataU64 { 25 | uint32_t row; 26 | uint32_t col; 27 | uint64_t u64; 28 | }; 29 | struct _NCp1_NTokenDataIndex { 30 | int v[15]; 31 | int c; 32 | }; 33 | union _NCp1_NTokenData { 34 | struct _NCp1_NTokenDataI32 basic; 35 | struct _NCp1_NTokenDataF32 f32; 36 | struct _NCp1_NTokenDataU64 u64; 37 | struct _NCp1_NTokenDataIndex index; 38 | void* pointer; 39 | }; 40 | 41 | /* 42 | void _NCp1_Ppreprocess_init_0() { 43 | #ifdef _WIN32 44 | _NCp1_Ppreprocess_def_2("windows", 7); 45 | #endif 46 | #ifdef __APPLE__ 47 | _NCp1_Ppreprocess_def_2("apple", 5); 48 | #ifdef TARGET_OS_MAC 49 | _NCp1_Ppreprocess_def_2("macos", 5); 50 | #endif 51 | #endif 52 | #ifdef __linux__ 53 | _NCp1_Ppreprocess_def_2("linux", 5); 54 | #endif 55 | #ifdef __unix__ 56 | _NCp1_Ppreprocess_def_2("unix", 4); 57 | #endif 58 | #ifdef BSD 59 | _NCp1_Ppreprocess_def_2("bsd", 3); 60 | #endif 61 | #ifdef __FreeBSD__ 62 | _NCp1_Ppreprocess_def_2("freebsd", 7); 63 | #endif 64 | #ifdef __OpenBSD__ 65 | _NCp1_Ppreprocess_def_2("openbsd", 7); 66 | #endif 67 | #ifdef __NetBSD__ 68 | _NCp1_Ppreprocess_def_2("netbsd", 6); 69 | #endif 70 | #ifdef __DragonFly__ 71 | _NCp1_Ppreprocess_def_2("dragonfly", 9); 72 | #endif 73 | #if defined(_LP64) || defined(__LP64__) 74 | _NCp1_Ppreprocess_def_2("cpu64", 5); 75 | #endif 76 | } 77 | */ 78 | 79 | extern int _Glast_token; 80 | extern int _Glast_last_token; 81 | 82 | typedef int _NCp1_NExprI; 83 | typedef int _NCp1_NId; 84 | typedef int _NCp1_NInclude; 85 | typedef int _NCp1_NAt; 86 | typedef int8_t _NCp1_NBasicTypeId; 87 | typedef int8_t _NCp1_NUnary; 88 | typedef int8_t _NCp1_NMath; 89 | typedef int8_t _NCp1_NExprType; 90 | typedef int8_t _NCp1_NExprInt; 91 | typedef int8_t _NCp1_NNameType; 92 | typedef int8_t _NCp1_NStmtType; 93 | typedef int8_t _NCp1_NCompare; 94 | typedef int8_t _NCp1_NAssign; 95 | typedef int8_t _NCp1_NBools; 96 | typedef int _NCp1_NToken; 97 | struct _NCp1_NStmtSpace; 98 | struct _NCp1_NStmt; 99 | struct _NCp1_NExprData; 100 | #ifdef CP1_NEW 101 | #include "out/export.h" 102 | #else 103 | #include "export.h" 104 | #endif 105 | 106 | extern int _Glast_row; 107 | extern int _Glast_col; 108 | extern int _Grow; 109 | extern int _Gcol; 110 | int _Glast_row; 111 | int _Glast_col; 112 | int _Grow; 113 | int _Gcol; 114 | 115 | extern char* input_path; 116 | 117 | #ifdef CP1_NEW 118 | #include "out/cp1_parse.c" 119 | #else 120 | #include "cp1_parse.c" 121 | #endif 122 | 123 | struct cp1_lexer { 124 | const char *content; 125 | const char *start; 126 | const char *cursor; 127 | const char *marker; 128 | }; 129 | 130 | void* _NCp1_NParser_Palloc_0() { 131 | return cp1ParseAlloc(malloc); 132 | } 133 | 134 | void _NCp1_NParser_Pfree_1(void* parser) { 135 | cp1ParseFree(parser, free); 136 | } 137 | 138 | int _NCp1_Pchar_escape_value_1(char c) { 139 | switch(c) { 140 | case 'a': return '\a'; 141 | case 'b': return '\b'; 142 | case 'f': return '\f'; 143 | case 'n': return '\n'; 144 | case 'r': return '\r'; 145 | case 't': return '\t'; 146 | case 'v': return '\v'; 147 | case '\\': return '\\'; 148 | case '\'': return '\''; 149 | case '"': return '"'; 150 | case '0': return '\0'; 151 | default: 152 | printf("%s:%u:%u: Invalid escape sequence '\\%c'\n", input_path, _Grow, _Gcol, c); 153 | exit(EXIT_FAILURE); 154 | } 155 | } 156 | 157 | #ifdef CP1_NEW 158 | #include "out/lex.c" 159 | #else 160 | #include "lex.c" 161 | #endif 162 | -------------------------------------------------------------------------------- /parse2.c: -------------------------------------------------------------------------------- 1 | #ifdef __APPLE__ 2 | #include 3 | #endif 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | struct _NCp1_NTokenDataI32 { 13 | uint32_t row; 14 | uint32_t col; 15 | int32_t id; 16 | int32_t id2; 17 | int32_t id3; 18 | }; 19 | struct _NCp1_NTokenDataF32 { 20 | uint32_t row; 21 | uint32_t col; 22 | float f32; 23 | }; 24 | struct _NCp1_NTokenDataU64 { 25 | uint32_t row; 26 | uint32_t col; 27 | uint64_t u64; 28 | }; 29 | struct _NCp1_NTokenDataIndex { 30 | int v[15]; 31 | int c; 32 | }; 33 | union _NCp1_NTokenData { 34 | struct _NCp1_NTokenDataI32 basic; 35 | struct _NCp1_NTokenDataF32 f32; 36 | struct _NCp1_NTokenDataU64 u64; 37 | struct _NCp1_NTokenDataIndex index; 38 | void* pointer; 39 | }; 40 | 41 | /* 42 | void _NCp1_Ppreprocess_init_0() { 43 | #ifdef _WIN32 44 | _NCp1_Ppreprocess_def_2("windows", 7); 45 | #endif 46 | #ifdef __APPLE__ 47 | _NCp1_Ppreprocess_def_2("apple", 5); 48 | #ifdef TARGET_OS_MAC 49 | _NCp1_Ppreprocess_def_2("macos", 5); 50 | #endif 51 | #endif 52 | #ifdef __linux__ 53 | _NCp1_Ppreprocess_def_2("linux", 5); 54 | #endif 55 | #ifdef __unix__ 56 | _NCp1_Ppreprocess_def_2("unix", 4); 57 | #endif 58 | #ifdef BSD 59 | _NCp1_Ppreprocess_def_2("bsd", 3); 60 | #endif 61 | #ifdef __FreeBSD__ 62 | _NCp1_Ppreprocess_def_2("freebsd", 7); 63 | #endif 64 | #ifdef __OpenBSD__ 65 | _NCp1_Ppreprocess_def_2("openbsd", 7); 66 | #endif 67 | #ifdef __NetBSD__ 68 | _NCp1_Ppreprocess_def_2("netbsd", 6); 69 | #endif 70 | #ifdef __DragonFly__ 71 | _NCp1_Ppreprocess_def_2("dragonfly", 9); 72 | #endif 73 | #if defined(_LP64) || defined(__LP64__) 74 | _NCp1_Ppreprocess_def_2("cpu64", 5); 75 | #endif 76 | } 77 | */ 78 | 79 | extern int _Glast_token; 80 | extern int _Glast_last_token; 81 | 82 | typedef int _NCp1_NExprI; 83 | typedef int _NCp1_NId; 84 | typedef int _NCp1_NInclude; 85 | typedef int _NCp1_NAt; 86 | typedef int8_t _NCp1_NBasicTypeId; 87 | typedef int8_t _NCp1_NUnary; 88 | typedef int8_t _NCp1_NMath; 89 | typedef int8_t _NCp1_NExprType; 90 | typedef int8_t _NCp1_NExprInt; 91 | typedef int8_t _NCp1_NNameType; 92 | typedef int8_t _NCp1_NStmtType; 93 | typedef int8_t _NCp1_NCompare; 94 | typedef int8_t _NCp1_NAssign; 95 | typedef int8_t _NCp1_NBools; 96 | typedef int _NCp1_NToken; 97 | struct _NCp1_NStmtSpace; 98 | struct _NCp1_NStmt; 99 | struct _NCp1_NExprData; 100 | #ifdef CP1_NEW 101 | #include "out/export.h" 102 | #else 103 | #include "export.h" 104 | #endif 105 | 106 | extern int _Glast_row; 107 | extern int _Glast_col; 108 | extern int _Grow; 109 | extern int _Gcol; 110 | int _Glast_row; 111 | int _Glast_col; 112 | int _Grow; 113 | int _Gcol; 114 | 115 | extern char* input_path; 116 | 117 | #ifdef CP1_NEW 118 | #include "out/cp1_parse.c" 119 | #else 120 | #include "cp1_parse.c" 121 | #endif 122 | 123 | struct cp1_lexer { 124 | const char *content; 125 | const char *start; 126 | const char *cursor; 127 | const char *marker; 128 | }; 129 | 130 | void* _NCp1_NParser_Palloc_0() { 131 | return cp1ParseAlloc(malloc); 132 | } 133 | 134 | void _NCp1_NParser_Pfree_1(void* parser) { 135 | cp1ParseFree(parser, free); 136 | } 137 | 138 | int _NCp1_Pchar_escape_value_1(char c) { 139 | switch(c) { 140 | case 'a': return '\a'; 141 | case 'b': return '\b'; 142 | case 'f': return '\f'; 143 | case 'n': return '\n'; 144 | case 'r': return '\r'; 145 | case 't': return '\t'; 146 | case 'v': return '\v'; 147 | case '\\': return '\\'; 148 | case '\'': return '\''; 149 | case '"': return '"'; 150 | case '0': return '\0'; 151 | default: 152 | printf("%s:%u:%u: Invalid escape sequence '\\%c'\n", input_path, _Grow, _Gcol, c); 153 | exit(EXIT_FAILURE); 154 | } 155 | } 156 | 157 | #ifdef CP1_NEW 158 | #include "out/lex.c" 159 | #else 160 | #include "lex.c" 161 | #endif 162 | -------------------------------------------------------------------------------- /qjs/libregexp-opcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifdef DEF 26 | 27 | DEF(invalid, 1) /* never used */ 28 | DEF(char, 3) 29 | DEF(char32, 5) 30 | DEF(dot, 1) 31 | DEF(any, 1) /* same as dot but match any character including line terminator */ 32 | DEF(line_start, 1) 33 | DEF(line_end, 1) 34 | DEF(goto, 5) 35 | DEF(split_goto_first, 5) 36 | DEF(split_next_first, 5) 37 | DEF(match, 1) 38 | DEF(save_start, 2) /* save start position */ 39 | DEF(save_end, 2) /* save end position, must come after saved_start */ 40 | DEF(save_reset, 3) /* reset save positions */ 41 | DEF(loop, 5) /* decrement the top the stack and goto if != 0 */ 42 | DEF(push_i32, 5) /* push integer on the stack */ 43 | DEF(drop, 1) 44 | DEF(word_boundary, 1) 45 | DEF(not_word_boundary, 1) 46 | DEF(back_reference, 2) 47 | DEF(backward_back_reference, 2) /* must come after back_reference */ 48 | DEF(range, 3) /* variable length */ 49 | DEF(range32, 3) /* variable length */ 50 | DEF(lookahead, 5) 51 | DEF(negative_lookahead, 5) 52 | DEF(push_char_pos, 1) /* push the character position on the stack */ 53 | DEF(check_advance, 1) /* pop one stack element and check that it is different from the character position */ 54 | DEF(prev, 1) /* go to the previous char */ 55 | DEF(simple_greedy_quant, 17) 56 | 57 | #endif /* DEF */ 58 | -------------------------------------------------------------------------------- /qjs/libregexp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIBREGEXP_H 25 | #define LIBREGEXP_H 26 | 27 | #include 28 | 29 | #include "libunicode.h" 30 | 31 | #define LRE_BOOL int /* for documentation purposes */ 32 | 33 | #define LRE_FLAG_GLOBAL (1 << 0) 34 | #define LRE_FLAG_IGNORECASE (1 << 1) 35 | #define LRE_FLAG_MULTILINE (1 << 2) 36 | #define LRE_FLAG_DOTALL (1 << 3) 37 | #define LRE_FLAG_UTF16 (1 << 4) 38 | #define LRE_FLAG_STICKY (1 << 5) 39 | #define LRE_FLAG_INDICES (1 << 6) /* Unused by libregexp, just recorded. */ 40 | 41 | #define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */ 42 | 43 | uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, 44 | const char *buf, size_t buf_len, int re_flags, 45 | void *opaque); 46 | int lre_get_capture_count(const uint8_t *bc_buf); 47 | int lre_get_flags(const uint8_t *bc_buf); 48 | const char *lre_get_groupnames(const uint8_t *bc_buf); 49 | int lre_exec(uint8_t **capture, 50 | const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, 51 | int cbuf_type, void *opaque); 52 | 53 | int lre_parse_escape(const uint8_t **pp, int allow_utf16); 54 | LRE_BOOL lre_is_space(int c); 55 | 56 | /* must be provided by the user */ 57 | LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size); 58 | void *lre_realloc(void *opaque, void *ptr, size_t size); 59 | 60 | /* JS identifier test */ 61 | extern uint32_t const lre_id_start_table_ascii[4]; 62 | extern uint32_t const lre_id_continue_table_ascii[4]; 63 | 64 | static inline int lre_js_is_ident_first(int c) 65 | { 66 | if ((uint32_t)c < 128) { 67 | return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1; 68 | } else { 69 | #ifdef CONFIG_ALL_UNICODE 70 | return lre_is_id_start(c); 71 | #else 72 | return !lre_is_space(c); 73 | #endif 74 | } 75 | } 76 | 77 | static inline int lre_js_is_ident_next(int c) 78 | { 79 | if ((uint32_t)c < 128) { 80 | return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1; 81 | } else { 82 | /* ZWNJ and ZWJ are accepted in identifiers */ 83 | #ifdef CONFIG_ALL_UNICODE 84 | return lre_is_id_continue(c) || c == 0x200C || c == 0x200D; 85 | #else 86 | return !lre_is_space(c) || c == 0x200C || c == 0x200D; 87 | #endif 88 | } 89 | } 90 | 91 | #undef LRE_BOOL 92 | 93 | #endif /* LIBREGEXP_H */ 94 | -------------------------------------------------------------------------------- /qjs/libunicode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Unicode utilities 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIBUNICODE_H 25 | #define LIBUNICODE_H 26 | 27 | #include 28 | 29 | #define LRE_BOOL int /* for documentation purposes */ 30 | 31 | /* define it to include all the unicode tables (40KB larger) */ 32 | #define CONFIG_ALL_UNICODE 33 | 34 | #define LRE_CC_RES_LEN_MAX 3 35 | 36 | typedef enum { 37 | UNICODE_NFC, 38 | UNICODE_NFD, 39 | UNICODE_NFKC, 40 | UNICODE_NFKD, 41 | } UnicodeNormalizationEnum; 42 | 43 | int lre_case_conv(uint32_t *res, uint32_t c, int conv_type); 44 | int lre_canonicalize(uint32_t c, BOOL is_unicode); 45 | LRE_BOOL lre_is_cased(uint32_t c); 46 | LRE_BOOL lre_is_case_ignorable(uint32_t c); 47 | 48 | /* char ranges */ 49 | 50 | typedef struct { 51 | int len; /* in points, always even */ 52 | int size; 53 | uint32_t *points; /* points sorted by increasing value */ 54 | void *mem_opaque; 55 | void *(*realloc_func)(void *opaque, void *ptr, size_t size); 56 | } CharRange; 57 | 58 | typedef enum { 59 | CR_OP_UNION, 60 | CR_OP_INTER, 61 | CR_OP_XOR, 62 | } CharRangeOpEnum; 63 | 64 | void cr_init(CharRange *cr, void *mem_opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); 65 | void cr_free(CharRange *cr); 66 | int cr_realloc(CharRange *cr, int size); 67 | int cr_copy(CharRange *cr, const CharRange *cr1); 68 | 69 | static inline int cr_add_point(CharRange *cr, uint32_t v) 70 | { 71 | if (cr->len >= cr->size) { 72 | if (cr_realloc(cr, cr->len + 1)) 73 | return -1; 74 | } 75 | cr->points[cr->len++] = v; 76 | return 0; 77 | } 78 | 79 | static inline int cr_add_interval(CharRange *cr, uint32_t c1, uint32_t c2) 80 | { 81 | if ((cr->len + 2) > cr->size) { 82 | if (cr_realloc(cr, cr->len + 2)) 83 | return -1; 84 | } 85 | cr->points[cr->len++] = c1; 86 | cr->points[cr->len++] = c2; 87 | return 0; 88 | } 89 | 90 | int cr_union1(CharRange *cr, const uint32_t *b_pt, int b_len); 91 | 92 | static inline int cr_union_interval(CharRange *cr, uint32_t c1, uint32_t c2) 93 | { 94 | uint32_t b_pt[2]; 95 | b_pt[0] = c1; 96 | b_pt[1] = c2 + 1; 97 | return cr_union1(cr, b_pt, 2); 98 | } 99 | 100 | int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, 101 | const uint32_t *b_pt, int b_len, int op); 102 | 103 | int cr_invert(CharRange *cr); 104 | 105 | int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode); 106 | 107 | #ifdef CONFIG_ALL_UNICODE 108 | 109 | LRE_BOOL lre_is_id_start(uint32_t c); 110 | LRE_BOOL lre_is_id_continue(uint32_t c); 111 | 112 | int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, 113 | UnicodeNormalizationEnum n_type, 114 | void *opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); 115 | 116 | /* Unicode character range functions */ 117 | 118 | int unicode_script(CharRange *cr, 119 | const char *script_name, LRE_BOOL is_ext); 120 | int unicode_general_category(CharRange *cr, const char *gc_name); 121 | int unicode_prop(CharRange *cr, const char *prop_name); 122 | 123 | #endif /* CONFIG_ALL_UNICODE */ 124 | 125 | #undef LRE_BOOL 126 | 127 | #endif /* LIBUNICODE_H */ 128 | -------------------------------------------------------------------------------- /qjs/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Linux klist like system 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIST_H 25 | #define LIST_H 26 | 27 | #ifndef NULL 28 | #include 29 | #endif 30 | 31 | struct list_head { 32 | struct list_head *prev; 33 | struct list_head *next; 34 | }; 35 | 36 | #define LIST_HEAD_INIT(el) { &(el), &(el) } 37 | 38 | /* return the pointer of type 'type *' containing 'el' as field 'member' */ 39 | #define list_entry(el, type, member) container_of(el, type, member) 40 | 41 | static inline void init_list_head(struct list_head *head) 42 | { 43 | head->prev = head; 44 | head->next = head; 45 | } 46 | 47 | /* insert 'el' between 'prev' and 'next' */ 48 | static inline void __list_add(struct list_head *el, 49 | struct list_head *prev, struct list_head *next) 50 | { 51 | prev->next = el; 52 | el->prev = prev; 53 | el->next = next; 54 | next->prev = el; 55 | } 56 | 57 | /* add 'el' at the head of the list 'head' (= after element head) */ 58 | static inline void list_add(struct list_head *el, struct list_head *head) 59 | { 60 | __list_add(el, head, head->next); 61 | } 62 | 63 | /* add 'el' at the end of the list 'head' (= before element head) */ 64 | static inline void list_add_tail(struct list_head *el, struct list_head *head) 65 | { 66 | __list_add(el, head->prev, head); 67 | } 68 | 69 | static inline void list_del(struct list_head *el) 70 | { 71 | struct list_head *prev, *next; 72 | prev = el->prev; 73 | next = el->next; 74 | prev->next = next; 75 | next->prev = prev; 76 | el->prev = NULL; /* fail safe */ 77 | el->next = NULL; /* fail safe */ 78 | } 79 | 80 | static inline int list_empty(struct list_head *el) 81 | { 82 | return el->next == el; 83 | } 84 | 85 | #define list_for_each(el, head) \ 86 | for(el = (head)->next; el != (head); el = el->next) 87 | 88 | #define list_for_each_safe(el, el1, head) \ 89 | for(el = (head)->next, el1 = el->next; el != (head); \ 90 | el = el1, el1 = el->next) 91 | 92 | #define list_for_each_prev(el, head) \ 93 | for(el = (head)->prev; el != (head); el = el->prev) 94 | 95 | #define list_for_each_prev_safe(el, el1, head) \ 96 | for(el = (head)->prev, el1 = el->prev; el != (head); \ 97 | el = el1, el1 = el->prev) 98 | 99 | #endif /* LIST_H */ 100 | -------------------------------------------------------------------------------- /qjs/quickjs-libc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS C library 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef QUICKJS_LIBC_H 25 | #define QUICKJS_LIBC_H 26 | 27 | #include 28 | #include 29 | 30 | #include "quickjs.h" 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name); 37 | JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name); 38 | void js_std_add_helpers(JSContext *ctx, int argc, char **argv); 39 | void js_std_loop(JSContext *ctx); 40 | void js_std_init_handlers(JSRuntime *rt); 41 | void js_std_free_handlers(JSRuntime *rt); 42 | void js_std_dump_error(JSContext *ctx); 43 | uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename); 44 | int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val, 45 | JS_BOOL use_realpath, JS_BOOL is_main); 46 | JSModuleDef *js_module_loader(JSContext *ctx, 47 | const char *module_name, void *opaque); 48 | void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, 49 | int flags); 50 | void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise, 51 | JSValueConst reason, 52 | JS_BOOL is_handled, void *opaque); 53 | void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt)); 54 | 55 | #ifdef __cplusplus 56 | } /* extern "C" { */ 57 | #endif 58 | 59 | #endif /* QUICKJS_LIBC_H */ 60 | -------------------------------------------------------------------------------- /system2.h: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include 3 | int system2(char* cmd) { 4 | STARTUPINFO si; 5 | PROCESS_INFORMATION pi; 6 | ZeroMemory(&si, sizeof(si)); 7 | si.cb = sizeof(si); 8 | ZeroMemory(&pi, sizeof(pi)); 9 | 10 | // Change this to any executable you want to run 11 | // LPCSTR application = "notepad.exe"; 12 | 13 | // Create the process 14 | if (!CreateProcess( 15 | NULL, // Application name (NULL means command line contains it) 16 | cmd, // Command line 17 | NULL, // Process handle not inheritable 18 | NULL, // Thread handle not inheritable 19 | FALSE, // Set handle inheritance to FALSE 20 | 0, // No creation flags 21 | NULL, // Use parent's environment block 22 | NULL, // Use parent's starting directory 23 | &si, // Pointer to STARTUPINFO 24 | &pi) // Pointer to PROCESS_INFORMATION 25 | ) { 26 | printf("Failed to create process. Error: %lu\n", GetLastError()); 27 | return 1; 28 | } 29 | 30 | // printf("Process created with PID: %lu\n", pi.dwProcessId); 31 | 32 | // Wait for the child process to exit 33 | WaitForSingleObject(pi.hProcess, INFINITE); 34 | 35 | // Get exit code of the process 36 | DWORD exitCode; 37 | if (GetExitCodeProcess(pi.hProcess, &exitCode)) { 38 | // printf("Process exited with code: %lu\n", exitCode); 39 | } else { 40 | exitCode = 1; 41 | printf("Failed to get exit code. Error: %lu\n", GetLastError()); 42 | } 43 | 44 | // Close process and thread handles 45 | CloseHandle(pi.hProcess); 46 | CloseHandle(pi.hThread); 47 | 48 | return exitCode; 49 | } 50 | #else 51 | int system2(char* cmd) { 52 | return system(cmd); 53 | } 54 | #endif 55 | -------------------------------------------------------------------------------- /token.cp1: -------------------------------------------------------------------------------- 1 | import "LibC/stdio.cp1"; 2 | import "LibC/stdlib.cp1"; 3 | import "LibC/string.cp1"; 4 | import "Posix/fcntl.cp1"; 5 | import "Posix/unistd.cp1"; 6 | using C = LibC; 7 | using X = Posix; 8 | main(arg-c:intc, arg-v:char[][]):intc { 9 | if arg-c != 3 { 10 | C.printf("Usage: %s [.h input file] [.cp1 output file]\n", arg-v[0]); 11 | C.exit(#failure); 12 | } 13 | var in-fd; 14 | if !X.Fd.open(in-fd, arg-v[1], #rdonly) { 15 | C.printf("Cannot open file for reading: %s\n", arg-v[1]); 16 | C.exit(#failure); 17 | } 18 | in-size! = in-fd.seek(0, #end); 19 | in-fd.seek(0, #set); 20 | var in-data:char[] = C.malloc(in-size); 21 | in-fd.read(in-data, in-size); 22 | in-fd.close(); 23 | if !(&&, in-size > 0, in-data[in-size - 1] == ''\n) { 24 | C.printf("Error, file '%s' does not end with a new line\n", arg-v[1]); 25 | C.exit(#failure); 26 | } 27 | pos! = 0; 28 | out-f! = C.fopen(arg-v[2], "w"); 29 | out-f.printf( 30 | '= using Cp1 { 31 | '= enum Token[ 32 | '= #nil, 33 | ); 34 | loop pos < in-size { 35 | start! = pos; 36 | loop { 37 | if in-data[pos] == ''\n { 38 | break; 39 | } 40 | pos++; 41 | } 42 | len! = pos - start; 43 | var line:char[] = &in-data[start]; 44 | var push:char[64]; 45 | push-c! = 0; 46 | loop i = 18; len - 18; i++ { 47 | if (&&, line[i] >= ''0, line[i] <= ''9) { 48 | push[push-c++] = line[i]; 49 | } elif (&&, line[i] >= ''a, line[i] <= ''z) { 50 | push[push-c++] = line[i]; 51 | } elif (&&, line[i] >= ''A, line[i] <= ''Z) { 52 | push[push-c++] = line[i] + (''a - ''A); 53 | } elif line[i] == ''_ { 54 | push[push-c++] = ''-; 55 | } else { 56 | break; 57 | } 58 | } 59 | out-f.printf("#%.*s,\n", push-c, push); 60 | pos++; 61 | } 62 | out-f.printf( 63 | '= ]:intc { 64 | '= cp1-name(e:this):char[] @cp1-name; 65 | '= } 66 | '= } 67 | ); 68 | out-f.close(); 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /upgrade.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cp compile2.c compile.c 3 | cp parse2.c parse.c 4 | cp out/export.h export.h 5 | cp out/lex.c lex.c 6 | cp out/cp1_parse.c cp1_parse.c 7 | cp out/parse2.cp1.c parse.cp1.c 8 | cp out/compile2.cp1.c compile.cp1.c 9 | cp out/run2.cp1.c run.cp1.c 10 | cp out/build-crc32c.h build-crc32c.h 11 | cp hashtable2.c hashtable.c 12 | rm -rf cp1-tmp-* out bin/cp1-parse bin/cp1-run bin/cp1-compile bin/cp1-qjs 13 | --------------------------------------------------------------------------------