lis.p8/lisp.p8

581 lines
14 KiB
Lua
Raw Permalink Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

pico-8 cartridge // http://www.pico-8.com
version 32
__lua__
-- utils / globals
local none = {}
--have to do this before i make
--any functions
local wraps = {}
for k,v in pairs(_ENV) do
if type(v)=="function" then
wraps[#wraps + 1]={k=k, v=v,}
end
end
function is_sym(s)
return type(s) == "string"
and sub(s,1,1) != ";"
end
function is_num(n)
return type(n) == "number"
end
function is_fun(f)
return type(f) == "function"
end
function is_tab(t)
return type(t) == "table"
and t != none
end
function is_str(s)
return type(s) == "string"
and sub(s,1,1) == ";"
end
function is_bool(b)
return type(b) == "boolean"
end
--todo:
--can this be made faster ?
function rest(t)
local function r_1(fst, ...)
return {...}
end
return r_1(unpack(t))
end
function deep_copy(v)
if not is_tab(v) then
return v
end
local c = {}
for key = 1, #v do
--for key in pairs(v) do
c[key] = deep_copy(v[key])
end
return c
end
--todo: this is limitted to 2
--args, it's kinda missleading
--ig, tho i doubt anyone else
--will be using this func
--todo: see if this needs to /
--can be spead up
function bind(func, ...)
local args = {...}
local function copy(t)
return pack(unpack(t))
end
return function(a, b)
local args_2 = copy(args)
args_2[#args + 1] = a
args_2[#args + 2] = b
return func(unpack(args_2))
end
end
function list_tostr(l, s)
if l == none then
return s .. "none"
end
if type(l)=="table" then
s = s .. "("
for i = 1, #l do
if(i > 1) s = s .. " "
s = list_tostr(l[i], s)
end
s = s .. ")"
return s
end
if is_str(l) then
return
s.."\""..sub(l,2).."\""
end
return s .. tostr(l)
end
function chr_size(c)
return ord(c) < 128 and 4 or 8
end
function replace(s, a, b)
local r = ""
for i = 1, #s do
local c = sub(s, i, i)
if c == a then
c = b
end
r = r .. c
end
return r
end
-->8
-- tokenizer
--[[ todo:
generisize token_str + com ?
--]]
--::tok,rst,type
--[[
"pun" = puncuation
"ws" = whitespace
"sym" = symbol
"num" = number
"end" = end of input
"str" = string
"com" = comment
--]]
function token_str(s, hk)
for i = 2, #s do
if(hk) hk(sub(s,i,i))
if sub(s,i,i) == "\"" then
return sub(s, 1, i),
sub(s,i + 1), "str"
end
end
return s, "", "str" --no end
end
function token_com(s, hk)
for i = 2, #s do
if(hk) hk(sub(s,i,i))
if sub(s,i,i) == "\n" then
return sub(s, 1, i),
sub(s,i + 1), "com"
end
end
return s, "", "com" --eof
end
function token_1(s, hk)
local fst,rst = sub(s,1,1),
sub(s,2)
if(hk) hk(fst)
if(s=="")return "","","end"
if fst == "\"" then
return token_str(s, hk)
end
if fst == ";" then
return token_com(s, hk)
end
if fst == " "
or fst == "\n"
or fst == "\t" then
local t,r,tp = token_1(rst,hk)
if tp == "ws" then
return fst..t, r, "ws"
end
return fst, rst, "ws"
end
if fst == "("
or fst == ")"
or fst == "'"
or fst == "`"
or fst == ","
or fst == "@" then
return fst, rst, "pun"
end
local t,r,tp = token_1(rst,hk)
if tp == "sym" then
return fst..t, r, "sym"
end
return fst,rst,"sym"
end
function token(s, hk)
local t,r,tp = token_1(s, hk)
if tonum(t) != nil then
return tonum(t),r,"num"
end
return t,r,tp
end
-->8
-- parser
--[[ todo:
collect line numbers ?
--]]
function parse(src)
local t, rst, tp = token(src)
if tp=="ws"
or tp=="com" then
return parse(rst) end
if t == "'" then
t, rst, tp = parse(rst)
return {"quote",t}, rst, tp
end
if t == "`" then
t, rst, tp = parse(rst)
return {"backquote",t}, rst, tp
end
if t == "," then
t, rst, tp = parse(rst)
return {"comma",t}, rst, tp
end
if tp == "str" then
return ";" .. sub(t,2,#t-1),
rst, tp
end
if t == "(" then
local list = {}
while true do
t, rst, tp = parse(rst)
if(t == ")") break
if tp == "end" then
print("err, unclosed paren")
break
end
add(list, t)
end
return list, rst, tp
end
return t, rst, tp
end
-->8
-- env
#include env.lua
-->8
-- lib
#include lib.lua
-->8
-- eval
#include eval.lua
eval(parse([[
(do
(def! push (\ (l a)
(join l (list a))))
(def! bq-fold (\ (acc ast)
(push acc
(if (tab? ast)
(if (= ([] ast 1) 'comma)
([] ast 2)
(fold bq-fold '(list) ast))
(list 'quote ast)))))
(defmacro! backquote (\ (ast)
(fold bq-fold '(list) ast))))
]]), lib, function(val)
--
end)
-->8
cls()
lisp_src = [[
;; edit example
(?! 69 "steamed hams") ;comment
(do
(def! add-or-sub (\ (func)
(func 10 18)))
(add-or-sub (\ (a b)
(?! a b)
(= a b))))
(do
(def! add-or-sub (\ (func)
(func 10 18)))
(add-or-sub (\ (a b)
(?! a b)
(= a b))))
(do
(def! farts (list 69 420 666))
(def! combo (\ (acc l)
(?! "combo:" acc l)
(+ acc l)))
(fold combo 0 farts))
(do
(def! thing 1)
(def! adder (\ (num)
; unamed second function
(\ (a)
; unamed third function
(\ (b)
(+ a b num)))
))
(def! crap (adder 4))
(def! dung (crap 2))
(dung 1)
;((adder 4) 2) -> dung
(dung 63))
(do
(def! cownter (let ((c 0))
(\ (a)
(set! c (+ c a))
(?! c))))
(cownter 1)
(cownter 5)
(cownter 2))
(do
(def! uwu (\ (x y)
(set! x (- 0 x))
(set! y (- 0 y))
(camera x y)
(color 5)
(line 10 98 10 88)
(line 10 98 50 98)
(line 50 88 50 98)
(line 50 88 40 88)
(line 20 88 10 88)
(line 20 88 20 60)
(line 40 88 40 60)
(line 40 60 20 60)
(line 40 70 20 70)
(line 30 65 30 60)))
(cls 1)
(uwu 50 0)
(uwu 0 0)
(uwu 25 -48))
(do
(defmacro! bee
(let ((bees 0)) (\ (val)
(set! bees (+ 1 bees))
`(?! ,bees ,val))))
(def! a 6)
(def! b "trees")
(bee b)
(bee "yeet")
(bee ((\() "yeet")))
(bee "tank")
(bee "yank")
(bee "gank"))
(def! draw (let ()
(def! l (\ (c)
(def! x (rnd 128))
(def! y (rnd 128))
(def! u (rnd 128))
(def! v (rnd 128))
(line x y u v c)
(spr 1 (- x 4) (- y 4))
(circ u v 4)))
(def! jump 0)
(\ ()
(call/cc (\ (c)
(set! jump c)))
(cls 15)
(cursor 1 1)
(color 0)
(?! (stat 0))
(map 0 0)
(if (< 0 (btn))
(?! "hi"))
(l 1) (l 0)
(l 1) (l 0)
(l 1) (l 0)
(l 1) (l 0))))
]]
lisp_src = replace(lisp_src,
"\t", " ")
list,rst = parse(lisp_src)
print(list_tostr(list, ""))
local enviro = {
__p = lib,
__t = {},
["true"] = true,
["false"] = false,
["none"] = none,
}
local err = eval(list, enviro,
function(v)
print(list_tostr(v, "-> "))
end)
if(err) print("err: " .. tostr(err))
-->8
-- edit
--[[
todo:
--]]
function draw_line(s, y)
if y > 128 or y < -6 then
return
end
local x = 0
local cols = {
str=3, com=13, num=12, sym=6,
bound=14, lib=11,
}
local t, rst, tp = token(s)
while tp != "end" do
color(7)
if cols[tp] then
color(cols[tp])
end
if lib[t] then
color(cols.lib)
end
if enviro[t] then
color(cols.bound)
end
x = print(t, x, y)
t, rst, tp = token(rst)
end
end
function draw_code(y)
cls(0)
local src=split(lisp_src, "\n")
for i = 1, #src do
draw_line(src[i], y+ i * 6 - 6)
--print(src[i])
end
end
-->8
-- draw
if enviro.draw then
function _draw()
local err = enviro.draw({},
enviro, function(v)end)
if err then
color(7)
?err
stop()
end
end
else
local scroll = 0
function _draw()
draw_code(scroll)
if(btn())scroll += 6
if(btn())scroll -= 6
end
end
__gfx__
00000000008888000033330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000002200000000220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700002200000000220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000088aa8000036633000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000a88aa8a00636633600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700a88aa8a00636633600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000088888000033333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000080080000003003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
03333330333330003333330300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33333333333333333333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33333333333333333332233300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
03332223332223233333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
03333332333233333333232300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33333333333332333333233300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33332333323333333333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33333233322333333333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
03333323333333333333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
03333333333333333332333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33233333333222332333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33333333223333333333333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
32323233233333333332333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33333333333322323333333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33323333333332233333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00333333333333333332333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33333333333333333322333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33333333333333333333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33333333332332333333323300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
32323322223333333332333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33223333323333233233333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33333333333333333332333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
03332333333333333333333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
30333303330033300333333000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__map__
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000002021220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000003031320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000004041420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000202121212200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000404141414200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000