############## # TEXT UTILS # ############## {}uint8 e_tc_nl = "\n\0" {}uint8 e_noquit = "[TNSLC] [UB] PRE-ALPHA VERSION OF COMPILER UNABLE TO EXIT! UNDEFINED BEHAVIOUR AHEAD\n\0" {}uint8 e_unknown_meta = "[TNSLC] [WARNING] Unknown meta character '%c'!\n\0" /; parse_meta (~uint8 str, int idx) [uint8] uint8 c = str{idx} /; if (c == 'n') return '\n' ;; else if (c == 'r') return '\r' ;; else if (c == '\\') return '\\' ;; else if (c == '"') return '"' ;; else if (c == '\'') return '\'' ;; else if (c == '0') return 0 ;/ _print_num(~e_unknown_meta{0}, c) _printf(~e_noquit{0}) return c ;/ /; 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) i++ ;; 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 = "_#\0" {}uint8 w_enum_guard = "__#\0" #################### # 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, first first = cur`.data{0} /; if (first == '(') op = ')' ;; else if (first == '[') op = ']' ;; else if (first == '{') 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 ;/ 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 == ';') first = cur`.data{1} /; if (first == '/') 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" # 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) ;/ ;/ /; round_one_file (Path in, ~Module root) ~uint8 pth = in.full_path() Vector v = tokenize_file(pth) _delete(pth) # round_one_tokens(in, v, root, 0, v.num_el) # Clean up tokens ~Token t /; loop (int i = 0; i < v.num_el) [i++] t = v.get(i) _delete(t`.data) ;/ ;/ /; compile (Path in, out) Module root root.start() root.exp = true # round_one_file(in, ~root) # flush_structs(root) # CompData dat = round_two(in, ~root) ~void fd = out.open_write() dat.write_file(fd) _close_file(fd) ;/