93 lines
4.6 KiB
Plaintext
93 lines
4.6 KiB
Plaintext
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
|