Expressions
expression |
bytecode |
|---|---|
<expr> |
expr |
<(expr)> |
expr |
<expr; o1=e1, o2=e2> |
expr |
text |
load_str string-pool-index |
true |
true |
false |
false |
a |
load_local attribute-index ; if a is template argument |
i |
load_local attribute-index |
i0 |
load_local attribute-index |
a |
load_attr a-string-pool-index |
a.b |
load_attr a ; from now now, a means its string index |
a.(b) |
load_attr a |
t() |
new t,0 ; string pool index of t |
super.r() |
super_new region_t_r,0 ; region r in template t |
t(e1,e2,e3) |
e1 |
t(...) |
args |
t(a1=e1,a2=e2,a3=e3) |
args |
t(a1=e1,a2=e2,...) |
args |
(expr)(args) |
expr |
a:t() |
load_attr a |
a:t(x) |
load_attr a |
a:t(),u() |
load_attr a |
a,b:t() |
load_attr a |
first(expr) |
expr |
[a,b,c] |
list |
Anonymous templates
expression |
bytecode |
|---|---|
{t} |
new _subN,0 |
a:{x | ...} |
load_attr a |
a,b:{x,y | ...} |
load_attr a |
If statements
upon if, create 'end' label.
upon else, create 'else' label.
statement |
bytecode |
|---|---|
<if(a)>t<endif> |
load_attr a |
<if(a)>t<else>u<endif> |
load_attr a |
<if(a)>t<elseif(b)>u<else>v<endif> |
load_attr a |
<if(!a)>t<endif> |
load_attr a |
a||b |
load_attr a |
a&&b |
load_attr a |
Auto-indentation
expr |
bytecode |
|---|---|
<expr>\n |
expr |
\n\t<expr> |
newline |
Size limitations
I use unsigned shorts not ints for the bytecode operands and addresses. This limits size of templates but not the output size. In single template, you can have only 64k of
- attributes
- unique property name refs
- unique template name refs
- options (there are only about 5 now)
- lists or template names in a map/iteration operation
- bytecodes (short addressed)
- chunks of text outside of expressions. effectively same thing as saying can have at most 64k / n expressions where n is avg size of bytecode to emit an expression. E.g., 3 bytes to write a chunk of text.