Headers = []
at_exit {
code = []
Headers.each{|x| code << "#include <#{x}.h>" }
code << "int main() {"
Stack.each{|x|
code << "#{make_indent}#{x};"
}
code << " return 0;"
code << "}"
puts code
open('a.c', 'w') {|f| f.puts code }
puts "---------------------------"
system 'gcc -w -lm a.c && ./a.out'
}
Pos = :__pos__
@indent = 2
def make_indent
" " * @indent
end
Stack = []
def double(name = fresh, value = 0)
Stack.push "double #{name} = #{value}"
name.to_sym
end
class T
def self.fresh
@id ||= 0
@id += 1
"v_#{@id}"
end
def method_missing(type, name = T.fresh, value = 0)
if Numeric === name
name, value = T.fresh, name
end
Stack.push "#{type} #{name} = #{value}"
name.to_sym
end
end
t = T.new
def getargs(*args)
args.reverse.map{|x|
case x
when Pos
Stack.pop
when String
x.inspect
else
x
end
}.reverse
end
def ref(a)
r = getargs(a)
Stack.push "&#{r[0]}"
Pos
end
class O
def method_missing(sym, *args)
a = getargs(*args)
Stack.push("((#{a.join(") #{sym} (")}))")
Pos
end
end
o = O.new
class D
def method_missing(sym, *args)
a = getargs(*args)
Stack.push("#{sym}(#{a.join(", ")})")
Pos
end
end
class C
def method_missing(sym, *)
Headers.push(sym) unless Headers.include?(sym)
::D.new
end
end
c = C.new
c.stdio.printf("%lf", o.+(c.math.sqrt((a = t.double 2)), a))