mirror of
https://github.com/Reuh/candran.git
synced 2025-10-27 17:59:30 +00:00
180 lines
No EOL
4.8 KiB
Lua
180 lines
No EOL
4.8 KiB
Lua
#!/usr/bin/lua
|
|
--[[
|
|
Lune language & compiler by Thomas99.
|
|
|
|
LICENSE :
|
|
Copyright (c) 2014 Thomas99
|
|
|
|
This software is provided 'as-is', without any express or implied warranty.
|
|
In no event will the authors be held liable for any damages arising from the
|
|
use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose, including
|
|
commercial applications, and to alter it and redistribute it freely, subject
|
|
to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software. If you use this software in a
|
|
product, an acknowledgment in the product documentation would be appreciated
|
|
but is not required.
|
|
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
misrepresented as being the original software.
|
|
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
]]
|
|
#include("lib/lexer.lua")
|
|
#include("lib/table.lua")
|
|
|
|
local lune = {}
|
|
lune.VERSION = "0.0.1"
|
|
lune.syntax = {
|
|
affectation = { ["+"] = "= %s +", ["-"] = "= %s -", ["*"] = "= %s *", ["/"] = "= %s /",
|
|
["^"] = "= %s ^", ["%"] = "= %s %%", [".."] = "= %s .." },
|
|
incrementation = { ["+"] = " = %s + 1" , ["-"] = " = %s - 1" },
|
|
}
|
|
|
|
-- Preprocessor
|
|
function lune.preprocess(input, args)
|
|
-- generate preprocessor
|
|
local preprocessor = "return function()\n"
|
|
|
|
local lines = {}
|
|
for line in (input.."\n"):gmatch("(.-)\n") do
|
|
table.insert(lines, line)
|
|
if line:sub(1,1) == "#" then
|
|
-- exclude shebang
|
|
if not (line:sub(1,2) == "#!" and #lines ==1) then
|
|
preprocessor ..= line:sub(2) .. "\n"
|
|
else
|
|
preprocessor ..= "output ..= lines[" .. #lines .. "] .. \"\\n\"\n"
|
|
end
|
|
else
|
|
preprocessor ..= "output ..= lines[" .. #lines .. "] .. \"\\n\"\n"
|
|
end
|
|
end
|
|
preprocessor ..= "return output\nend"
|
|
|
|
-- make preprocessor environement
|
|
local env = table.copy(_G)
|
|
env.lune = lune
|
|
env.output = ""
|
|
env.include = function(file)
|
|
local f = io.open(file)
|
|
if not f then error("can't open the file to include") end
|
|
|
|
local filename = file:match("([^%/%\\]-)%.[^%.]-$")
|
|
|
|
env.output ..=
|
|
"-- INCLUSION OF FILE \""..file.."\" --\n"..
|
|
"local function _()\n"..
|
|
f:read("*a").."\n"..
|
|
"end\n"..
|
|
"local "..filename.." = _() or "..filename.."\n"..
|
|
"-- END OF INCLUDSION OF FILE \""..file.."\" --\n"
|
|
|
|
f:close()
|
|
end
|
|
env.rawInclude = function(file)
|
|
local f = io.open(file)
|
|
if not f then error("can't open the file to raw include") end
|
|
env.output ..= f:read("*a").."\n"
|
|
f:close()
|
|
end
|
|
env.print = function(...)
|
|
env.output ..= table.concat({...}, "\t") .. "\n"
|
|
end
|
|
env.args = args or {}
|
|
env.lines = lines
|
|
|
|
-- load preprocessor
|
|
local preprocess, err = load(lune.compile(preprocessor), "Preprocessor", nil, env)
|
|
if not preprocess then error("Error while creating preprocessor :\n" .. err) end
|
|
|
|
-- execute preprocessor
|
|
local success, output = pcall(preprocess())
|
|
if not success then error("Error while preprocessing file :\n" .. output .. "\nWith preprocessor : \n" .. preprocessor) end
|
|
|
|
return output
|
|
end
|
|
|
|
-- Compiler
|
|
function lune.compile(input)
|
|
local output = ""
|
|
|
|
local last = {}
|
|
for t,v in lexer.lua(input, {}, {}) do
|
|
local toInsert = v
|
|
|
|
-- affectation
|
|
if t == "=" then
|
|
if table.hasKey(lune.syntax.affectation, last.token) then
|
|
toInsert = string.format(lune.syntax.affectation[last.token], last.varName)
|
|
output = output:sub(1, -1 -#last.token) -- remove token before =
|
|
end
|
|
end
|
|
|
|
-- self-incrementation
|
|
if table.hasKey(lune.syntax.incrementation, t) and t == last.token then
|
|
toInsert = string.format(lune.syntax.incrementation[last.token], last.varName)
|
|
output = output:sub(1, -#last.token*2) -- remove token ++/--
|
|
end
|
|
|
|
-- reconstitude full variable name (ex : ith.game.camera)
|
|
if t == "iden" then
|
|
if last.token == "." then
|
|
last.varName ..= "." .. v
|
|
else
|
|
last.varName = v
|
|
end
|
|
end
|
|
|
|
last[t] = v
|
|
last.token = t
|
|
last.value = v
|
|
|
|
output ..= toInsert
|
|
end
|
|
|
|
return output
|
|
end
|
|
|
|
-- Preprocess & compile
|
|
function lune.make(code, args)
|
|
local preprocessed = lune.preprocess(code, args or {})
|
|
local output = lune.compile(preprocessed)
|
|
return output
|
|
end
|
|
|
|
-- Standalone mode
|
|
if debug.getinfo(3) == nil and arg then
|
|
-- Check args
|
|
if #arg < 1 then
|
|
print("Lune version "..lune.VERSION.." by Thomas99")
|
|
print("Command-line usage :")
|
|
print("lua lune.lua <filename> [preprocessor arguments]")
|
|
return lune
|
|
end
|
|
|
|
-- Parse args
|
|
local inputFilePath = arg[1]
|
|
local args = {}
|
|
-- Parse compilation args
|
|
for i=2, #arg, 1 do
|
|
if arg[i]:sub(1,2) == "--" then
|
|
args[arg[i]:sub(3)] = arg[i+1]
|
|
i = i +1 -- skip argument value
|
|
end
|
|
end
|
|
|
|
-- Open & read input file
|
|
local inputFile, err = io.open(inputFilePath, "r")
|
|
if not inputFile then error("Error while opening input file : "..err) end
|
|
local input = inputFile:read("*a")
|
|
inputFile:close()
|
|
|
|
-- End
|
|
print(lune.make(input, args))
|
|
end
|
|
|
|
return lune |