581 lines
14 KiB
Plaintext
581 lines
14 KiB
Plaintext
|
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
|