Commits

Bart van Strien  committed 7e59bc4

Implement tons more special forms, should be near workable now

  • Participants
  • Parent commits 59115ae

Comments (0)

Files changed (5)

File fplua/compiler.lua

 local reader = require "fplua.reader"
+local utils = require "fplua.utils"
 
 local infixOps = {
 	["+"] = true, ["-"] = true, ["/"] = true,
 		end
 		output = ("do\n%s\nend"):
 			format(table.concat(subBlocks, "\n"))
-	elseif command == "function" then
+	elseif command == "function" or command == "function=" then
 		local args = {}
 		local subBlocks = {}
+		local name = ""
+		if command == "function=" then
+			name = table.remove(ast, 1)
+		end
 		for i, v in ipairs(table.remove(ast, 1)) do
 			table.insert(args, v)
 		end
 		for i, v in ipairs(ast) do
 			table.insert(subBlocks, compileItem(v))
 		end
-		output = ("function(%s)\n%s\nend"):
-			format(table.concat(args, ", "),
+		output = ("function %s(%s)\n%s\nend"):
+			format(name, table.concat(args, ", "),
 				table.concat(subBlocks, "\n"))
 	elseif command == "local" then
 		output = ("local %s "):format(ast[1])
+	elseif command == "local=" then
+		output = ("local %s = %s"):format(ast[1],
+			compileItem(ast[2]))
+	elseif command == "if" then
+		local condition = compileItem(ast[1])
+		local thenbranch = compileItem(ast[2])
+		local elsebranch = ""
+		if #ast > 2 then
+			elsebranch = ("\nelse\n%s"):format(compileItem(ast[3]))
+		end
+		output = ("if %s then\n%s%s\nend"):format(condition, thenbranch, elsebranch)
+	elseif command == "for=" then
+		local var = table.remove(ast, 1)
+		local values = table.concat(
+			table.remove(ast, 1), ", ")
+		local subBlocks = {}
+		for i, v in ipairs(ast) do
+			table.insert(subBlocks, compileItem(v))
+		end
+		output = ("for %s = %s do\n%s\nend"):format(
+			var, values,
+			table.concat(subBlocks, "\n"))
+	elseif command == "for" then
+		local vars = table.concat(
+			table.remove(ast, 1), ", ")
+		local generator = compileItem(table.remove(ast, 1))
+		local subBlocks = {}
+		for i, v in ipairs(ast) do
+			table.insert(subBlocks, compileItem(v))
+		end
+		output = ("for %s in %s do\n%s\nend"):format(
+			vars, generator,
+			table.concat(subBlocks, "\n"))
 	elseif command == "while" then
 		local subBlocks = {}
 		for i, v in ipairs(ast) do
 		end
 		output = ("while %s do\n%s\nend"):
 			format(table.remove(subBlocks, 1), table.concat(subBlocks, "\n"))
+	elseif command == "until" then
+		local subBlocks = {}
+		for i, v in ipairs(ast) do
+			table.insert(subBlocks, compileItem(v))
+		end
+		output = ("repeat\n%s\nuntil %s"):
+			format(table.remove(subBlocks, 1), table.concat(subBlocks, "\n"))
+	elseif command == "[]" then
+		output = ("(%s)[%s]"):format(ast[1], compileItem(ast[2]))
+	elseif command == "return" then
+		local subBlocks = {}
+		for i, v in ipairs(ast) do
+			table.insert(subBlocks, compileItem(v))
+		end
+		output = ("return %s"):format(table.concat(subBlocks, ", "))
+	elseif command == "break" then
+		output = "break"
 	elseif infixOps[command] then
 		local out = {}
 		for i, v in ipairs(ast) do
 		for i, v in ipairs(ast) do
 			table.insert(out, compileItem(v))
 		end
+		if type(command) == "table" and command.ast then
+			command = ("(%s)"):format(compileItem(command))
+		end
 		output = ("%s(%s)"):format(command, table.concat(out, ", "))
 	end
 	return output
 	return item
 end
 
-local function dumptree(tree, prefix)
-	prefix = prefix or ""
-	for i, v in ipairs(tree) do
-		if type(v) == "table" then
-			dumptree(v, prefix .. "  ")
-		else
-			print(prefix .. v)
-		end
-	end
-end
-
 local function compileChunk(chunk)
 	local ast = reader("do " .. chunk)
 
-	--dumptree(ast)
+	--utils.dumptree(ast)
 	return compileItem(ast)
 end
 

File fplua/fplua.lua

-local fplua = {
+local fplua = setmetatable({
 	reader = require "fplua.reader",
 	compileChunk = require "fplua.compiler"
-}
+}, {__index = require "fplua.utils"})
 
 function fplua.loadstring(s)
 	return loadstring(fplua.compileChunk(s))
 	return nil, "No fplua file found in path"
 end
 
-table.insert(package.loaders, fplua.require)
-
 return fplua

File fplua/init.lua

-return require "fplua.fplua"
+local fplua = require "fplua.fplua"
+
+table.insert(package.loaders, fplua.require)
+
+return fplua

File fplua/reader.lua

 				insexpr == 0 and
 				not escape then
 			word = table.concat(word)
-			word = word:match("^%s*(%S-)%s*$")
+			word = word:match("^%s*(.-)%s*$")
 			if word and #word > 0 then
 				table.insert(tree, word)
 			end
-(= reduce
-  (function (f list)
-    (local a)
-	(local b)
-	(= a (table.remove list 1))
-	(while (> (# list) 0)
-	  (= b (table.remove list 1))
-	  (= a (f a b)))
-	(return a)))
+(function= reduce (f list)
+  (local= a (table.remove list 1))
+  (local b)
+  (while (> (# list) 0)
+    (= b (table.remove list 1))
+    (= a (f a b)))
+  (return a))
 
-(= polynomial
-  (function (coefs x)
-    (return
-	  (reduce
-	    (Λ (a b)
-		  (return (+ (* a x) b)))
-		coefs))))
+(function= polynomial (coefs x)
+  (return
+    (reduce
+      (Λ (a b)
+  	  (return (+ (* a x) b)))
+  	coefs)))
 
-(assert
+(local= result
+  (polynomial
+    {5 8 -3} 5))
+(if
   (==
-    (polynomial
-      {5 8 -3} 5)
-	  162))
+    result
+    ([] {162} 1))
+  (print "Correct results have been found")
+  (error (.. "It all went to shit, it was " result " but we wanted " 162)))
 
 (print (polynomial
   {2 8 1 4} 9))