t64/t64.y

93 lines
4.6 KiB
Plaintext
Raw Permalink Normal View History

2020-06-21 14:14:57 -05:00
class T64
rule
start: {
@code=[]
@labels={}
@ops=["NOT","AND","OR","ADD","SUB","MULL","MULH","MULUL","MULUH",
"DIVL","DIVH","DIVUL","DIVUH","NEG","CMP","ADC","SBB"]
@pos=0
@backpatches={}
@linestarts=[]
@lineends=[]
} program {return @code,@labels,@linestarts,@lineends}
program: line NEWLINE program {} | line NEWLINE {} | NEWLINE {@linestarts.push @pos;@lineends.push @pos} program {} | NEWLINE {@linestarts.push @pos;@lineends.push @pos}
line: IDENT COLON {@startpos=@pos} ins {
@labels[val[0]]=@startpos
defed_label(val[0])
@linestarts.push @startpos
@lineends.push @pos
}
| IDENT COLON {
@labels[val[0]]=@pos
defed_label(val[0])
@linestarts.push @pos
@lineends.push @pos
}
| {@startpos=@pos} ins {
@linestarts.push @startpos
@lineends.push @pos
}
ins: LDB REG COMMA LPAREN IDENT RPAREN {@code.push([0x0,0x10|val[1],0x0,*get_label(val[4])]);@pos+=0x10}
| LDB REG COMMA NUM {@code.push([0x0,val[1],0x0,*val[3][0,1]]);@pos+=0x10}
| LDB REG COMMA REG LPAREN REG RPAREN {@code.push([0x0,0x30|val[1],val[3]<<4|val[5],*val[3,1]]);@pos+=0x10}
| LDB REG COMMA LPAREN REG RPAREN {@code.push([0x0,0x20|val[1],val[4]<<4]);@pos+=0x10}
| LDW REG COMMA NUM {@code.push([0x1,val[1],0x0,*val[3][0,2]]);@pos+=0x10}
| LD REG COMMA NUM {@code.push([0x03,val[1],0x0,*val[3]]);@pos+=0x10}
| LD REG COMMA IDENT {@code.push([0x03,val[1],0x0,*get_label(val[3])]);@pos+=0x10}
| LD REG COMMA LPAREN IDENT RPAREN {@code.push([0x03,0x10|val[1],0x0,*get_label(val[4])]);@pos+=0x10}
| ARB REG COMMA REG COMMA REG COMMA AROP COMMA NUM {@code.push([0x8,0x70|val[1],(val[3]<<4)|val[5],@ops.index(val[7])|(val[9][0]<<7)]);@pos+=0x10}
| ARIB REG COMMA REG COMMA NUM COMMA AROP COMMA NUM {@code.push([0x8,0x80|val[1],(val[3]<<4),@ops.index(val[7]),val[5][0]]);@pos+=0x10}
| ARW REG COMMA REG COMMA REG COMMA AROP COMMA NUM {@code.push([0x9,0x70|val[1],(val[3]<<4)|val[5],@ops.index(val[7])|(val[9][0]<<7)]);@pos+=0x10}
| ARI REG COMMA REG COMMA NUM COMMA AROP COMMA NUM {@code.push([0xb,0x80|val[1],(val[3]<<4),@ops.index(val[7])|((val[9][0])<<7),*val[5]]);@pos+=0x10}
| AR REG COMMA REG COMMA REG COMMA AROP {@code.push([0xb,0x70|val[1],(val[3]<<4)|val[5],@ops.index(val[7])]);@pos+=0x10}
| ST REG COMMA LPAREN REG RPAREN {@code.push([0x7,0x20,(val[4]<<4|val[1])]);@pos+=0x10}
| ST REG COMMA NUM LPAREN IDENT RPAREN {@code.push([0x7,0x40,val[1],*get_label(val[5]),*val[3][0,4]]);@pos+=0x10}
| STB REG COMMA LPAREN IDENT RPAREN {@code.push([0x4,0x10,val[1],*get_label(val[4])]);@pos+=0x10}
| STB REG COMMA NUM LPAREN IDENT RPAREN {@code.push([0x4,0x90,val[1],*get_label(val[5]),*val[3][0,4]]);@pos+=0x10}
| STB REG COMMA REG LPAREN REG RPAREN {@code.push([0x4,0x20,(val[5]<<4|val[1]),val[3]]);@pos+=0x10}
| STB REG COMMA LPAREN REG RPAREN {@code.push([0x4,0x20,(val[4]<<4)|val[1]]);@pos+=0x10}
| JNC LPAREN IDENT RPAREN {@code.push([0x10,0x10,0x0,*get_label(val[2])]);@pos+=0x10}
| JNZ LPAREN IDENT RPAREN {@code.push([0xe,0x10,0x0,*get_label(val[2])]);@pos+=0x10}
| JMP LPAREN IDENT RPAREN {@code.push([0xc,0x10,0x0,*get_label(val[2])]);@pos+=0x10}
| JMP LPAREN REG RPAREN {@code.push([0xc,0x20,val[2]<<4]);@pos+=0x10}
| JMP NUM {@code.push([0xc,0x10,0x0,*val[1]]);@pos+=0x10}
| JNZ NUM {@code.push([0xe,0x10,0x0,*val[1]]);@pos+=0x10}
| JST REG COMMA LPAREN IDENT RPAREN {@code.push([0x11,0x10|val[1],0x0,*get_label(val[4])]);@pos+=0x10}
| HLT {@code.push([0xFF]);@pos+=0x10}
| DB NUM {@code.push([*val[1][0,1]]);@pos+=1}
| DQW NUM {@code.push([*val[1]]);@pos+=8}
| ORG NUM {@pos=val[1].pack("C*").unpack("Q<")}
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)
newcode=[]
for line in @code
for index in line.each_index.select {|index| line[index]==label}
line[index,8]=make_bytes(@labels[label])
end
newcode.push line
end
@code=newcode
end