summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/help.txt2
-rw-r--r--docs/stats.txt4
-rw-r--r--docs/version.txt2
-rw-r--r--examples/all-examples.txt589
-rwxr-xr-xfypebin278432 -> 288064 bytes
-rw-r--r--src/build.h2
-rw-r--r--src/core/functions.c961
-rw-r--r--tags50
8 files changed, 873 insertions, 737 deletions
diff --git a/docs/help.txt b/docs/help.txt
index 06b1017..f4a8e65 100644
--- a/docs/help.txt
+++ b/docs/help.txt
@@ -1,4 +1,4 @@
-Fype Superalpha Build 9686
+Fype Superalpha Build 9691
(c) Paul C. Buetow (2005 - 2008) <fype@dev.buetow.org>
-e Executes given code string (see synopses)
-h Prints this help
diff --git a/docs/stats.txt b/docs/stats.txt
index 190942c..fdb7486 100644
--- a/docs/stats.txt
+++ b/docs/stats.txt
@@ -1,6 +1,6 @@
make[1]: Entering directory '/home/paul/git/fype'
===> Num of C source files : 46
-===> Num of C source lines : 8602
+===> Num of C source lines : 8686
===> Num of Fype source examples : 19
-===> Num of Fype source lines : 822
+===> Num of Fype source lines : 883
make[1]: Leaving directory '/home/paul/git/fype'
diff --git a/docs/version.txt b/docs/version.txt
index 0087354..e0f6705 100644
--- a/docs/version.txt
+++ b/docs/version.txt
@@ -1 +1 @@
-Fype Superalpha Build 9686
+Fype Superalpha Build 9691
diff --git a/examples/all-examples.txt b/examples/all-examples.txt
index 5349073..0ca0393 100644
--- a/examples/all-examples.txt
+++ b/examples/all-examples.txt
@@ -493,329 +493,390 @@ assert say integer double string put say neg 12; # Nonsense but working :)
#*
- * Fype uber-example: exercises every language feature.
- * Every assertion must pass for the script to exit cleanly.
+ * Student Score Report — Fype uber-example
+ *
+ * Analyses a class of ten exam scores (0-100) and produces a brief
+ * statistical summary. Every Fype language feature is exercised in
+ * service of the analysis; all assertions must pass for the script
+ * to exit cleanly.
*#
-# ─── 1. COMMENTS ─────────────────────────────────────────────────────────────
+# ─── DATASET ───────────────────────────────────────────────────────────────
+# Ten student exam scores. We will compute sum, average, band counts, etc.
+my scores = [72, 45, 89, 91, 55, 78, 63, 100, 48, 82];
+my N = 10; # number of students
+my PASS = 60; # minimum score for a pass
+my DIST = 80; # minimum score for a distinction
-# Single-line comment — ignored completely.
+# ─── 1. COMMENTS ───────────────────────────────────────────────────────────
-#*
- * Block comment: also ignored.
- *#
+# Single-line comment — ignored.
+#* Block comment — also ignored. *#
-# Inline block comment inside an expression:
-my commentsok = 1 #* this is ignored *# + 1;
-assert 2 == say commentsok;
+# Inline block comment inside an expression — the #* *# part is discarded:
+my ok = 1 #* invisible *# + 0;
+assert 1 == ok;
-# ─── 2. VARIABLES AND BASIC ARITHMETIC ───────────────────────────────────────
+# ─── 2. BASIC ARITHMETIC AND VARIABLES ─────────────────────────────────────
-# Multiple declarations on one line; bay gets the default value 0
-my x = 10, y = 3, bay;
-assert 0 == say bay;
-assert 13 == say x + y;
-assert 7 == say x - y;
-assert 30 == say x * y;
-assert 3 == say x / y; # integer division truncates toward zero
+# Multiple declarations on one line; band defaults to 0.
+my a = 10, b = 3, band;
+assert 0 == say band;
+assert 13 == say a + b;
+assert 7 == say a - b;
+assert 30 == say a * b;
+assert 3 == say a / b; # integer division truncates toward zero
assert 10 == say 2 * (4 + 2) - 2;
assert 10 == say (8 / 2) + 2 * 3;
-x = x + 1;
-assert 11 == say x;
-
-# ─── 3. NEGATION AND NOT ──────────────────────────────────────────────────────
-
-assert 5 == say neg neg 5;
-assert 0 == say neg neg 0;
-assert (neg 1) == (say neg not 0); # not 0 => 1, neg 1 => -1
-
-# ─── 4. INCREMENT / DECREMENT ────────────────────────────────────────────────
-
-my counter = 5;
-incr counter;
-assert 6 == say counter;
-decr counter;
-decr counter;
-assert 4 == say counter;
-
-# ─── 5. TYPE CONVERSION ───────────────────────────────────────────────────────
-
-assert 2 == say integer 2.8; # truncates toward zero
-assert 1 == say double 1; # 1.0 compared as 1
-assert 14 == say 1 + string 13; # "13" coerced to integer 13
-assert 5 == say "10 bla" / 2; # leading digits extracted
-
-# ─── 6. STRING ARITHMETIC ────────────────────────────────────────────────────
-
-assert 46 == say "12" + "34"; # "12"->12 + "34"->34 = 46
-assert 1231 == say "1234" - "3"; # 1234 - 3 = 1231
-assert 5 == say "10 bla" / 2;
-
-# ─── 7. COMPARISON OPERATORS ─────────────────────────────────────────────────
-
-assert 1 == (put 5 > 3); assert 0 == (say 5 > 5);
-assert 1 == (put 5 >= 5); assert 0 == (say 4 >= 5);
-assert 1 == (put 3 < 5); assert 0 == (say 5 < 5);
-assert 1 == (put 3 <= 5); assert 0 == (say 6 <= 5);
-assert 1 == (put 5 == 5); assert 0 == (say 4 == 5);
-assert 1 == (put 5 != 4); assert 0 == (say 5 != 5);
-
-# ─── 8. BITWISE OPERATORS ────────────────────────────────────────────────────
-
-assert 1 == say (5 and 3); # 0b101 & 0b011 = 0b001 = 1
-assert 7 == say (5 or 2); # 0b101 | 0b010 = 0b111 = 7
-assert 6 == say (5 xor 3); # 0b101 ^ 0b011 = 0b110 = 6
-assert 8 == say (2 :< 2); # 2 << 2 = 8
-assert 2 == say (8 :> 2); # 8 >> 2 = 2
-assert 0 == say (1 and 0);
-assert 1 == say (0 or 1);
-assert 0 == say (1 xor 1);
-
-# ─── 9. CONDITIONALS ─────────────────────────────────────────────────────────
-
-my flag = 0;
-if 1 { flag = 1; }
-assert 1 == say flag;
-
-ifnot 0 { flag = 2; }
-assert 2 == say flag;
-
-if 0 { flag = 99; } # must not execute
-ifnot 1 { flag = 99; } # must not execute
-assert 2 == say flag;
-
-# ─── 10. WHILE AND UNTIL ─────────────────────────────────────────────────────
-
-my cnt = 0;
-while cnt < 5 { cnt = cnt + 1; }
-assert 5 == say cnt;
-
-cnt = 0;
-until cnt >= 4 { cnt = cnt + 1; }
-assert 4 == say cnt;
-
-# ─── 11. LOOP WITH BREAK AND NEXT ────────────────────────────────────────────
+# Assignment is also an expression that returns the new value.
+assert 15 == (a = 15);
+assert 15 == say a;
+
+# ─── 3. NEGATION AND NOT ───────────────────────────────────────────────────
+
+assert 5 == say neg neg 5;
+assert 0 == say neg neg 0;
+assert 1 == say not 0;
+assert 0 == say not 1;
+
+# Temporarily penalise the first score by 5, then restore it.
+my s0 = scores[0]; # 72
+s0 = s0 - 5;
+assert 67 == say s0;
+s0 = s0 + 5;
+assert 72 == say s0;
+
+# ─── 4. INCREMENT / DECREMENT ──────────────────────────────────────────────
+
+# Used as statements:
+my tally = 0;
+incr tally; incr tally; incr tally;
+assert 3 == say tally;
+decr tally;
+assert 2 == say tally;
+
+# Used as expressions (return the new value):
+my step = 0;
+assert 1 == say incr step;
+assert 0 == say decr step;
+
+# ─── 5. TYPE CONVERSION ────────────────────────────────────────────────────
+
+assert 7 == say integer 7.9; # truncates toward zero
+assert 80 == say double 80; # 80.0 compares equal to 80
+assert 14 == say 1 + string 13; # "13" coerced to integer 13
+assert 5 == say "10 pts" / 2; # leading digits extracted first
+
+# ─── 6. STRING ARITHMETIC ──────────────────────────────────────────────────
+
+assert 46 == say "12" + "34"; # "12"->12 + "34"->34 = 46
+assert 1231 == say "1234" - "3"; # 1234 - 3 = 1231
+
+# ─── 7. COMPARISON OPERATORS ───────────────────────────────────────────────
+
+assert 1 == (put scores[0] > PASS); ln; # 72 > 60 => 1
+assert 0 == (put scores[1] > PASS); ln; # 45 > 60 => 0
+assert 1 == (put scores[3] >= DIST); ln; # 91 >= 80 => 1
+assert 1 == (put PASS != DIST); ln;
+assert 0 == (say PASS == DIST);
+assert 1 == (put 3 < 5); assert 0 == (say 5 < 5); ln;
+assert 1 == (put 5 <= 5); assert 0 == (say 6 <= 5); ln;
+
+# ─── 8. BITWISE GRADE FLAGS ────────────────────────────────────────────────
+# Encode quality: bit 0 = passed (>=PASS), bit 1 = distinction (>=DIST).
+
+# Score 91 => passed AND distinction => 0b11 = 3
+my g91 = 0;
+if scores[3] >= PASS { g91 = g91 or 1; }
+if scores[3] >= DIST { g91 = g91 or 2; }
+assert 3 == say g91;
+
+# Score 45 => failed => 0b00 = 0
+my g45 = 0;
+if scores[1] >= PASS { g45 = g45 or 1; }
+assert 0 == say g45;
+
+assert 1 == say (g91 and 1); # extract pass bit from g91
+assert 0 == say (g45 and 1); # extract pass bit from g45
+assert 6 == say (5 xor 3); # 0b101 ^ 0b011 = 0b110 = 6
+assert 4 == say (1 :< 2); # 1 << 2 = 4
+assert 2 == say (8 :> 2); # 8 >> 2 = 2
+
+# ─── 9. CONDITIONALS ───────────────────────────────────────────────────────
+
+# 91 is a distinction
+if scores[3] >= DIST { band = 2; }
+assert 2 == say band;
+
+# 45 is a fail
+ifnot scores[1] >= PASS { band = 0; }
+assert 0 == say band;
+
+if 0 { band = 99; } # must not execute
+ifnot 1 { band = 99; } # must not execute
+assert 0 == say band;
+
+# ─── 10. WHILE + UNTIL: SUM ALL SCORES ─────────────────────────────────────
+# 72+45+89+91+55+78+63+100+48+82 = 723
+
+my total = 0, wi = 0;
+while wi < N {
+ total = total + scores[wi];
+ incr wi;
+}
+assert 723 == say total;
-my n = 0;
-loop {
- n = n + 1;
- if n == 7 { break; }
+my total2 = 0, ui = 0;
+until ui >= N {
+ total2 = total2 + scores[ui];
+ incr ui;
}
-assert 7 == say n;
+assert 723 == say total2;
+
+# ─── 11. LOOP + BREAK + NEXT: COUNT PASSING SCORES ─────────────────────────
+# Scores >= 60: 72,89,91,78,63,100,82 => 7 students
-# Sum 1..10 skipping multiples of 3: 1+2+4+5+7+8+10 = 37
-my total = 0, step = 0;
+my passing = 0, li = 0;
loop {
- step = step + 1;
- if step > 10 { break; }
- if step / 3 * 3 == step { next; } # divisible by 3
- total = total + step;
+ if li >= N { break; }
+ if scores[li] < PASS { li = li + 1; next; }
+ incr passing;
+ incr li;
}
-assert 37 == say total;
+assert 7 == say passing;
-# ─── 12. WHILE WITH BREAK AND NEXT ───────────────────────────────────────────
+# ─── 12. WHILE + BREAK + NEXT: COUNT DISTINCTIONS ──────────────────────────
+# Scores >= 80: 89,91,100,82 => 4 students
-# Sum 1..10 skipping 5, stopping after 8: 1+2+3+4 + 6+7+8 = 31
-my wsum = 0, wi = 0;
-while wi < 10 {
- wi = wi + 1;
- if wi == 5 { next; }
- if wi > 8 { break; }
- wsum = wsum + wi;
+my dists = 0, di = 0;
+while di < N {
+ incr di;
+ if scores[di - 1] < DIST { next; }
+ incr dists;
}
-assert 31 == say wsum;
+assert 4 == say dists;
-# ─── 13. DO-WHILE / DO-UNTIL ─────────────────────────────────────────────────
+# ─── 13. DO-WHILE / DO-UNTIL ───────────────────────────────────────────────
-# Body runs once even though the condition is already false
+# Body runs once even though the condition is already false.
my dw = 10;
do { dw = dw + 1; } while dw < 10;
assert 11 == say dw;
-my du = 0;
-do { du = du + 1; } until du == 5;
-assert 5 == say du;
-
-# ─── 14. PROCEDURES ──────────────────────────────────────────────────────────
-
-# Procedures share the caller's scope; mutations are visible to the caller
-my acc = 0;
-proc bump { acc = acc + 10; }
-bump;
-bump;
-assert 20 == say acc;
-
-# Variables declared inside a procedure leak into the caller's scope
-proc initcoords { my cx = 3; my cy = 7; }
-initcoords;
-assert 3 == say cx;
-assert 7 == say cy;
-
-# ─── 15. FUNCTIONS ───────────────────────────────────────────────────────────
-
-# Zero-arg function with explicit return
-fun answer() { ret 42; }
-assert 42 == say answer();
-
-# Single-arg
-fun square(m) { ret m * m; }
-assert 25 == say square(5);
-assert 0 == say square(0);
-
-# Two-arg
-fun add(a, b) { ret a + b; }
-assert 9 == say add(4, 5);
+# Accumulate scores until the running total exceeds 500 (runs at least once).
+# After 8 iterations: 72+45+89+91+55+78+63+100 = 593.
+my rsum = 0, ri = 0;
+do {
+ rsum = rsum + scores[ri];
+ incr ri;
+} while rsum < 500;
+assert 593 == say rsum;
+assert 8 == say ri;
+
+# do-until: count down from 3 to 0.
+my cd = 3;
+do { decr cd; } until cd == 0;
+assert 0 == say cd;
+
+# ─── 14. FUNCTIONS ─────────────────────────────────────────────────────────
+
+# Sum the first n elements of an array.
+fun arr_sum(arr, n) {
+ my s = 0, i = 0;
+ while i < n {
+ s = s + arr[i];
+ incr i;
+ }
+ ret s;
+}
+assert 723 == say arr_sum(scores, N);
-# Conditional return
-fun absval(v) {
- if v < 0 { ret neg v; }
- ret v;
+# Integer average (floor division).
+fun avg(arr, n) {
+ ret arr_sum(arr, n) / n;
}
-assert 7 == say absval(7);
-assert 7 == say absval(neg 7);
+assert 72 == say avg(scores, N);
-# Iterative function with local variables and decr
-fun factorial(num) {
- my result = 1;
- while num > 1 {
- result = result * num;
- decr num;
- }
- ret result;
+# Conditional return: grade band (0=fail, 1=pass, 2=distinction).
+fun grade_band(score) {
+ if score >= DIST { ret 2; }
+ if score >= PASS { ret 1; }
+ ret 0;
}
-assert 1 == say factorial(0);
-assert 1 == say factorial(1);
-assert 120 == say factorial(5);
-assert 720 == say factorial(6);
-
-# Iterative fibonacci using local variables
-fun fib(num) {
- if num <= 1 { ret num; }
- my fa = 0, fb = 1, ftmp = 0, fi = 2;
- while fi <= num {
- ftmp = fa + fb;
- fa = fb;
- fb = ftmp;
- fi = fi + 1;
+assert 2 == say grade_band(91);
+assert 1 == say grade_band(72);
+assert 0 == say grade_band(45);
+
+# Multiple return values: minimum and maximum of an array.
+fun arr_minmax(arr, n) {
+ my mn = arr[0], mx = arr[0], i = 1;
+ while i < n {
+ if arr[i] < mn { mn = arr[i]; }
+ if arr[i] > mx { mx = arr[i]; }
+ incr i;
}
- ret fb;
+ ret mn, mx; # prints 45 then 100
}
-assert 0 == say fib(0);
-assert 1 == say fib(1);
-assert 1 == say fib(2);
-assert 8 == say fib(6);
-assert 55 == say fib(10);
-
-# Old-style zero-arg function (no parentheses)
-fun greet { say "hello from greet"; }
-greet;
+say arr_minmax(scores, N);
-# Multiple return values both land on the caller's stack (printed here)
-fun minmax(a, b) {
- if a < b { ret a, b; }
- ret b, a;
+# Nested function: range check (returns 1 if 0 <= score <= 100).
+fun valid_score(score) {
+ fun in_range(v) {
+ if v >= 0 { if v <= 100 { ret 1; } }
+ ret 0;
+ }
+ ret in_range(score);
+}
+assert 1 == say valid_score(72);
+assert 0 == say valid_score(neg 1);
+assert 0 == defined in_range; # nested function gone after the call
+
+# Old-style zero-arg function (no parentheses).
+fun banner { say "=== Student Score Report ==="; }
+banner;
+
+# Self-undefining one-shot function.
+fun init_once { say "Initialising report..."; undef init_once; }
+init_once;
+assert 0 == defined init_once;
+
+# ─── 15. PROCEDURES ────────────────────────────────────────────────────────
+# Procedures share the caller's scope; mutations are visible to the caller.
+
+my accum = total; # start from the already-computed sum
+proc apply_bonus { accum = accum + 10; }
+apply_bonus; apply_bonus;
+assert 743 == say accum; # 723 + 20
+
+# Variables declared inside a procedure leak into the caller's scope.
+proc make_summary {
+ my summary_pass = passing;
+ my summary_dist = dists;
}
-say minmax(3, 7); # prints 3 then 7
+make_summary;
+assert 7 == say summary_pass;
+assert 4 == say summary_dist;
-# ─── 16. SCOPING ─────────────────────────────────────────────────────────────
+# ─── 16. SCOPING ───────────────────────────────────────────────────────────
my outer = 100;
{
- my inner = 200;
+ my inner = 50;
outer = outer + inner;
assert 1 == defined inner;
+ scope; # prints all symbols visible here
}
-assert 300 == say outer;
-assert 0 == defined inner;
+assert 150 == say outer;
+assert 0 == defined inner; # inner vanished when the block closed
-# Variables defined in nested blocks vanish when the block closes
+# Deep nesting: mutate a counter from three levels deep.
my depth = 0;
{
- depth = depth + 1;
- {
- depth = depth + 1;
- { depth = depth + 1; }
- assert 3 == say depth;
- }
+ incr depth;
+ { incr depth; { incr depth; } }
}
assert 3 == say depth;
-# ─── 17. SYNONYMS / ALIASES ──────────────────────────────────────────────────
+# ─── 17. SYNONYMS / ALIASES ────────────────────────────────────────────────
-my orig = 42;
-my alias = \orig;
-assert 42 == say alias; # alias starts with orig's value
+my best = scores[3]; # 91
+my top = \best; # top is a synonym for best
+assert 91 == say top;
-orig = 99;
-assert 99 == say alias; # alias reflects the change
+best = 95; # update through the original name
+assert 95 == say top; # synonym reflects the change
-assert 2 == syms orig; # two symbols point to the same value
-undef orig;
-assert 1 == syms alias;
-assert 0 == defined orig;
-assert 1 == defined alias;
-undef alias;
+assert 2 == syms best;
+undef best;
+assert 1 == syms top;
+assert 0 == defined best;
+assert 1 == defined top;
+undef top;
-# Procedure synonym
-proc grp { say "grp called"; }
-my grp2 = \grp;
-assert 2 == syms grp;
-grp2; # still callable through the alias
-undef grp;
-grp2; # alias keeps it alive
-assert 0 == defined grp;
-undef grp2;
+# Procedure synonym keeps the procedure alive after the original is undefined.
+proc show_band { put "band="; say grade_band(91); }
+my show_band2 = \show_band;
+assert 2 == syms show_band;
+show_band2;
+undef show_band;
+show_band2; # alias still callable
+assert 0 == defined show_band;
+undef show_band2;
-# ─── 18. DEFINED AND UNDEF ───────────────────────────────────────────────────
+# ─── 18. DEFINED / UNDEF ───────────────────────────────────────────────────
-my tmpvar = 5;
-assert 1 == defined tmpvar;
+my tmp = 42;
+assert 1 == defined tmp;
assert 0 == defined nosuchvar;
-undef tmpvar;
-assert 0 == defined tmpvar;
+undef tmp;
+assert 0 == defined tmp;
# ─── 19. ARRAYS — LITERALS, INDEXING, ASSIGNMENT ────────────────────────────
-my nums = [10, 20, 30, 40, 50];
-assert 5 == say len nums;
-assert 10 == say nums[0];
-assert 30 == say nums[2];
-assert 50 == say nums[4];
-
-# Expression-based index
-my idx = 1;
-assert 20 == say nums[idx];
-assert 30 == say nums[idx + 1];
-
-# Element assignment
-nums[2] = 99;
-assert 99 == say nums[2];
-
-# ─── 20. ARRAY SLICES ────────────────────────────────────────────────────────
-
-# nums is now [10, 20, 99, 40, 50]
-my sl = nums[1:4]; # half-open: indices 1, 2, 3
-assert 3 == say len sl;
-assert 20 == say sl[0];
-assert 99 == say sl[1];
-assert 40 == say sl[2];
+my extra = [5, 10, 15, 20, 25];
+assert 5 == say len extra;
+assert 5 == say extra[0];
+assert 15 == say extra[2];
+
+# Element assignment.
+extra[2] = 99;
+assert 99 == say extra[2];
+
+# Expression-based index.
+my ei = 1;
+assert 10 == say extra[ei];
+assert 99 == say extra[ei + 1];
+
+# ─── 20. ARRAY SLICES ──────────────────────────────────────────────────────
+# scores is [72, 45, 89, 91, 55, 78, 63, 100, 48, 82]
+
+# Half-open slice: indices 2, 3, 4 => [89, 91, 55]
+my mid = scores[2:5];
+assert 3 == say len mid;
+assert 89 == say mid[0];
+assert 55 == say mid[2];
+
+# Slice from start (low bound omitted): first three => [72, 45, 89]
+my first3 = scores[:3];
+assert 3 == say len first3;
+assert 72 == say first3[0];
+assert 89 == say first3[2];
+
+# Slice to end (high bound omitted): from index 7 => [100, 48, 82]
+my tail = scores[7:];
+assert 3 == say len tail;
+assert 100 == say tail[0];
+assert 82 == say tail[2];
+
+# Full shallow copy.
+my copy = scores[:];
+assert 10 == say len copy;
+assert 72 == say copy[0];
+assert 82 == say copy[9];
+
+# ─── 21. I/O ───────────────────────────────────────────────────────────────
+
+put "Total: "; put total; ln;
+put "Average: "; put avg(scores, N); ln;
+put "Passing: "; put passing; ln;
+put "Distincts: "; say dists;
+
+# ─── 22. FORK ──────────────────────────────────────────────────────────────
+# Child process computes the same sum independently; parent waits.
-my head = nums[:2]; # first two elements
-assert 2 == say len head;
-assert 10 == say head[0];
-assert 20 == say head[1];
+my pid = fork;
-my tail = nums[3:]; # from index 3 to end
-assert 2 == say len tail;
-assert 40 == say tail[0];
-assert 50 == say tail[1];
+if pid {
+ put "Parent: child pid = "; say pid;
+}
-my cpy = nums[:]; # full shallow copy
-assert 5 == say len cpy;
-assert 10 == say cpy[0];
-assert 50 == say cpy[4];
+ifnot pid {
+ put "Child: score sum = "; say arr_sum(scores, N);
+ exit 0;
+}
+# ─── DONE ──────────────────────────────────────────────────────────────────
say "All assertions passed.";
#*
diff --git a/fype b/fype
index 3f518c5..b407841 100755
--- a/fype
+++ b/fype
Binary files differ
diff --git a/src/build.h b/src/build.h
index 161c8f2..ab16e44 100644
--- a/src/build.h
+++ b/src/build.h
@@ -36,7 +36,7 @@
#ifndef BUILD_H
#define BUILD_H
-#define BUILDNR 9689
+#define BUILDNR 9696
#define OS_LINUX
#endif
diff --git a/src/core/functions.c b/src/core/functions.c
index af889e2..d4a2b51 100644
--- a/src/core/functions.c
+++ b/src/core/functions.c
@@ -455,506 +455,533 @@ functions_delete(Functions *p_functions) {
/* ─── Operator processing ────────────────────────────────────────────── */
-void
-_process(Interpret *p_interpret, Token *p_token_store, Token *p_token_op,
- Token *p_token_op2, Token *p_token_next) {
+/* Resolve a two-token compound operator into its canonical single TokenType.
+ * For example, '!' + '=' becomes TT_NEQ, ':' + '<' becomes TT_LSHIFT.
+ * Returns tt_op unchanged when no compound match is found. */
+static TokenType
+_resolve_composite_op(TokenType tt_op, TokenType tt_op2) {
+ switch (tt_op) {
+ case TT_NOT:
+ if (tt_op2 == TT_ASSIGN) return (TT_NEQ);
+ break;
+ case TT_ASSIGN:
+ if (tt_op2 == TT_ASSIGN) return (TT_EQ);
+ break;
+ case TT_LT:
+ if (tt_op2 == TT_ASSIGN) return (TT_LE);
+ break;
+ case TT_GT:
+ if (tt_op2 == TT_ASSIGN) return (TT_GE);
+ break;
+ case TT_DDOT:
+ if (tt_op2 == TT_LT) return (TT_LSHIFT);
+ if (tt_op2 == TT_GT) return (TT_RSHIFT);
+ break;
+ default:
+ break;
+ }
+ return (tt_op);
+}
- TokenType tt_op = token_get_tt(p_token_op);
- TokenType tt_op2 = p_token_op2 == NULL
- ? TT_NONE
- : token_get_tt(p_token_op2);
+/* Perform variable or array-element assignment.
+ * If p_interpret->p_token_array_lhs is set, writes into that array slot;
+ * otherwise writes into the named variable in p_interpret->p_token_temp. */
+static void
+_op_assign(Interpret *p_interpret, Token *p_token_store) {
+ /* Array element assignment: arr[i] = val */
+ if (p_interpret->p_token_array_lhs != NULL) {
+ array_set(p_interpret->p_token_array_lhs->p_array,
+ p_interpret->i_array_lhs_index,
+ p_token_store);
+ p_interpret->p_token_array_lhs = NULL;
+ return;
+ }
-#ifdef DEBUG_FUNCTION_PROCESS
- if (p_token_op2 == NULL)
- printf("DEBUG::FUNCTION::PROCESS: Operator %s\n", tt_get_name(tt_op));
- else
- printf("DEBUG::FUNCTION::PROCESS: Operator %s %s\n", tt_get_name(tt_op),
- tt_get_name(tt_op2));
+ /* Regular variable assignment */
+ Token *p_token_assign = p_interpret->p_token_temp;
+ TokenType tt_assign = token_get_tt(p_token_assign);
- token_print(p_token_next);
- printf("\n");
- token_print(p_token_store);
- printf("\n");
-#endif /* DEBUG_FUNCTION_PROCESS */
+ if (tt_assign != TT_IDENT) {
+ _FUNCTIONS_ERROR("Can only assign to symbols", p_token_store);
+ }
- if (p_token_op2 != NULL) {
- switch (tt_op) {
- case TT_NOT:
- switch (tt_op2) {
- case TT_ASSIGN:
- tt_op = TT_NEQ;
- break;
- default:
- break;
- }
- break;
- case TT_ASSIGN:
- switch (tt_op2) {
- case TT_ASSIGN:
- tt_op = TT_EQ;
- break;
- default:
- break;
- }
- break;
- case TT_LT:
- switch (tt_op2) {
- case TT_ASSIGN:
- tt_op = TT_LE;
- break;
- default:
- break;
- }
- break;
- case TT_GT:
- switch (tt_op2) {
- case TT_ASSIGN:
- tt_op = TT_GE;
- break;
- default:
- break;
- }
- break;
- case TT_DDOT:
- switch (tt_op2) {
- case TT_LT:
- tt_op = TT_LSHIFT;
- break;
- case TT_GT:
- tt_op = TT_RSHIFT;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- } else {
- switch (tt_op) {
- case TT_ASSIGN:
- {
- /* Array element assignment: arr[i] = val */
- if (p_interpret->p_token_array_lhs != NULL) {
- array_set(p_interpret->p_token_array_lhs->p_array,
- p_interpret->i_array_lhs_index,
- p_token_store);
- p_interpret->p_token_array_lhs = NULL;
- return;
- }
+ Symbol *p_symbol = scope_get(p_interpret->p_scope,
+ token_get_val(p_token_assign));
- /* Regular variable assignment */
- Token *p_token_assign = p_interpret->p_token_temp;
- TokenType tt_assign = token_get_tt(p_token_assign);
+ if (p_symbol == NULL) {
+ _FUNCTIONS_ERROR("No such symbol", p_token_assign);
+ }
- if (tt_assign != TT_IDENT) {
- _FUNCTIONS_ERROR("Can only assign to symbols",
- p_token_store);
- }
+ symbol_set_val(p_symbol, p_token_store);
+ symbol_set_sym(p_symbol, SYM_VARIABLE);
+}
- Symbol *p_symbol = scope_get(p_interpret->p_scope,
- token_get_val(p_token_assign));
+/* Addition: store = next + store (integers, doubles, strings, array append) */
+static void
+_op_add(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ token_get_ival(p_next) + token_get_ival(p_store));
+ break;
+ case TT_DOUBLE:
+ token_set_dval(p_store,
+ token_get_dval(p_next) + token_get_dval(p_store));
+ break;
+ case TT_STRING:
+ token_set_ival(p_store,
+ atoi(token_get_val(p_next)) +
+ atoi(token_get_val(p_store)));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_ARRAY:
+ array_append(p_store->p_array, p_next->p_array);
+ break;
+ NO_DEFAULT;
+ }
+}
- if (p_symbol == NULL) {
- _FUNCTIONS_ERROR("No such symbol",
- p_token_assign);
- }
+/* Subtraction: store = next - store */
+static void
+_op_sub(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ token_get_ival(p_next) - token_get_ival(p_store));
+ break;
+ case TT_DOUBLE:
+ token_set_dval(p_store,
+ token_get_dval(p_next) - token_get_dval(p_store));
+ break;
+ case TT_STRING:
+ token_set_ival(p_store,
+ atoi(token_get_val(p_next)) -
+ atoi(token_get_val(p_store)));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_ARRAY:
+ ERROR("TT_ARRAY - TT_ARRAY not yet implemented");
+ break;
+ NO_DEFAULT;
+ }
+}
- symbol_set_val(p_symbol, p_token_store);
- symbol_set_sym(p_symbol, SYM_VARIABLE);
+/* Multiplication: store = next * store */
+static void
+_op_mult(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ token_get_ival(p_next) * token_get_ival(p_store));
+ break;
+ case TT_DOUBLE:
+ token_set_dval(p_store,
+ token_get_dval(p_next) * token_get_dval(p_store));
+ break;
+ case TT_STRING:
+ token_set_ival(p_store,
+ atoi(token_get_val(p_next)) *
+ atoi(token_get_val(p_store)));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_ARRAY:
+ ERROR("TT_ARRAY * TT_ARRAY not yet implemented");
+ break;
+ NO_DEFAULT;
+ }
+}
- return;
- }
+/* Division: store = next / store */
+static void
+_op_div(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ (int) token_get_ival(p_next) /
+ token_get_ival(p_store));
+ break;
+ case TT_DOUBLE:
+ token_set_dval(p_store,
+ token_get_dval(p_next) / token_get_dval(p_store));
+ break;
+ case TT_STRING:
+ token_set_dval(p_store,
+ atof(token_get_val(p_next)) /
+ atof(token_get_val(p_store)));
+ token_set_tt(p_store, TT_DOUBLE);
+ break;
+ case TT_ARRAY:
+ ERROR("TT_ARRAY / TT_ARRAY not yet implemented");
+ break;
+ NO_DEFAULT;
+ }
+}
+/* Equality: store = (next == store) — result is always TT_INTEGER */
+static void
+_op_eq(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ (int) token_get_ival(p_next) ==
+ token_get_ival(p_store));
+ break;
+ case TT_DOUBLE:
+ token_set_ival(p_store,
+ token_get_dval(p_next) == token_get_dval(p_store));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_STRING:
+ token_set_ival(p_store,
+ strcmp(token_get_val(p_next),
+ token_get_val(p_store)) == 0);
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_ARRAY:
+ ERROR("TT_ARRAY eq TT_ARRAY not yet implemented");
break;
NO_DEFAULT;
- }
}
+}
- p_token_next = token_new_copy(p_token_next);
- TokenType tt_highest = convert_to_highest(p_token_store, p_token_next);
+/* Inequality: store = (next != store) — result is always TT_INTEGER */
+static void
+_op_neq(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ (int) token_get_ival(p_next) !=
+ token_get_ival(p_store));
+ break;
+ case TT_DOUBLE:
+ token_set_ival(p_store,
+ token_get_dval(p_next) != token_get_dval(p_store));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_STRING:
+ token_set_ival(p_store,
+ strcmp(token_get_val(p_next),
+ token_get_val(p_store)) != 0);
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_ARRAY:
+ ERROR("TT_ARRAY != TT_ARRAY not yet implemented");
+ break;
+ NO_DEFAULT;
+ }
+}
-#ifdef DEBUG_FUNCTION_PROCESS
- printf("DEBUG::FUNCTION::PROCESS: ===> %s %s %s\n",
- tt_get_name(tt_highest),
- tt_get_name(tt_op),
- tt_get_name(tt_highest));
-#endif /* DEBUG_FUNCTION_PROCESS */
+/* Less-than: store = (next < store) — result is always TT_INTEGER */
+static void
+_op_lt(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ (int) token_get_ival(p_next) <
+ token_get_ival(p_store));
+ break;
+ case TT_DOUBLE:
+ token_set_ival(p_store,
+ token_get_dval(p_next) < token_get_dval(p_store));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_STRING:
+ token_set_ival(p_store,
+ strcmp(token_get_val(p_next),
+ token_get_val(p_store)) < 0);
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_ARRAY:
+ ERROR("TT_ARRAY < TT_ARRAY not yet implemented");
+ break;
+ NO_DEFAULT;
+ }
+}
- switch (tt_op) {
- case TT_ADD:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- token_get_ival(p_token_next) +
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_dval(p_token_store,
- token_get_dval(p_token_next) +
- token_get_dval(p_token_store));
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- atoi(token_get_val(p_token_next)) +
- atoi(token_get_val(p_token_store)));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- array_append(p_token_store->p_array,
- p_token_next->p_array);
- break;
- NO_DEFAULT;
- }
+/* Greater-than: store = (next > store) — result is always TT_INTEGER */
+static void
+_op_gt(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ (int) token_get_ival(p_next) >
+ token_get_ival(p_store));
break;
- case TT_SUB:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- token_get_ival(p_token_next) -
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_dval(p_token_store,
- token_get_dval(p_token_next) -
- token_get_dval(p_token_store));
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- atoi(token_get_val(p_token_next)) -
- atoi(token_get_val(p_token_store)));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("TT_ARRAY - TT_ARRAY not yet implemented");
- break;
- NO_DEFAULT;
- }
+ case TT_DOUBLE:
+ token_set_ival(p_store,
+ token_get_dval(p_next) > token_get_dval(p_store));
+ token_set_tt(p_store, TT_INTEGER);
break;
- case TT_MULT:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- token_get_ival(p_token_next) *
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_dval(p_token_store,
- token_get_dval(p_token_next) *
- token_get_dval(p_token_store));
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- atoi(token_get_val(p_token_next)) *
- atoi(token_get_val(p_token_store)));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("TT_ARRAY * TT_ARRAY not yet implemented");
- break;
- NO_DEFAULT;
- }
+ case TT_STRING:
+ token_set_ival(p_store,
+ strcmp(token_get_val(p_next),
+ token_get_val(p_store)) > 0);
+ token_set_tt(p_store, TT_INTEGER);
break;
- case TT_DIV:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- (int) token_get_ival(p_token_next) /
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_dval(p_token_store,
- token_get_dval(p_token_next) /
- token_get_dval(p_token_store));
- break;
- case TT_STRING:
- token_set_dval(p_token_store,
- atof(token_get_val(p_token_next)) /
- atof(token_get_val(p_token_store)));
- token_set_tt(p_token_store, TT_DOUBLE);
- break;
- case TT_ARRAY:
- ERROR("TT_ARRAY / TT_ARRAY not yet implemented");
- break;
- NO_DEFAULT;
- }
+ case TT_ARRAY:
+ ERROR("TT_ARRAY > TT_ARRAY not yet implemented");
break;
- case TT_EQ:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- (int) token_get_ival(p_token_next) ==
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_ival(p_token_store,
- token_get_dval(p_token_next) ==
- token_get_dval(p_token_store));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- strcmp(token_get_val(p_token_next),
- token_get_val(p_token_store)) == 0);
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("TT_ARRAY eq TT_ARRAY not yet implemented");
- break;
- NO_DEFAULT;
- }
+ NO_DEFAULT;
+ }
+}
+
+/* Less-or-equal: store = (next <= store) — result is always TT_INTEGER */
+static void
+_op_le(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ (int) token_get_ival(p_next) <=
+ token_get_ival(p_store));
break;
- case TT_NEQ:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- (int) token_get_ival(p_token_next) !=
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_ival(p_token_store,
- token_get_dval(p_token_next) !=
- token_get_dval(p_token_store));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- strcmp(token_get_val(p_token_next),
- token_get_val(p_token_store)) != 0);
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("ARRAY bla yet implemented");
- break;
- NO_DEFAULT;
- }
+ case TT_DOUBLE:
+ token_set_ival(p_store,
+ token_get_dval(p_next) <= token_get_dval(p_store));
+ token_set_tt(p_store, TT_INTEGER);
break;
- case TT_LE:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- (int) token_get_ival(p_token_next) <=
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_ival(p_token_store,
- token_get_dval(p_token_next) <=
- token_get_dval(p_token_store));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- strcmp(token_get_val(p_token_next),
- token_get_val(p_token_store)) <= 0);
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("ARRAY bla yet implemented");
- break;
- NO_DEFAULT;
- }
+ case TT_STRING:
+ token_set_ival(p_store,
+ strcmp(token_get_val(p_next),
+ token_get_val(p_store)) <= 0);
+ token_set_tt(p_store, TT_INTEGER);
break;
- case TT_GE:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- (int) token_get_ival(p_token_next) >=
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_ival(p_token_store,
- token_get_dval(p_token_next) >=
- token_get_dval(p_token_store));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- strcmp(token_get_val(p_token_next),
- token_get_val(p_token_store)) >= 0);
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("ARRAY bla yet implemented");
- break;
- NO_DEFAULT;
- }
+ case TT_ARRAY:
+ ERROR("TT_ARRAY <= TT_ARRAY not yet implemented");
break;
- case TT_LT:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- (int) token_get_ival(p_token_next) <
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_ival(p_token_store,
- token_get_dval(p_token_next) <
- token_get_dval(p_token_store));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- strcmp(token_get_val(p_token_next),
- token_get_val(p_token_store)) < 0);
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("ARRAY bla yet implemented");
- break;
- NO_DEFAULT;
- }
+ NO_DEFAULT;
+ }
+}
+
+/* Greater-or-equal: store = (next >= store) — result is always TT_INTEGER */
+static void
+_op_ge(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ (int) token_get_ival(p_next) >=
+ token_get_ival(p_store));
break;
- case TT_GT:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- (int) token_get_ival(p_token_next) >
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_ival(p_token_store,
- token_get_dval(p_token_next) >
- token_get_dval(p_token_store));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- strcmp(token_get_val(p_token_next),
- token_get_val(p_token_store)) > 0);
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("ARRAY bla yet implemented");
- break;
- NO_DEFAULT;
- }
+ case TT_DOUBLE:
+ token_set_ival(p_store,
+ token_get_dval(p_next) >= token_get_dval(p_store));
+ token_set_tt(p_store, TT_INTEGER);
break;
- case TT_AND:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- (int) token_get_ival(p_token_next) &
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_ival(p_token_store,
- (int) token_get_dval(p_token_next) &
- (int) token_get_dval(p_token_store));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- atoi(token_get_val(p_token_next)) &
- atoi(token_get_val(p_token_store)));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("ARRAY bla yet implemented");
- break;
- NO_DEFAULT;
- }
+ case TT_STRING:
+ token_set_ival(p_store,
+ strcmp(token_get_val(p_next),
+ token_get_val(p_store)) >= 0);
+ token_set_tt(p_store, TT_INTEGER);
break;
- case TT_OR:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- (int) token_get_ival(p_token_next) |
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_ival(p_token_store,
- (int) token_get_dval(p_token_next) |
- (int) token_get_dval(p_token_store));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- atoi(token_get_val(p_token_next)) |
- atoi(token_get_val(p_token_store)));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("ARRAY bla yet implemented");
- break;
- NO_DEFAULT;
- }
+ case TT_ARRAY:
+ ERROR("TT_ARRAY >= TT_ARRAY not yet implemented");
break;
- case TT_XOR:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- (int) token_get_ival(p_token_next) ^
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_ival(p_token_store,
- (int) token_get_dval(p_token_next) ^
- (int) token_get_dval(p_token_store));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- atoi(token_get_val(p_token_next)) ^
- atoi(token_get_val(p_token_store)));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("ARRAY bla yet implemented");
- break;
- NO_DEFAULT;
- }
+ NO_DEFAULT;
+ }
+}
+
+/* Bitwise AND: store = next & store — doubles and strings coerced to int */
+static void
+_op_and(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ (int) token_get_ival(p_next) &
+ token_get_ival(p_store));
break;
- case TT_LSHIFT:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- (int) token_get_ival(p_token_next) <<
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_ival(p_token_store,
- (int) token_get_dval(p_token_next) <<
- (int) token_get_dval(p_token_store));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- atoi(token_get_val(p_token_next)) <<
- atoi(token_get_val(p_token_store)));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("ARRAY bla yet implemented");
- break;
- NO_DEFAULT;
- }
+ case TT_DOUBLE:
+ token_set_ival(p_store,
+ (int) token_get_dval(p_next) &
+ (int) token_get_dval(p_store));
+ token_set_tt(p_store, TT_INTEGER);
break;
- case TT_RSHIFT:
- switch (tt_highest) {
- case TT_INTEGER:
- token_set_ival(p_token_store,
- (int) token_get_ival(p_token_next) >>
- token_get_ival(p_token_store));
- break;
- case TT_DOUBLE:
- token_set_ival(p_token_store,
- (int) token_get_dval(p_token_next) >>
- (int) token_get_dval(p_token_store));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_STRING:
- token_set_ival(p_token_store,
- atoi(token_get_val(p_token_next)) >>
- atoi(token_get_val(p_token_store)));
- token_set_tt(p_token_store, TT_INTEGER);
- break;
- case TT_ARRAY:
- ERROR("ARRAY bla yet implemented");
- break;
- NO_DEFAULT;
- }
+ case TT_STRING:
+ token_set_ival(p_store,
+ atoi(token_get_val(p_next)) &
+ atoi(token_get_val(p_store)));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_ARRAY:
+ ERROR("TT_ARRAY & TT_ARRAY not yet implemented");
+ break;
+ NO_DEFAULT;
+ }
+}
+
+/* Bitwise OR: store = next | store — doubles and strings coerced to int */
+static void
+_op_or(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ (int) token_get_ival(p_next) |
+ token_get_ival(p_store));
+ break;
+ case TT_DOUBLE:
+ token_set_ival(p_store,
+ (int) token_get_dval(p_next) |
+ (int) token_get_dval(p_store));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_STRING:
+ token_set_ival(p_store,
+ atoi(token_get_val(p_next)) |
+ atoi(token_get_val(p_store)));
+ token_set_tt(p_store, TT_INTEGER);
break;
+ case TT_ARRAY:
+ ERROR("TT_ARRAY | TT_ARRAY not yet implemented");
+ break;
+ NO_DEFAULT;
+ }
+}
+
+/* Bitwise XOR: store = next ^ store — doubles and strings coerced to int */
+static void
+_op_xor(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ (int) token_get_ival(p_next) ^
+ token_get_ival(p_store));
+ break;
+ case TT_DOUBLE:
+ token_set_ival(p_store,
+ (int) token_get_dval(p_next) ^
+ (int) token_get_dval(p_store));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_STRING:
+ token_set_ival(p_store,
+ atoi(token_get_val(p_next)) ^
+ atoi(token_get_val(p_store)));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_ARRAY:
+ ERROR("TT_ARRAY ^ TT_ARRAY not yet implemented");
+ break;
+ NO_DEFAULT;
+ }
+}
+/* Left shift: store = next << store — doubles and strings coerced to int */
+static void
+_op_lshift(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ (int) token_get_ival(p_next) <<
+ token_get_ival(p_store));
+ break;
+ case TT_DOUBLE:
+ token_set_ival(p_store,
+ (int) token_get_dval(p_next) <<
+ (int) token_get_dval(p_store));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_STRING:
+ token_set_ival(p_store,
+ atoi(token_get_val(p_next)) <<
+ atoi(token_get_val(p_store)));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_ARRAY:
+ ERROR("TT_ARRAY << TT_ARRAY not yet implemented");
+ break;
+ NO_DEFAULT;
+ }
+}
+
+/* Right shift: store = next >> store — doubles and strings coerced to int */
+static void
+_op_rshift(Token *p_store, Token *p_next, TokenType tt_highest) {
+ switch (tt_highest) {
+ case TT_INTEGER:
+ token_set_ival(p_store,
+ (int) token_get_ival(p_next) >>
+ token_get_ival(p_store));
+ break;
+ case TT_DOUBLE:
+ token_set_ival(p_store,
+ (int) token_get_dval(p_next) >>
+ (int) token_get_dval(p_store));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_STRING:
+ token_set_ival(p_store,
+ atoi(token_get_val(p_next)) >>
+ atoi(token_get_val(p_store)));
+ token_set_tt(p_store, TT_INTEGER);
+ break;
+ case TT_ARRAY:
+ ERROR("TT_ARRAY >> TT_ARRAY not yet implemented");
+ break;
+ NO_DEFAULT;
+ }
+}
+
+/* Dispatch to the correct per-operator handler.
+ * 1. Resolve composite two-token operators (!=, ==, <=, >=, <<, >>).
+ * 2. Handle assignment early — it does not need type conversion.
+ * 3. Coerce both operands to their highest shared type.
+ * 4. Call the matching _op_*() function for the resolved operator. */
+void
+_process(Interpret *p_interpret, Token *p_token_store, Token *p_token_op,
+ Token *p_token_op2, Token *p_token_next) {
+
+ TokenType tt_op = token_get_tt(p_token_op);
+ TokenType tt_op2 = p_token_op2 == NULL
+ ? TT_NONE
+ : token_get_tt(p_token_op2);
+
+#ifdef DEBUG_FUNCTION_PROCESS
+ if (p_token_op2 == NULL)
+ printf("DEBUG::FUNCTION::PROCESS: Operator %s\n",
+ tt_get_name(tt_op));
+ else
+ printf("DEBUG::FUNCTION::PROCESS: Operator %s %s\n",
+ tt_get_name(tt_op), tt_get_name(tt_op2));
+
+ token_print(p_token_next);
+ printf("\n");
+ token_print(p_token_store);
+ printf("\n");
+#endif /* DEBUG_FUNCTION_PROCESS */
+
+ /* Resolve two-token operators (!=, ==, <=, >=, <<, >>).
+ * When p_token_op2 is NULL and operator is TT_ASSIGN, handle assignment
+ * directly — it does not need type conversion and must not fall through. */
+ if (p_token_op2 != NULL)
+ tt_op = _resolve_composite_op(tt_op, tt_op2);
+ else if (tt_op == TT_ASSIGN) {
+ _op_assign(p_interpret, p_token_store);
+ return;
+ }
+
+ p_token_next = token_new_copy(p_token_next);
+ TokenType tt_highest = convert_to_highest(p_token_store, p_token_next);
+
+#ifdef DEBUG_FUNCTION_PROCESS
+ printf("DEBUG::FUNCTION::PROCESS: ===> %s %s %s\n",
+ tt_get_name(tt_highest), tt_get_name(tt_op),
+ tt_get_name(tt_highest));
+#endif /* DEBUG_FUNCTION_PROCESS */
+
+ switch (tt_op) {
+ case TT_ADD: _op_add(p_token_store, p_token_next, tt_highest); break;
+ case TT_SUB: _op_sub(p_token_store, p_token_next, tt_highest); break;
+ case TT_MULT: _op_mult(p_token_store, p_token_next, tt_highest); break;
+ case TT_DIV: _op_div(p_token_store, p_token_next, tt_highest); break;
+ case TT_EQ: _op_eq(p_token_store, p_token_next, tt_highest); break;
+ case TT_NEQ: _op_neq(p_token_store, p_token_next, tt_highest); break;
+ case TT_LT: _op_lt(p_token_store, p_token_next, tt_highest); break;
+ case TT_GT: _op_gt(p_token_store, p_token_next, tt_highest); break;
+ case TT_LE: _op_le(p_token_store, p_token_next, tt_highest); break;
+ case TT_GE: _op_ge(p_token_store, p_token_next, tt_highest); break;
+ case TT_AND: _op_and(p_token_store, p_token_next, tt_highest); break;
+ case TT_OR: _op_or(p_token_store, p_token_next, tt_highest); break;
+ case TT_XOR: _op_xor(p_token_store, p_token_next, tt_highest); break;
+ case TT_LSHIFT: _op_lshift(p_token_store, p_token_next, tt_highest); break;
+ case TT_RSHIFT: _op_rshift(p_token_store, p_token_next, tt_highest); break;
default:
_FUNCTIONS_ERROR("No such function/operator", p_token_op);
}
diff --git a/tags b/tags
index b7644a0..def4b29 100644
--- a/tags
+++ b/tags
@@ -38,6 +38,8 @@
!_TAG_ROLE_DESCRIPTION!C!struct foreigndecl /declared in foreign languages/
ARGV_OSLEN ./src/argv.c /^#define ARGV_OSLEN /;" d file:
BINARY ./src/argv.c /^char *BINARY;$/;" v typeref:typename:char *
+BuiltinEntry ./src/core/functions.c /^} BuiltinEntry;$/;" t typeref:struct:__anonc43baffb0108 file:
+BuiltinFn ./src/core/functions.c /^typedef void (*BuiltinFn)(Interpret *p_interpret,$/;" t typeref:typename:void (*)(Interpret * p_interpret,Stack * p_stack_args,Token * p_token_ident) file:
CASE ./src/core/token.c /^#define CASE(/;" d file:
CHECK ./src/core/token.c /^#define CHECK(/;" d file:
LIST_GARBAGE ./src/core/garbage.c /^List *LIST_GARBAGE = NULL;$/;" v typeref:typename:List *
@@ -56,13 +58,40 @@ _NEXT_ORG ./src/core/interpret.c /^#define _NEXT_ORG /;" d file:
_NEXT_TT ./src/core/interpret.c /^#define _NEXT_TT /;" d file:
_SKIP ./src/core/interpret.c /^#define _SKIP /;" d file:
_TOKENENDS ./src/core/scanner.c /^const char _TOKENENDS[] = "}])+-*\/={([<>;:,.!";$/;" v typeref:typename:const char[]
+__anonc43baffb0108 ./src/core/functions.c /^typedef struct {$/;" s file:
__anoneaa3b3cb0108 ./src/core/garbage.c /^typedef struct {$/;" s file:
_add_semicolon_to_list ./src/core/scanner.c /^_add_semicolon_to_list(Scanner *p_scanner) {$/;" f typeref:typename:void
_block ./src/core/interpret.c /^_block(Interpret *p_interpret) {$/;" f typeref:typename:int
_block_get ./src/core/interpret.c /^_block_get(Interpret *p_interpret, List *p_list_block) {$/;" f typeref:typename:int
_block_skip ./src/core/interpret.c /^_block_skip(Interpret *p_interpret) {$/;" f typeref:typename:int
+_builtin_assert ./src/core/functions.c /^_builtin_assert(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_decr ./src/core/functions.c /^_builtin_decr(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_double ./src/core/functions.c /^_builtin_double(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_end ./src/core/functions.c /^_builtin_end(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_exit ./src/core/functions.c /^_builtin_exit(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_fork ./src/core/functions.c /^_builtin_fork(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_gc ./src/core/functions.c /^_builtin_gc(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_incr ./src/core/functions.c /^_builtin_incr(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_ind ./src/core/functions.c /^_builtin_ind(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_integer ./src/core/functions.c /^_builtin_integer(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_len ./src/core/functions.c /^_builtin_len(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_ln ./src/core/functions.c /^_builtin_ln(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_neg ./src/core/functions.c /^_builtin_neg(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_no ./src/core/functions.c /^_builtin_no(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_not ./src/core/functions.c /^_builtin_not(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_put ./src/core/functions.c /^_builtin_put(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_refs ./src/core/functions.c /^_builtin_refs(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_say ./src/core/functions.c /^_builtin_say(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_scope ./src/core/functions.c /^_builtin_scope(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_string ./src/core/functions.c /^_builtin_string(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
+_builtin_yes ./src/core/functions.c /^_builtin_yes(Interpret *p_interpret, Stack *p_stack_args,$/;" f typeref:typename:void file:
_compare ./src/core/interpret.c /^_compare(Interpret *p_interpret) {$/;" f typeref:typename:int
_control ./src/core/interpret.c /^_control(Interpret *p_interpret) {$/;" f typeref:typename:int
+_control_do ./src/core/interpret.c /^_control_do(Interpret *p_interpret) {$/;" f typeref:typename:int file:
+_control_if_ifnot ./src/core/interpret.c /^_control_if_ifnot(Interpret *p_interpret) {$/;" f typeref:typename:int file:
+_control_loop ./src/core/interpret.c /^_control_loop(Interpret *p_interpret) {$/;" f typeref:typename:int file:
+_control_while_until ./src/core/interpret.c /^_control_while_until(Interpret *p_interpret) {$/;" f typeref:typename:int file:
+_eval_expr_list ./src/core/interpret.c /^_eval_expr_list(Interpret *p_interpret, List *p_list_expr) {$/;" f typeref:typename:Token * file:
_expression ./src/core/interpret.c /^_expression(Interpret *p_interpret) {$/;" f typeref:typename:int
_expression_ ./src/core/interpret.c /^_expression_(Interpret *p_interpret) {$/;" f typeref:typename:int
_expression_get ./src/core/interpret.c /^_expression_get(Interpret *p_interpret, List *p_list_expression) {$/;" f typeref:typename:int
@@ -71,12 +100,29 @@ _indent ./src/data/tree.c /^void _indent(int i_indent) {$/;" f typeref:typename:
_list_copy_cb ./src/data/list.c /^_list_copy_cb(void *p_void1, void *p_cpy) {$/;" f typeref:typename:void
_next ./src/core/interpret.c /^_next(Interpret *p_interpret) {$/;" f typeref:typename:int
_next_tt ./src/core/interpret.c /^_next_tt(Interpret *p_interpret) {$/;" f typeref:typename:TokenType
+_op_add ./src/core/functions.c /^_op_add(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_and ./src/core/functions.c /^_op_and(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_assign ./src/core/functions.c /^_op_assign(Interpret *p_interpret, Token *p_token_store) {$/;" f typeref:typename:void file:
+_op_div ./src/core/functions.c /^_op_div(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_eq ./src/core/functions.c /^_op_eq(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_ge ./src/core/functions.c /^_op_ge(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_gt ./src/core/functions.c /^_op_gt(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_le ./src/core/functions.c /^_op_le(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_lshift ./src/core/functions.c /^_op_lshift(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_lt ./src/core/functions.c /^_op_lt(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_mult ./src/core/functions.c /^_op_mult(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_neq ./src/core/functions.c /^_op_neq(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_or ./src/core/functions.c /^_op_or(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_rshift ./src/core/functions.c /^_op_rshift(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_sub ./src/core/functions.c /^_op_sub(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
+_op_xor ./src/core/functions.c /^_op_xor(Token *p_store, Token *p_next, TokenType tt_highest) {$/;" f typeref:typename:void file:
_print_lookahead ./src/core/interpret.c /^_print_lookahead(Interpret *p_interpret) {$/;" f typeref:typename:void
_proc_decl ./src/core/interpret.c /^_proc_decl(Interpret *p_interpret) {$/;" f typeref:typename:int
_process ./src/core/functions.c /^_process(Interpret *p_interpret, Token *p_token_store, Token *p_token_op,$/;" f typeref:typename:void
_product ./src/core/interpret.c /^_product(Interpret *p_interpret) {$/;" f typeref:typename:int
_product2 ./src/core/interpret.c /^_product2(Interpret *p_interpret) {$/;" f typeref:typename:int
_program ./src/core/interpret.c /^_program(Interpret *p_interpret) {$/;" f typeref:typename:int
+_resolve_composite_op ./src/core/functions.c /^_resolve_composite_op(TokenType tt_op, TokenType tt_op2) {$/;" f typeref:typename:TokenType file:
_scanner_get_next_char ./src/core/scanner.c /^_scanner_get_next_char(Scanner *p_scanner) {$/;" f typeref:typename:char
_scanner_has_next_char ./src/core/scanner.c /^_scanner_has_next_char(Scanner *p_scanner) {$/;" f typeref:typename:_Bool
_scope_get_hash ./src/core/scope.c /^_scope_get_hash(Scope *p_scope, char *c_key) {$/;" f typeref:typename:Hash * file:
@@ -126,6 +172,7 @@ arrayiterator_delete ./src/data/array.c /^arrayiterator_delete(ArrayIterator *p_
arrayiterator_has_next ./src/data/array.c /^arrayiterator_has_next(ArrayIterator *p_arrayiterator) {$/;" f typeref:typename:_Bool
arrayiterator_new ./src/data/array.c /^arrayiterator_new(Array *p_array) {$/;" f typeref:typename:ArrayIterator *
arrayiterator_next ./src/data/array.c /^arrayiterator_next(ArrayIterator *p_arrayiterator) {$/;" f typeref:typename:void *
+c_name ./src/core/functions.c /^ const char *c_name;$/;" m struct:__anonc43baffb0108 typeref:typename:const char * file:
convert_function_arg_types_to_highest ./src/core/convert.c /^convert_function_arg_types_to_highest(Stack *p_stack_args, int i_args) {$/;" f typeref:typename:TokenType
convert_to_array ./src/core/convert.c /^convert_to_array(Token *p_token) {$/;" f typeref:typename:void
convert_to_double ./src/core/convert.c /^convert_to_double(Token *p_token) {$/;" f typeref:typename:void
@@ -161,6 +208,7 @@ datiter_new ./src/data/dat.c /^datiter_new(Dat *p_dat) {$/;" f typeref:typename:
datiter_next ./src/data/dat.c /^datiter_next(DatIter *p_iter) {$/;" f typeref:typename:void *
datiter_next_t ./src/data/dat.c /^datiter_next_t(DatIter *p_iter, TYPE *p_type) {$/;" f typeref:typename:void *
datiter_skip ./src/data/dat.c /^datiter_skip(DatIter *p_iter, unsigned i_num) {$/;" f typeref:typename:void
+fn ./src/core/functions.c /^ BuiltinFn fn;$/;" m struct:__anonc43baffb0108 typeref:typename:BuiltinFn file:
funcdef_delete ./src/core/symbol.c /^funcdef_delete(FuncDef *p_funcdef) {$/;" f typeref:typename:void
funcdef_new ./src/core/symbol.c /^funcdef_new(List *p_body, List *p_params, int i_nparams) {$/;" f typeref:typename:FuncDef *
function_delete ./src/core/function.c /^function_delete(Function *p_function) {$/;" f typeref:typename:void
@@ -176,6 +224,7 @@ functions_new ./src/core/functions.c /^functions_new() {$/;" f typeref:typename:
fype_delete ./src/fype.c /^fype_delete(Fype *p_fype) {$/;" f typeref:typename:void
fype_new ./src/fype.c /^fype_new() {$/;" f typeref:typename:Fype *
fype_run ./src/fype.c /^fype_run(int i_argc, char **pc_argv) {$/;" f typeref:typename:int
+g_builtins ./src/core/functions.c /^static const BuiltinEntry g_builtins[] = {$/;" v typeref:typename:const BuiltinEntry[] file:
garbage_add ./src/core/garbage.c /^garbage_add(void *p, GarbageType type) {$/;" f typeref:typename:void
garbage_add2 ./src/core/garbage.c /^garbage_add2(void *p,$/;" f typeref:typename:void
garbage_add3 ./src/core/garbage.c /^garbage_add3(void *p,$/;" f typeref:typename:void
@@ -346,7 +395,6 @@ token_new ./src/core/token.c /^token_new(char *c_val, TokenType tt_cur, int i_li
token_new_ ./src/core/token.c /^token_new_(char *c_val, TokenType tt_cur, char *c_filename) {$/;" f typeref:typename:Token *
token_new_array ./src/core/token.c /^token_new_array(int i_size) {$/;" f typeref:typename:Token *
token_new_copy ./src/core/token.c /^token_new_copy(Token *p_token) {$/;" f typeref:typename:Token *
-token_new_double ./src/core/token.c /^token_new_double(double d_val) {$/;" f typeref:typename:Token *
token_new_dummy ./src/core/token.c /^token_new_dummy() {$/;" f typeref:typename:Token *
token_new_integer ./src/core/token.c /^token_new_integer(int i_val) {$/;" f typeref:typename:Token *
token_new_string ./src/core/token.c /^token_new_string(char *c_val) {$/;" f typeref:typename:Token *