mirror of
https://github.com/Reuh/candran.git
synced 2025-10-27 09:59:29 +00:00
- Changed name to Candran
- Do a real code parsing
* Removed lexer.lua
* Added LuaMinify
- Removed -- and ++ operators (see issue #2)
- Added decorators
- Preprocessor : renamed include to import and rawInclude to include
- Updated test.lua
- Updated table.lua
- Updated README.md
- Fixed tons of things
170 lines
No EOL
4.9 KiB
Text
170 lines
No EOL
4.9 KiB
Text
--[[
|
|
Candran language, preprocessor and compiler by Thomas99.
|
|
|
|
LICENSE :
|
|
Copyright (c) 2015 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.
|
|
]]
|
|
|
|
local candran = {
|
|
VERSION = "0.1.0",
|
|
syntax = {
|
|
assignment = { "+=", "-=", "*=", "/=", "^=", "%=", "..=" },
|
|
decorator = "@"
|
|
}
|
|
}
|
|
package.loaded["candran"] = candran
|
|
|
|
#import("lib.table")
|
|
#import("lib.LuaMinify.Util")
|
|
#import("lib.LuaMinify.Scope")
|
|
#import("lib.LuaMinify.ParseCandran")
|
|
#import("lib.LuaMinify.FormatIdentityCandran")
|
|
|
|
-- Preprocessor
|
|
function candran.preprocess(input, args)
|
|
-- generate preprocessor
|
|
local preprocessor = "return function()\n"
|
|
|
|
local lines = {}
|
|
for line in (input.."\n"):gmatch("(.-)\n") do
|
|
table.insert(lines, line)
|
|
-- preprocessor instructions (exclude shebang)
|
|
if line:match("^%s*#") and not (line:match("^#!") and #lines == 1) then
|
|
preprocessor ..= line:gsub("^%s*#", "") .. "\n"
|
|
else
|
|
preprocessor ..= "output ..= lines[" .. #lines .. "] .. \"\\n\"\n"
|
|
end
|
|
end
|
|
preprocessor ..= "return output\nend"
|
|
|
|
-- make preprocessor environement
|
|
local env = table.copy(_G)
|
|
env.candran = candran
|
|
env.output = ""
|
|
env.import = function(modpath, autoRequire)
|
|
local autoRequire = (autoRequire == nil) or autoRequire
|
|
|
|
-- get module filepath
|
|
local filepath
|
|
for _,search in ipairs(package.searchers) do
|
|
local loader, path = search(modpath)
|
|
if type(loader) == "function" and type(path) == "string" then
|
|
filepath = path
|
|
break
|
|
end
|
|
end
|
|
if not filepath then error("No module named \""..modpath.."\"") end
|
|
|
|
-- open module file
|
|
local f = io.open(filepath)
|
|
if not f then error("Can't open the module file to import") end
|
|
local modcontent = f:read("*a")
|
|
f:close()
|
|
|
|
-- get module name (ex: module name of path.to.module is module)
|
|
local modname = modpath:match("[^%.]+$")
|
|
|
|
--
|
|
env.output ..=
|
|
"-- IMPORT OF MODULE \""..modpath.."\" --\n"..
|
|
"local function _()\n"..
|
|
modcontent.."\n"..
|
|
"end\n"..
|
|
(autoRequire and "local "..modname.." = _() or "..modname.."\n" or "").. -- auto require
|
|
"package.loaded[\""..modpath.."\"] = "..(autoRequire and modname or "_()").." or true\n".. -- add to package.loaded
|
|
"-- END OF IMPORT OF MODULE \""..modpath.."\" --\n"
|
|
end
|
|
env.include = function(file)
|
|
local f = io.open(file)
|
|
if not f then error("Can't open the file to 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(candran.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 candran.compile(input)
|
|
local parse = require("lib.LuaMinify.ParseCandran")
|
|
local format = require("lib.LuaMinify.FormatIdentityCandran")
|
|
|
|
local success, ast = parse.ParseLua(input)
|
|
if not success then error("Error while parsing the file :\n"..tostring(ast)) end
|
|
|
|
local success, output = format(ast)
|
|
if not success then error("Error while formating the file :\n"..tostring(output)) end
|
|
|
|
return output
|
|
end
|
|
|
|
-- Preprocess & compile
|
|
function candran.make(code, args)
|
|
local preprocessed = candran.preprocess(code, args or {})
|
|
local output = candran.compile(preprocessed)
|
|
|
|
return output
|
|
end
|
|
|
|
-- Standalone mode
|
|
if debug.getinfo(3) == nil and arg then
|
|
-- Check args
|
|
if #arg < 1 then
|
|
print("Candran version "..candran.VERSION.." by Thomas99")
|
|
print("Command-line usage :")
|
|
print("lua candran.lua <filename> [preprocessor arguments]")
|
|
return candran
|
|
end
|
|
|
|
-- Parse args
|
|
local inputFilepath = arg[1]
|
|
local 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()
|
|
|
|
-- Make
|
|
print(candran.make(input, args))
|
|
end
|
|
|
|
return candran |