News : The level of daily SPAM has reached insane proportions, all registrations are now manual. I ask you to send me an e-mail (john (at) murga (dot) org), to confirm that you want me to create an account for you.

Post Reply  Post Thread 
Interactive Fish interpreter
Author Message

Posts: 113
Group: Registered
Joined: Jul 2007
Status: Offline
Reputation: 0
Post: #1
RE: Interactive Fish interpreter

I've been coding this interactive fish interpreter, because it's a really nice language ( I'm almost there, but I can't get the output window to redraw when using the run button (which goes into a loop calling the main coroutine). So I can't see the individual characters being printed.

Using the step button (which just resumes the coroutine once) does work.

Any Ideas? This is the code:

-- configuration --
demo=[["hello, world"r> ?o?<;]]
-- end config --

-- parsing different commands
p=z.insert    -- push
P=z.remove    -- pop
W=function(...) win.output_buffer:append(...) end
t="><^v/\\|_#x+-*,%=)(!?:~$@&r}{gponi;[].mX"        -- all tokens
"z=P(s.s)if z~=0 then p(s.s,P(s.s)/z)else error'Div by 0'end","y=P(s.s)z=P(s.s)p(s.s,z%y)", -- div
"p(s.s,P(s.s)==P(s.s) and 1 or 0)",
"p(s.s,P(s.s)>P(s.s) and 1 or 0)",
"p(s.s,P(s.s)<P(s.s) and 1 or 0)",
"if #s.s==0 or s.s[#s.s]==0 then f['!'](s) end",
"z=#s.s s.s[z],s.s[z-1]=s.s[z-1],s.s[z]",
"z=#s.s s.s[z],s.s[z-1],s.s[z-2]=s.s[z-1],s.s[z-2],s.s[z]",
"if s.r then p(s.s,s.r)s.r=nil else s.r=P(s.s)end",
"if s.s==s.l then z=s.l s.l={}s.s=s.l else z=S S={}s.s=S end for k=1,#z do s.s[#z-k+1]=z[k]end",
"z=P(s.s) p(s.s,c[P(s.s)][z])",
"z,w=P(s.s),P(s.s) c[w][P(s.s)]=z",
" if not z then p(s.s,4)else while z:match'%s'do not z then z='\\4'end end p(s.s,B(z))end",
"fltk.fl_message('Fish program quit')step=coroutine.create(function()return end) coroutine.resume(step)", --"os.exit()", -- TODO modify!
"P(T,,#T do T[k].id=k end", -- update after removing a thread.
"s.s = s.s==S and s.l or S",
"z= s.s==S and s.l or S for k=#s.s,1,-1 do p(z,P(s.s,1))end",
function dbg(s)
    print("Current Stack:",s.s==s.l and "Local Stack" or "Global Stack")
    print("Local stack:")
    for k,v in pairs(s.l) do print("",k,v,v>=0 and string.char(v) or "NEG") end
    print("Global stack:")
    for k,v in pairs(S) do print("",k,v,v>=0 and string.char(v) or "NEG") end
    print("Register: ",s.r)
    for k=0,#c do
        io.write(string.format("%0"..#tostring(#c).."i",k),": ")
        for l=0,#c[k] do

-- Linking commands to functions
for k in t:gmatch"." do -- will contain the tokens
    --TODO setfenv / setmetatable to avoid all indexing in functions.

T={        -- table of threads
    --nt = new thread to be created.
c={}    -- codebox IP wraps around
S={}    -- global stack
-- codebox layout
--     -----> +x
--  @  |line of text            -- wrap around to second line
--     |second line of text.    -- negative indices can be used for variables
--     |
--     V +Y

-- y first coord, x second
-- wrap around rows if nil row
-- wrap around cols if nil char.
function T.n(T,x,y,dx,dy) -- New thread function
    id=#T+1,                    -- keep number id
    l={},                    -- local stack
    dx=dx or 1,                    -- 1 for +x, -1 for -x, 0 for y/-y
    dy=dy or 0,                    -- 1 for +y, -1 for -y, 0 for x/-x
    x=x or 0,                    -- X of IP
    y=y or 0,                    -- Y of IP
    -- i,                    -- will contain type of quote when reading in a string
    -- r,                    -- registry
        if s.y > #c then
        elseif s.y<0 then
        if s.x>#c[s.y] and s.dx==1 then
        elseif s.x<0 then
    z.s=z.l -- current stack is local stack
    T[]=z    -- add at next index

function run()
-- compile to codebox
--fh= arg[1] and[1]) or io.stdin    -- use file or stdin
-- Todo: find a way to "lock" the editor.
while pos<=win.edt_buffer:length() do
    c[y]=M({},{__index=function()return 32 end})--default to space
    local l = win.edt_buffer:line_text(pos)
    for k=1,#l do
        local z=l:sub(k,k)
        if not i then        -- normal mode
            if F(z,"['\"]") then i=z end
            if F(z,"[^\n\r]")then --filter out only newlines
            end -- any spacing allowed.
        else                -- verbatim string mode
            if z==i then i=nil end

while #T>0 do
    for id=1,#T do --TODO make that f[q] uses the correct stacks etc.
        s:m()                                        -- move the IP
        n,o=s.dx,s.dy -- keep old directions for new thread detection
        if s.i then                        -- stringparsing mode        
            if F(q,"['\"]") then        -- end-quote
                p(s.s,c[s.y][s.x])    -- push contents of box, then advance
        else                             -- not in string parsing mode
            if F(q,"['\"]") then        -- start-quote
            elseif F(q,"%x") then        -- parsing a number
            elseif F(q,"[^ ]") then
                f[q](s)    -- call, feed with state/thread
    if T.nt and (n~=s.dx or o~=s.dy) then
        -- create new thread
        s.dx,s.dy=n,o        -- restore directions of parent

step = coroutine.create(run)

win = {}
  win.window = fltk:Fl_Double_Window(334, 210, 565, 355, "Fish interpreter")
    win.edt_buffer = fltk:Fl_Text_Buffer()
    win.edt = fltk:Fl_Text_Editor(25, 25, 260, 280)

    win.output_buffer = fltk:Fl_Text_Buffer()
    win.output = fltk:Fl_Text_Display(285, 25, 260, 280)

    win.rol = fltk:Fl_Roller(105, 320, 45, 25, "Delay")
    win.rol_output = fltk:Fl_Value_Output(160, 320, 50, 25)
    win.rol:callback(function() win.rol_output:value(win.rol:value()) end)

    local o = fltk:Fl_Button(215, 320, 70, 25, "Back")
    o:callback( function() print"Back button not implemented" end)
    local o = fltk:Fl_Button(285, 320, 70, 25, "Step")
    o:callback( function() coroutine.resume(step) end)
    local o = fltk:Fl_Return_Button(355, 320, 70, 25, "Run")
        while coroutine.status(step)~="dead" do
            print("step, sleeping for "
            coroutine.resume(step) win.window:show() win.output:redraw()



05-06-2011 01:36 AM
Find all posts by this user Quote this message in a reply
Post Reply  Post Thread 

Messages In This Thread
Interactive Fish interpreter - jpjacobs - 04-21-2011, 08:09 PM
RE: Texteditor - mikshaw - 04-22-2011, 12:43 AM
RE: Texteditor - jpjacobs - 04-22-2011, 08:14 PM
RE: Interactive Fish interpreter - jpjacobs - 05-06-2011 01:36 AM
RE: Interactive Fish interpreter - mikshaw - 05-06-2011, 11:23 PM

View a Printable Version
Send this Thread to a Friend
Subscribe to this Thread | Add Thread to Favorites

Forum Jump: