############## # TEXT UTILS # ############## /; parse_meta (~uint8 str, int idx) [uint8] /; if (str{idx} == 'n') return '\n' ;; else if (str{idx} == '0') return 0 ;/ return str{idx} ;/ /; unquote_char (~uint8 str) [uint8] int l = cstr_len(str) /; if (l < 3) return 0 ;; else if (str{1} == '\\') return parse_meta(str, 2) ;/ return str{1} ;/ /; unquote_string (~uint8 str) [~uint8] ~uint8 out = _alloc(1) out{0} = 0 int ln = 0 int l = cstr_len(str) /; loop (int i = 1; i < l - 1) [i++] /; if (str{i} == '\\') out{ln} = parse_meta(str, i + 1) ;; else out{ln} = str{i} ;/ out = _realloc(out, ln + 2) out{ln + 1} = 0 ln++ ;/ return out ;/ {}uint8 e_str_parse = "[TNSLC] [ERROR] Error when parsing int from string. %d\n\0" /; str_to_int (~uint8 str) [int] int out = 0 int l = cstr_len(str) /; loop (int i = 0; i < l) [i++] uint8 c = str{i} /; if (c < '0' || c > '9') _print_num(~e_str_parse{0}, c) _printf(~e_noquit{0}) break ;; else out = out * 10 out = out + c - '0' ;/ ;/ return out ;/ {}uint8 w_method_guard = "_#" {}uint8 w_enum_guard = "__#" #################### # FIND/PARSE UTILS # #################### # finds the closing delim in a vector of tokens {}uint8 e_dmiss = "[TNSLC] [ERROR] Delimiter missmatch\n\0" /; matching_delim (Vector v, int c) [int] ~Token cur cur = v.get(c) uint8 op /; if (cur`.data{0} == '(') op = ')' ;; else if (cur`.data{0} == '[') op = ']' ;; else if (cur`.data{0} == '{') op = '}' ;; else op = ';' ;/ int p, b, s, f p = 0 # Parens b = 0 # Braces s = 0 # Squiggly Braces f = 0 # Funcs /; loop (c++; cur < v.num_el) [c++] cur = v.get(c) /; if (cur`._type !== TOKEN_TYPE.DELIMITER) continue ;/ uint8 first = cur`.data{0} # Increments /; if (first == '(') p++ continue ;; else if (first == '[') b++ continue ;; else if (first == '{') s++ continue ;; else if (first == '/') f++ continue ;/ # Check end /; if (first == op) /; if (p == 0 && b == 0 && s == 0 && f == 0) return c ;/ ;/ # Decrement /; if (first == ')') p-- ;; else if (first == ']') b-- ;; else if (first == '}') s-- ;; else if (first == ';') /; if (cur`.data{1} == '/') f-- ;/ ;/ # Mismatch /; if (p < 0 || b < 0 || s < 0 || f < 0) _printf(~e_dmiss{0}) _printf(~e_noquit{0}) ;/ ;/ return 0 - 1 ;/ # Entrypoint for round two /; round_two (Path in, ~Module m) [CompData] CompData out out.start() return out ;/ {}uint8 e_circular = "[TNSLC] [ERROR] Circular struct definition detected in structs:\n\0" {}uint8 e_tc_nl = "\n\0" {}uint8 e_noquit = "[TNSLC] [UB] PRE-ALPHA VERSION OF COMPILER UNABLE TO EXIT! UNDEFINED BEHAVIOUR AHEAD\n\0" # Structure sizing for the first round /; size_struct (~Type t, ~Module m) /; if (t`.s !== 0) return ;/ t`.s = 0 - 1 int s = 0 ~Variable mb ~Module mbm ~Type mbt /; loop (int i = 0; i < t`.members.num_el) [i++] mb = t`.members.get(i) mbt = ~mb`.data_type /; if (mbt`.ptr_chain.num_el > 0) s = s + 8 ;; else if (mbt`.s > 0) s = s + mbt`.s ;; else if (mbt`.s == 0) Vector v v.start(8) v.push(~mbt`.name) mbm = mbt`.mod ~Type tmp tmp = mbm`._find_type(v, 0) size_struct(tmp, mbm) mbt`.s = tmp`.s s = s + tmp`.s v._del() ;; else if (mbt`.s < 0) _printf(~e_circular{0}) _printf(t`.name) _printf(~e_tc_nl{0}) _printf(mbt`.name) _printf(~e_tc_nl{0}) _printf(~e_noquit{0}) ;/ ;/ t`.s = s ;/ /; flush_structs (~Module m) ~Type t /; loop(int i = 0; i < m`.typ.num_el) [i++] t = m`.typ.get(i) size_struct(t, m) ;/ ~Module s /; loop(int i = 0; i < m`.sub.num_el) [i++] s = m`.sub.get(i) flush_structs(s) ;/ ;/ # Parses a struct (and skips that many tokens) /; create_struct (Vector v, ~int c) [Type] ;/ /; create_module (~uint8 name, bool e, bool m) [Module] Module out out.start() out.name ;/ {}uint8 r1_export = "export\0" {}uint8 r1_module = "module\0" {}uint8 r1_struct = "struct\0" {}uint8 r1_method = "method\0" /; round_one (Path in, ~Module root) ~uint8 pth = in.full_path() Vector v = tokenize_file(pth) _delete(pth) ~Token cur /; loop (int i = 0; i < v.num_el) [i++] cur = v.get(i) /; if(cstr_eq(cur`.data, ~r1_struct{0})) ;/ ;/ flush_structs(root) ;/ /; compile (Path in, out) Module root root.start() root.exp = true round_one(in, ~root) CompData dat = round_two(in, ~root) ~void fd = out.open_write() dat.write_file(fd) _close_file(fd) ;/