1
0
Fork 0
mirror of https://github.com/Reuh/candran.git synced 2025-10-27 09:59:29 +00:00

Complete overhaul

- 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
This commit is contained in:
Reuh 2015-02-14 20:23:39 +01:00
parent 18d3acf648
commit 1875ea31de
36 changed files with 11601 additions and 1582 deletions

170
candran.can Normal file
View file

@ -0,0 +1,170 @@
--[[
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