-
Notifications
You must be signed in to change notification settings - Fork 0
tstanisl/acmag
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Syntax:
SCRIPT -> {FUNC}
FUNC -> ID '(' [FUNC_ARGS] ')' '{' INST '}'
FUNC_ARGS -> ID {',' ID}
INST -> ';'
INST -> EXPR ';'
INST -> 'return' [ EXPR ] ';'
INST -> 'if' '(' EXPR ')' INST ['else' INST]
INST -> 'for' '(' ID [ ',' ID] ':' EXPR ')' INST
INST -> 'while' '(' EXPR ')' INST
INST -> '{' { INST } '}'
INST -> 'break'
INST -> 'continue'
EXPR -> ORR_EXPR [ '=' EXPR ]
ORR_EXPR -> AND_EXPR { '||' AND_EXPR }
AND_EXPR -> CMP_EXPR { '&&' CMP_EXPR }
CMP_EXPR -> SUM_EXPR { '<' SUM_EXPR }
CMP_EXPR -> SUM_EXPR { '<=' SUM_EXPR }
CMP_EXPR -> SUM_EXPR { '>' SUM_EXPR }
CMP_EXPR -> SUM_EXPR { '>=' SUM_EXPR }
CMP_EXPR -> SUM_EXPR { '==' SUM_EXPR }
CMP_EXPR -> SUM_EXPR { '!=' SUM_EXPR }
SUM_EXPR -> MUL_EXPR { '+' MUL_EXPR }
SUM_EXPR -> MUL_EXPR { '-' MUL_EXPR }
MUL_EXPR -> SNG_EXPR { '*' SNG_EXPR }
MUL_EXPR -> SNG_EXPR { '/' SNG_EXPR }
MUL_EXPR -> SNG_EXPR { '%' SNG_EXPR }
SNG_EXPR -> '+' SNG_EXPR
SNG_EXPR -> '-' SNG_EXPR
SNG_EXPR -> '!' SNG_EXPR
SNG_EXPR -> REF_EXPR
REF_EXPR -> TOP_EXPR { REF_TAIL }
REF_TAIL -> '(' ARGS ')'
REF_TAIL -> '.' ID
ARGS -> [EXPR {',' EXPR}]
TOP_EXPR -> ID
TOP_EXPR -> NUM
TOP_EXPR -> STR
TOP_EXPR -> '(' EXPR ')'
Example:
sword() {
s = weapon();
s.name = "sword";
s.damage = "1d10";
return s;
}
granade_boom(g)
{
a = explosion_area(g.position, 5);
// TODO: add owner here
d = damage_effect("3d6", "fire");
add_area_effect(d, a);
delete(g);
}
granade_start(g)
{
if (a.activated) {
info("Granade is already activated.");
return;
}
a.activated = 1;
// schedule boom in 10 seconds
add_event(g, granade_boom, 10);
}
granade()
{
g = item();
g.name = "granade";
g.activated = 0;
g.on_use = granade_start;
return g;
}
====== Machine ========
Support for commands:
movsp #n
push previous frame pointer on stack, move sp by #n units
ret #a, #b
pop $0 (aka FP) to fp_
copy #b registers to fp[-#a] position
set FP to fp_
retv #b
pop $0 (aka FP) to fp_
pop $-1 (aka n_args) to n_args
copy #b registers to fp[-#n_args] position
set FP to fp_
push $r
push content of register $r on stack
push #n
push integer (12bit) on stack
push *n
push large integer (indexed by 12bit) on stack
push "str"
push string (indexed by 12bit) on stack
pushn #n
push nil #n times on stack
pop $r
pop to regiter $r
popn #n
pop #n times and ignore results
call #n
call global function of index #n
calli #n
call code at offset cur+#n
callb #n
call builin function #n
jz #n
pop stack, if zero pc = pc + #n
jnz #n
pop stack, if non-zero pc = pc + #n
jmp #n
pc = pc + #n
push $r
push #n
push *n
push "str"
pushn #n
pop $r
callg #func
call #func
callb #func
ret #n
jz label
jnz label
jmp label
How it may look like:
a)
x, x_ = 1, 0;
while (x < 1000) {
print(x);
x, x_ = x + x_, x;
}
maps to
push #0
push #1
pop $0
pop $1
L1: push $0
push #1000
call <
jz L2
push $0
call print
push $0
push $1
call +
push $0
pop $1
pop $2
jmp L1
L2:
b)
g.name = "granade";
==>
push "granade"
push "name"
push $0 ; assume that g is in 0
call .
call =
Result 17 instruction == 34 bytes :)
Requirements:
- returning tuples
- functions with variable number of arguments
-
c)
fib(a,b) : 2;
main() {
x, x_ = 1, 0;
while (x < 100)
x, x_ = fib(x, x_);
}
fib(a,b) {
return a + b, a;
}
===>
main: movsp #2
push #0
push #1
pop $1
pop $2
L1: push #100
push $1
call <
jz L2
push $2
push $1
calli fib
pop $1
pop $2
jmp L1
L2: ret #0, #2
fib: push $-1
push $-2
call +
push $-1
ret #2, #2
d)
info(...) {
for (i = 1; i <= arg[0]; ++i)
print(arg[i]);
return i;
}
===>
info: movsp #1
push #1
pop $1
L1: push #0
call arg[]
push $1
call <=
ifz L2
push $0
call arg[]
call print
jmp L1
L2: push $1
retv #1
About
code and tools for never-ending-development game
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published