This is a rpn-evaluator, developed in 2017. It's built on a lib_tokenizer, and it checks if an expression is valid before trying to generate the machine code for an "ijvm-modified" machine.
# defvar uint32_t a;
# defvar uint32_t b;
# defvar uint32_t c;
# defvar uint32_t d;
# defunc uint32_t Foo(uint32_t b, uint32_t c, uint32_t d);
In this example, it takes the expression "a + Foo( b, c, d )" and it converts into a "stack" of { variables, function-calls, operators }
# rpn a+Foo(b,c,d)
[rpn] kind3 3:1 token_StrictAlphaNum, type21
[a] kind3 3:2 token_StrictAlphaNum, type21
[+] kind2 3:3 token_Plus, type67
[Foo] kind3 3:4 token_StrictAlphaNum, type21
[(] kind2 3:5 token_OpenBracket, type84
[b] kind3 3:6 token_StrictAlphaNum, type21
[,] kind2 3:7 token_Comma, type9
[c] kind3 3:8 token_StrictAlphaNum, type21
[,] kind2 3:9 token_Comma, type9
[d] kind3 3:10 token_StrictAlphaNum, type21
[)] kind2 3:11 token_CloseBracket, type85
types analysis: PASSED
yards analysis: PASSED
stack analysis: PASSED
expr="a + Foo ( b , c , d ) " : PASSED
rpn=
{
0 1 cookie G0 [a] token_StrictAlphaNum, type21
4 1 f_cookie G1 [b] token_StrictAlphaNum, type21
6 1 f_cookie G1 [c] token_StrictAlphaNum, type21
8 1 f_cookie G1 [d] token_StrictAlphaNum, type21
2 -2 function G0 [Foo] token_StrictAlphaNum, type21
1 -1 operator G0 [+] token_Plus, type67
}
code gen, machine=ijvm-r2
---------------------------------------------- is_G=0
r1=a
---------------------------------------------- is_G=1
xxxx r2=b, push r2, SP=1
---------------------------------------------- is_G=1
xxxx r3=c, push r3, SP=2
---------------------------------------------- is_G=1
xxxx r4=d, push r4, SP=3
---------------------------------------------- is_G=0
push stack[4]=arg_n 3
push stack[5]=ret_addr
call Foo, SP=6
accessging arg0 stack[1]
accessging arg1 stack[2]
accessging arg2 stack[3]
f_ans: r2=stack[1]
---------------------------------------------- is_G=0
r1=r1 + r2
-----------------------------------
### SP=1
### PASSED
-----------------------------------
As you can see, the answer returned by the function can be of any size, even a super large struct would be accepted if it passed the "(strong) types check", and at the low level, there is absolutely no performance problem with this approach on linear stack machines, because it's the natural way their hardware operates.
The above come from the description of the "ijvm" (integer java virtual) machine designed by Andrew S. Tanenbaum. I have modified it a bit, but it's still didactic toy, funny and useful for my researching.