# # These libraries are part of the ETA C Compiler project by Stephen Sykes # # Copyright (C) 2003 Stephen Sykes # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Stephen Sykes - etacc.9.sts@xoxy.net # #################################################################### # # Dereference functions used by string library # #################################################################### $s_temp = EtaInt.new def cstack_deref_to_temp eif($c.topval<0) { $s_temp.val = $globals[$c.topval + $globalsize] } eelse { $s_temp.val = $l[$c.topval] } end def estack_deref_to_temp eif($e.topval<0) { $s_temp.val = $globals[$e.topval + $globalsize] } eelse { $s_temp.val = $l[$e.topval] } end #################################################################### # # Printf # #################################################################### $printf_args = EtaArray.new(12) $printf_inpercent = EtaInt.new $printf_argpos = EtaInt.new class Printf def Printf.do(arity) (arity-1).downto(0) {|i| $e.pop $printf_args.set(i, EtaImmediate.instance) $ea.chomp } $c.push($printf_args.get(0)) $printf_inpercent.val = 0 $printf_argpos.val = 1 cstack_deref_to_temp ewhile($s_temp != 0) { eif($printf_inpercent == 1) { eif($s_temp == ?d) { eprint $printf_args[$printf_argpos] $printf_argpos.val = $printf_argpos + 1 } eif($s_temp == ?c) { cprint $printf_args[$printf_argpos] $printf_argpos.val = $printf_argpos + 1 } eif($s_temp == ?%) { eprint "%" } eif($s_temp == ?s) { $c.push($printf_args[$printf_argpos]) cstack_deref_to_temp ewhile($s_temp != 0) { cprint $s_temp $c.inctopval cstack_deref_to_temp } $c.chomp $printf_argpos.val = $printf_argpos + 1 } $printf_inpercent.val = 0 } eelse { eif($s_temp == ?%) { $printf_inpercent.val = 1 } eelse { cprint $s_temp } } $c.inctopval cstack_deref_to_temp } $c.chomp $e.push(0) # return value $ea.push(0) # null end end #################################################################### # # Getchar # #################################################################### class Getchar def Getchar.do(arity) $e.push(input) $ea.push(0) # null end end #################################################################### # # Putchar # #################################################################### class Putchar def Putchar.do(arity) $e.topval write('o') end end #################################################################### # # Astack - general purpose stack made from EtaArrays # #################################################################### class Astack def initialize(size, fsize) @size = size @fsize = fsize @s = EtaArray.new(size) @top = EtaInt.new(-1) if (fsize > 0) @frames = EtaArray.new(fsize) @ftop = EtaInt.new(-1) end @temp = EtaInt.new end def push(x) get_1_arg(x) @top.val = @top + 1 eif (@top == @size) { eprint("!!\n") eexit } @s[@top] = EtaImmediate.instance end def push_next_line @top.val = @top + 1 eif (@top == @size) { eprint("!!\n") eexit } @s[@top] = $p.linenumber + 7 end def [](n) @s[n] end def []=(n,v) @s[n] = v end def local2abs(n) @frames[@ftop] + n + 1 end def topval @s[@top] end def topval=(n) @s[@top] = n end def inctopval @s[@top] = @s[@top] + 1 end def dectopval @s[@top] = @s[@top] - 1 end def pop @s[@top] @top.val = @top - 1 EtaImmediate.instance end def chomp @top.val = @top - 1 end def newframe(n) @ftop.val = @ftop + 1 eif (@ftop == @fsize) { eprint("Frame stack overflow\n") eexit } @frames[@ftop] = @top @top.val = @top + n end def popframe @top.val = @frames[@ftop] @ftop.val = @ftop - 1 end end #################################################################### # # deref_assignment - code to assign value to a location (*x = y) # address should be on top of the stack, value below # #################################################################### def deref_assignment(ass_op) $e.chomp # useless value, we are interested in the address only eif ($ea.topval<0) { if (ass_op == "=") $globals[$ea.pop + $globalsize] = $e.topval else eval("$globals[$ea.topval + $globalsize] = $globals[$ea.topval + $globalsize] #{ass_op[0..-2]} $e.topval") $ea.chomp end } eelse { if (ass_op == "=") $l[$ea.pop] = $e.topval else eval("$l[$ea.topval] = $l[$ea.topval] #{ass_op[0..-2]} $e.topval") $ea.chomp end } end #################################################################### # # dereference # #################################################################### def dereference $ea.topval=$e.topval eif($ea.topval<0) { $e.topval = $globals[$ea.topval + $globalsize] } eelse { $e.topval = $l[$ea.topval] } end #################################################################### # # postinc # #################################################################### def postinc eif($ea.topval<0) { $globals[$ea.topval + $globalsize] = $globals[$ea.topval + $globalsize] + 1 } eelse { $l[$ea.topval] = $l[$ea.topval] + 1 } end #################################################################### # # postdec # #################################################################### def postdec eif($ea.topval<0) { $globals[$ea.topval + $globalsize] = $globals[$ea.topval + $globalsize] - 1 } eelse { $l[$ea.topval] = $l[$ea.topval] - 1 } end #################################################################### # # preinc # #################################################################### def preinc postinc $e.inctopval end #################################################################### # # predec # #################################################################### def predec postdec $e.dectopval end