fix .gitignore, Makefile and README.md for 2014/endoh
Unpack src.zip.
This commit is contained in:
1 parent
a7163eafa2
commit
e18e03bff5
20 files changed
+1616
-96
No files matched your search
@@ -0,0 +1,122 @@
|
||||
# translate AST into stack-based instruction sequence
|
||||
|
||||
require_relative "ast-def"
|
||||
|
||||
class PRead
|
||||
def emit
|
||||
[IRead[var]]
|
||||
end
|
||||
end
|
||||
|
||||
class PImm
|
||||
def emit
|
||||
[IPush[num]]
|
||||
end
|
||||
end
|
||||
|
||||
class PNop
|
||||
def emit
|
||||
[INop[]]
|
||||
end
|
||||
end
|
||||
|
||||
class PBinary
|
||||
def emit
|
||||
if op == :<
|
||||
e2.emit + e1.emit + [IBinary[:>]]
|
||||
else
|
||||
e1.emit + e2.emit + [IBinary[op]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class PIfThenElse
|
||||
def emit
|
||||
s1 = e1.emit
|
||||
s2 = e2.emit
|
||||
|
||||
# merge the common tails if any
|
||||
tails = []
|
||||
s1.reverse.zip(s2.reverse) do |i1, i2|
|
||||
break if i1 != i2
|
||||
s1.pop
|
||||
s2.pop
|
||||
tails.unshift i1
|
||||
end
|
||||
|
||||
cond.emit + [IBranch[s1, s2]] + tails
|
||||
end
|
||||
end
|
||||
|
||||
class PARef
|
||||
def emit
|
||||
if e1 == PImm[0] && e2.is_a?(PBinary) && e2.op == :+
|
||||
e2.emit[0..-2] + [IARef[]]
|
||||
elsif e2 == PImm[0] && e1.is_a?(PBinary) && e1.op == :+
|
||||
e1.emit[0..-2] + [IARef[]]
|
||||
else
|
||||
e1.emit + e2.emit + [IARef[]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class PASet
|
||||
def emit
|
||||
if e1 == PImm[0] && e2.is_a?(PBinary) && e2.op == :+
|
||||
e3.emit + e2.emit[0..-2] + [IASet[]]
|
||||
elsif e2 == PImm[0] && e1.is_a?(PBinary) && e1.op == :+
|
||||
e3.emit + e1.emit[0..-2] + [IASet[]]
|
||||
else
|
||||
e3.emit + e2.emit + e1.emit + [IASet[]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class PAssign
|
||||
def emit
|
||||
exp.emit + [IWrite[var != ?_ ? var : nil]]
|
||||
end
|
||||
end
|
||||
|
||||
class PSequence
|
||||
def emit
|
||||
seq.flat_map {|e| e.emit } + e.emit
|
||||
end
|
||||
end
|
||||
|
||||
class PLoop
|
||||
def emit
|
||||
[ILoop[cond.emit, body.flat_map {|e| e.emit }]]
|
||||
end
|
||||
end
|
||||
|
||||
class PTest
|
||||
def emit
|
||||
e.emit + [ITest[]]
|
||||
end
|
||||
end
|
||||
|
||||
class PExit
|
||||
def emit
|
||||
e.emit + [IExit[]]
|
||||
end
|
||||
end
|
||||
|
||||
class POut
|
||||
def emit
|
||||
e.emit + [IOut[]]
|
||||
end
|
||||
end
|
||||
|
||||
class Array
|
||||
def emit
|
||||
flat_map {|e| e.emit }
|
||||
end
|
||||
end
|
||||
|
||||
if ARGV.size != 2
|
||||
puts "usage: #$0 <ast.txt> <seq1.txt>"
|
||||
else
|
||||
ast = eval(File.read(ARGV[0]))
|
||||
File.write(ARGV[1], ast.flat_map {|e| e.emit }.pretty_inspect)
|
||||
end
|
||||
Reference in new issue
Block a user