2020-06-21 14:14:57 -05:00

52 lines
1.9 KiB
Plaintext

class IR
rule
program: func program {result=[val[0],val[1]].flatten} | func {result=[val[0]]}
func: IDENT LPAREN RPAREN block {result={:name=>val[0],:code=>val[3]}}
block: LCURL lines RCURL {result=val[1]}
lines: line lines {result=[val[0],val[1]].flatten} | line {result=[val[0]]}
line: stmt SEMICOLON {result=val[0]}
| ASM {result={:type=>:asmline,:line=>val[0].chop}}
stmt: IDENT EQUAL expr {result={:type=>:set,:var=>val[0],:expr=>val[2]}}
| IDENT LBRACK IDENT RBRACK EQUAL expr {result={:type=>:arrayset,:off=>val[2],:base=>val[0],:expr=>val[5]}}
| IDENT LBRACK NUM RBRACK EQUAL expr {result={:type=>:arrayset,:off=>val[2],:base=>val[0],:expr=>val[5]}}
| TYPE IDENT NUM {result={:type=>:type,:var=>val[1],:typ=>val[2]}}
| IDENT LPAREN RPAREN {result={:type=>:call,:func=>val[0]}}
| ASTERISK IDENT LPAREN RPAREN {result={:type=>:callpoint,:func=>val[1]}}
expr: ASTERISK IDENT {result={:type=>:deref,:addr=>val[1]}}
| IDENT LBRACK IDENT RBRACK {result={:type=>:array,:off=>val[2],:base=>val[0]}}
| IDENT LBRACK NUM RBRACK {result={:type=>:array,:off=>val[2],:base=>val[0]}}
| NUM {result={:type=>:num,:val=>val[0]}}
| IDENT {result={:type=>:var,:var=>val[0]}}
| IDENT PLUS IDENT {result={:type=>:add,:v1=>val[0],:v2=>val[2]}}
| IDENT MINUS IDENT {result={:type=>:sub,:v1=>val[0],:v2=>val[2]}}
| IDENT PIPE IDENT {result={:type=>:bitor,:v1=>val[0],:v2=>val[3]}}
| TILDE IDENT {result={:type=>:inv,:val=>val[1]}}
end
---- inner
def parse(input)
scan_str(input)
end
def get_label(label)
if @labels[label]
return make_bytes(@labels[label])
else
return [label]+[0]*7
end
end
def make_bytes(val)
bytes=[]
8.times do |i|
mask=0xFF << i*8
byte=(val&mask) >> i*8
bytes.push byte
end
return bytes
end
def defed_label(label)
for index in @bytes.each_index.select {|index| @bytes[index]==label}
@bytes[index,8]=make_bytes(@labels[label])
end
end