Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
lcode.e - 2002sep29

Summary: one way to implement a Forth-like language on top of Lua is
to write an inner interpreter that runs code stored in a Lua array;
the cells of that array can be used to store arbitrary Lua values, not
just integers in a certain range, and I can start with a very simple
interpreter that runs "L-code" consisting mainly of strings and Lua
functions... then I can gradually change it into something that runs
"real bytecodes" that can be reimplemented in C. This file contains
some notes about that.



"mem" in flua: there's an array "mem" where numbered positions
correspond to "memory positions" - "cells", whose content is generally
a number, or a string (that gets translated to a number).

There's another dictionary that associates names -> numbers (for
compilation); when we define a dictionary function from interpretation
mode it gets an entry in that dictionary, and another that is a
function that when executed in interp mode will call the "compiled
version".





Implementar um array "nameof" pra eu poder mostrar funções e outros
baratinhos mais facilmente. Aliás, ele não precisa ser sempre um
array... não, não vou complicar tanto por enquanto (Lua não é Forth!),
ele vai ser um array sim. Depois eu mudo, se for o caso.


Sobre a compilação: um array "mem"; um certo número de estados, cada
um dado por uma função (em princípio só tenho os estados "head" e
"forth"; ou melhor, state_head e state_forth); o interpretador
simplesmente "while state do state() done".




#*
mylua -e '

push = function( stack, val ) tinsert(stack, 1, val) end
pop  = function( stack )      return tremove(stack, 1) end

mem = {}

rstack = {}
rpush = function( val ) push(rstack, val) end
rpop  = function( )     return pop(rstack) end

dstack = {}
dpush = function( val ) push(dstack, val) end
dpop  = function( )     return pop(dstack) end

state_forth = function( )
  local what_to_run = mem[ip]
  ip = ip + 1
  if type(what_to_run) == "number" then
    state = state_head
    rpush(ip)
    ip = what_to_run
  else
    what_to_run()	-- non-numbers are "primitives".
  end
end

state_head = function( )
  local what_to_run = mem[ip]
  ip = ip + 1
  what_to_run()		-- all my heads are primitives right now
end

f_exit = function( ) ip = pop(rstack); if ip == nil then state = nil end end
f_lit  = function( ) dpush(mem[ip]); ip = ip + 1 end

f_dup  = function( ) local v = dpop(); dpush(v); dpush(v) end
f_star = function( ) dpush(dpop()*dpop()) end
f_dot  = function( ) p(dpop()) end

h_forth = function( ) state = state_forth end

set_many = function( table, start, ... )
  for i = 1,getn(arg) do
    table[start] = arg[i]
    start = start + 1
  end
end

f_square = 0
set_many(mem, f_square,   h_forth, f_dup, f_star, f_exit)
f_cube = f_square + 4
set_many(mem, f_cube,     h_forth, f_dup, f_square, f_star, f_exit)
f_demo = f_cube + 5
set_many(mem, f_demo,     h_forth, f_lit, 5, f_cube, f_dot, f_exit)

ip = f_demo
state = state_head
while state do state() end
'

#*


-- (find-luanode "Table Constructors")
-- (find-luanode "Function Definitions")
-- (find-luanode "For Statement")

Próximos passos: adicionar um rstack e uns demos com variáveis (a l
Forth) e outros baratos; modificar o asText pra ele aceitar um
dicionário (ou uma função dicionário) que converta alguns carinhas de
modo especial, e fazer com que o tratamento dele de índices string não
bugue em strings com chars estranhos; criar um "dicionário para o modo
de compilação", em que cada string (um word) esteja associado ao
código que o compile; i.e., "." -> function( ) mem[here] = f_dot; here
= here + 1 end, etc.


# (find-angg "miniforth/macro2.lua")
# (find-angg "miniforth/")
# (find-angg "miniforth/miniforth1.lua")
# (find-angg "miniforth/crim/")


# (find-luanode "")

# (find-luanode "Lua Stand-alone")

# (find-luanode "type")
mylua -e 'print(type(function () end))'		;# "function"
mylua -e 'print(type("foo"))'			;# "string"
mylua -e 'print(type(22))'			;# "number"
mylua -e 'print(type(22.57))'			;# "number"

mylua -e 'p(push)'

# (find-angg ".zshrc" "lua")