File: bytecode.md

package info (click to toggle)
stringtemplate4 4.3.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,772 kB
  • sloc: java: 15,537; xml: 305; python: 39; makefile: 2
file content (147 lines) | stat: -rw-r--r-- 3,377 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# Template to Bytecode mapping

## Expressions

|expression|bytecode|
|----------|--------|
|`<expr>`|expr<br>write|
|`<(expr)>`|expr<br>tostr <br>write|
|`<expr; o1=e1, o2=e2>`| expr <br> options <br> e1 <br> store\_option o1-option-index <br> e2 <br>store\_option o2-option-index <br> write\_opt<br>|
|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 <br> load\_prop b|
|`a.(b)`| load\_attr a <br> load\_attr b <br> load\_prop\_ind|
|`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 <br> e2 <br> e3 <br> new t,3|
|`t(...)`| args <br>passthru t <br>new\_box\_args t|
|`t(a1=e1,a2=e2,a3=e3)`| args <br> e1 <br>store\_arg a1 <br>e2 <br>store\_arg a2 <br>e3 <br>store\_arg a3 <br>new\_box\_args t|
|`t(a1=e1,a2=e2,...)`| args<br>  e1<br> store\_arg a1 <br>e2<br> store\_arg a2<br> passthru t<br> new\_box\_args t|
|`(expr)(args)`| expr <br>tostr <br>args <br>new\_ind num-args|
|`a:t()`| load\_attr a <br>null <br>new t,1<br> map|
|`a:t(x)`| load\_attr a<br>null<br> x <br>new t,2<br> map|
|`a:t(),u()`| load\_attr a <br>null <br>new t,1<br> null <br>new u,1 <br>rot\_map 2|
|`a,b:t()`| load\_attr a <br>load\_attr b <br>null <br>null <br>new t,2 <br>zip\_map 2|
|`first(expr)`| expr <br>first        ; predefined function|
|`[`*a*`,`*b*`,`*c*`]`|list<br> a <br> add <br> b <br> add <br> c <br> add|

## Anonymous templates

|expression|bytecode|
|----------|--------|
|`{t}`|new \_subN,0|
|`a:{x | ...}`|load\_attr a<br> null<br> new \_subN, 1<br> map|
|`a,b:{x,y | ...}`|load\_attr a <br>load\_attr b<br> null<br> null<br> new \_subN,2<br> zip\_map 2|

## If statements

upon if, create 'end' label.<br>
upon else, create 'else' label.

`<if(a)>t<endif>`:

```
    load_attr a                                          
    brf end 
    t 
    write 
end:
```

`<if(a)>t<else>u<endif>`:

```
   load_attr a 
    brf else 
    t 
    write 
    br end 
else: 
    u 
    write 
end:
```

`<if(a)>t<elseif(b)>u<else>v<endif>`:

```
    load_attr a 
    brf lab1 
    t 
    write 
    br end 
lab1: 
    load_attr b 
    brf lab2 
    u 
    write 
    br end 
lab2: 
    v 
    write 
end:
```

`<if(!a)>t<endif>`:

```
    load_attr a 
    not 
    brf end 
    t 
    write 
end:
```

`a||b`:

```
    load_attr a 
    load_attr b 
    or
```

`a&&b`:

```
    load_attr a 
    load_attr b 
    and
```

## Auto-indentation

`<expr>`\n:

```
expr 
write 
newline
```

\n\t`<expr>`:

```
newline 
indent "\t" 
expr 
write 
dedent
```

## 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.