include asm.e include graphics.e ? text_rows(50) --constant -- EAX=0, EBX=3, ECX=1, EDX=2, ESP=4, EBP=5, ESI=6, EDI=7, -- AL=0, BL=3, CL=1, DL=2, -- AH=4, BH=7, CH=5, DH=6 function peek_object(atom address) sequence result atom a a = peek4s(address) if integer(a) then return a end if address = and_bits(a,#3FFFFFFF)*4 if a > 0 then return float64_to_atom(peek({address,8})) else result = repeat(0, peek4u(address)) for i = 1 to length(result) do result[i] = peek_object(address + 4*i) end for return result end if end function function encode_object(object o) atom address, k if integer(o) then return o end if if atom(o) then address = allocate(8) poke(address, atom_to_float64(o)) return or_bits(#40000000, floor(address / 4)) end if address = allocate(4 + 4 * length(o)) poke4(address, length(o)) for i = 1 to length(o) do poke4(address+i*4,encode_object(o[i])) end for return or_bits(#80000000, floor(address / 4)) end function function allocate_object(object o) atom address address = allocate(4) poke4(address, encode_object(o)) return address end function include smart.e asm_output(1,1) constant return_ = "\nmov esp,ebp\npop ebp"& "\nret" sequence arguments, variables, globals, global_addys arguments = {} variables = {} globals = {} global_addys = {} function Find(sequence name) if find(name, arguments) then return sprintf("dword ptr [ebp+%d]", 4*find(name, arguments)) end if if find(name, variables) then return sprintf("dword ptr [ebp-%d]", 4*find(name, variables)) end if if find(name, globals) then return sprintf("dword ptr [#%x]", global_addys[find(name, globals)]) end if end function function func(sequence code) --puts(1, code) return get_asm("push ebp\nmov ebp,esp\n" & code & return_) end function function get(sequence name) return "mov eax, "&Find(name)&" ; get "&name&"\n" end function function set(sequence name) return "mov "&Find(name)&", eax ; set "&name&"\n" end function function gets(sequence name) return "push "&Find(name)&" ; get "&name&"\n" end function function sets(sequence name) return "pop "&Find(name)&" ; set "&name&"\n" end function function declare_global(sequence name, atom address) globals &= {name} global_addys &= {address} return address end function function const(atom i) return sprintf("mov eax, #%x ; const %d\n", {i,i}) end function function consts(atom i) return sprintf("push dword #%x ; const %d\n", {i,i}) end function function funcall(sequence name) return sprintf("jmp near #%x ; funcall %s\n", { global_addys[find(name, globals)], name}) end function function subscript_assign(sequence name, sequence subscripts, object rval) sequence result integer esp result = "" esp = 0 for i = 1 to length(subscripts) do if sequence(subscripts[i]) then result &= subscripts[i] esp += 4 end if end for if sequence(rval) then result &= rval&"\nmov ecx, eax\n" rval = "ecx" else rval = sprintf("%d", {rval}) end if result &= "mov eax, "&Find(name)&" ; get "&name&"\n" for i = 1 to length(subscripts)-1 do result &= "shl eax, 2\n" if sequence(subscripts[i]) then esp -= 4 result &= sprintf("mov edx, [esp+%d]\nmov eax, [eax+edx*4]\n",{esp}) else result &= sprintf("mov eax, [eax+#%x]\n", {subscripts[i]*4}) end if end for result &= "shl eax, 2\n" if sequence(subscripts[length(subscripts)]) then esp -= 4 result &= sprintf("mov edx, [esp+%d]\nmov dword ptr [eax+edx*4], %s\n", {esp,rval}) else result &= sprintf("mov dword ptr [eax+#%x], %s\n", {subscripts[length(subscripts)]*4, rval}) end if return result end function arguments = {"arg"} variables = {"var"} constant foo = declare_global("foo", allocate_object({{0,{0,0,0}}})) constant f1 = declare_global("f1", func( const(1)& set("foo"))) constant f2 = func(funcall("f1")) constant f3 = func(subscript_assign("foo", {consts(1),consts(2),consts(3)}, 1)) printf(1,"%x\n", f2 ) call(f3) ? peek_object(foo)