mirror of
				https://github.com/Reuh/candran.git
				synced 2025-10-27 17:59:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			121 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| #!/usr/bin/env lua
 | |
| 
 | |
| local candran = require("candran")
 | |
| local cmdline = require("candran.cmdline")
 | |
| local parse = require("candran.can-parser.parser").parse
 | |
| local pp = require("candran.can-parser.pp")
 | |
| 
 | |
| local args = cmdline(arg)
 | |
| 
 | |
| if #arg < 1 or args.help or args.h then
 | |
| 	print("Candran "..candran.VERSION.." compiler by Reuh")
 | |
| 	print("Usage: "..arg[0].." [options] filenames...")
 | |
| 	print("Use - instead of filenames to read from the standard input. The output file will be named stdin.lua by default.")
 | |
| 	print("Compiler options:")
 | |
| 	print("  dest=\"directory\"  where compiled files should be written")
 | |
| 	print("  out=\"name.lua\"    output filename. By default, will use the same name as the input file with a .lua extension.")
 | |
| 	print("  -print            write to the standard output instead of creating files")
 | |
| 	print("  -preprocess       only run the preprocessor")
 | |
| 	print("  -compile          only run the compiler")
 | |
| 	print("  -parse            only parse the file and prints errors to stdout")
 | |
| 	print("  -ast              (for debugging purposes) only parse the files and dump the AST to stdout")
 | |
| 	print("  -help or -h       print this text")
 | |
| 	print("Default options:")
 | |
| 	for opt, val in pairs(candran.default) do
 | |
| 		if type(val) == "string" then val = val:gsub("\n", "\\n") end
 | |
| 		print(("  %s=%q"):format(opt, val))
 | |
| 	end
 | |
| 	return
 | |
| end
 | |
| 
 | |
| if arg[#arg] == "-" then
 | |
| 	table.insert(args, io.stdin)
 | |
| end
 | |
| 
 | |
| for _, file in ipairs(args) do
 | |
| 	-- Read
 | |
| 	local dest, input
 | |
| 	if file == io.stdin then
 | |
| 		dest = args.out or "stdin.lua"
 | |
| 
 | |
| 		input = io.read("*a")
 | |
| 
 | |
| 		args.chunkname = "stdin"
 | |
| 	else
 | |
| 		dest = args.out or (file:gsub("%.can$", "")..".lua")
 | |
| 
 | |
| 		local inputFile, err = io.open(file, "r")
 | |
| 		if not inputFile then
 | |
| 			io.stderr:write("canc: cannot open "..file..": "..err.."\n")
 | |
| 			os.exit(1)
 | |
| 		end
 | |
| 		input = inputFile:read("*a")
 | |
| 		inputFile:close()
 | |
| 
 | |
| 		args.chunkname = file
 | |
| 	end
 | |
| 
 | |
| 	-- Parse-only situations
 | |
| 	if args.parse or args.ast then
 | |
| 		local ast, err = parse(input, args.chunkname)
 | |
| 		if not ast then
 | |
| 			io.stderr:write("canc: "..err.."\n")
 | |
| 			os.exit(1)
 | |
| 		end
 | |
| 		if args.ast then
 | |
| 			pp.dump(ast)
 | |
| 		end
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	-- Compile and output
 | |
| 	if args.dest then
 | |
| 		dest = args.dest .. "/" .. dest
 | |
| 	end
 | |
| 
 | |
| 	if not args.print then
 | |
| 		print("Compiling "..args.chunkname.." in "..dest)
 | |
| 	end
 | |
| 
 | |
| 	local out = input
 | |
| 	if args.preprocess then
 | |
| 		local r, err = candran.preprocess(out, args)
 | |
| 		if not r then
 | |
| 			io.stderr:write("canc: "..err.."\n")
 | |
| 			os.exit(1)
 | |
| 		end
 | |
| 		out = r
 | |
| 	end
 | |
| 	if args.compile then
 | |
| 		local r, err = candran.compile(out, args)
 | |
| 		if not r then
 | |
| 			io.stderr:write("canc: "..err.."\n")
 | |
| 			os.exit(1)
 | |
| 		end
 | |
| 		out = r
 | |
| 	end
 | |
| 	if args.compile == nil and args.preprocess == nil then
 | |
| 		local r, err = candran.make(input, args)
 | |
| 		if not r then
 | |
| 			io.stderr:write("canc: "..err.."\n")
 | |
| 			os.exit(1)
 | |
| 		end
 | |
| 		out = r
 | |
| 	end
 | |
| 
 | |
| 	if args.print then
 | |
| 		print(out)
 | |
| 	else
 | |
| 		local outFile, err = io.open(dest, "w")
 | |
| 		if not outFile then
 | |
| 			os.execute("mkdir -p "..dest:gsub("[^/]+%.lua$", ""))
 | |
| 			outFile, err = io.open(dest, "w")
 | |
| 			if not outFile then
 | |
| 				io.stderr:write("canc: cannot open "..dest..": "..err)
 | |
| 				os.exit(1)
 | |
| 			end
 | |
| 		end
 | |
| 		outFile:write(out)
 | |
| 		outFile:close()
 | |
| 	end
 | |
| end
 |