From 523526f40e3f357e21eeb9f669bac0105b507734 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sat, 9 Jul 2016 23:52:32 -0700 Subject: [PATCH] Improve arg parsing a bit, including parsing arbitrary flags for later use. Got (after a bunch of linker pain solved by just linking in LLVM-3.8 plain and not messing with llvm-config at all) a LLVM example working --- kraken.krak | 29 ++++++++++------- llvm.krak | 78 ++++++++++++++++++++++++++++++++++++++++++++++ stdlib/string.krak | 1 + 3 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 llvm.krak diff --git a/kraken.krak b/kraken.krak index 499057b..be43657 100644 --- a/kraken.krak +++ b/kraken.krak @@ -47,19 +47,24 @@ fun main(argc: int, argv: **char):int { var interpret_instead = false var opt_str = string("-O3") var line_ctrl = false - if (!doing_repl) { - var argv1_str = string(argv[1]) - if (argv1_str == "-i") { + var positional_args = vector() + var flags = set() + for (var i = 1; i < argc; i++;) { + var arg_str = string(argv[i]) + if (arg_str == "-i") { interpret_instead = true - input_file_offset++ - } else if (argv1_str.length() > 2 && argv1_str.slice(0,2) == "-O") { - opt_str = argv1_str - input_file_offset++ - } else if (argv1_str == "-g") { + } else if (arg_str.length() > 2 && arg_str.slice(0,2) == "-O") { + opt_str = arg_str + } else if (arg_str == "-g") { line_ctrl = true - input_file_offset++ + } else if (arg_str.length() > 2 && arg_str.first() == '-') { + flags.add(arg_str.slice(1,-1)) + } else { + positional_args.add(arg_str) } } + /*positional_args.for_each(fun(i:string) println("positional_arg: " + i);)*/ + flags.for_each(fun(i:string) println("flag: " + i);) if (file_exists(compiled_name)) { var pos = 0 @@ -119,10 +124,10 @@ fun main(argc: int, argv: **char):int { } } - var kraken_file_name = string(argv[input_file_offset]) + var kraken_file_name = positional_args[0] var executable_name = string(".").join(kraken_file_name.split('.').slice(0,-2)) - if (argc == input_file_offset+2) - executable_name = string(argv[input_file_offset+1]) + if (positional_args.size > 1) + executable_name = positional_args[1] var importer.construct(parsers, ast_pass, vector(string(), base_dir + "/stdlib/")): importer importer.import(kraken_file_name) // Passes diff --git a/llvm.krak b/llvm.krak new file mode 100644 index 0000000..09890f4 --- /dev/null +++ b/llvm.krak @@ -0,0 +1,78 @@ +import vector_literals: * +import string:* +import io:* +import mem: * +import util: * +import os: * + +obj LLVMModule {} +obj LLVMType {} +obj LLVMValue {} +obj LLVMGenericValue {} +obj LLVMBasicBlock {} +obj LLVMBuilder {} +obj LLVMExecutionEngine {} + +ext fun LLVMModuleCreateWithName(ModuleID: *char): *LLVMModule +ext fun LLVMInt32Type(): *LLVMType +ext fun LLVMFunctionType(ret_type: *LLVMType, param_types: **LLVMType, ParamCount: uint, isVarArg: int): *LLVMType +ext fun LLVMAddFunction(mod: *LLVMModule, name: *char, rettype: *LLVMType): *LLVMValue +ext fun LLVMAppendBasicBlock(func: *LLVMValue, name: *char): *LLVMBasicBlock +ext fun LLVMCreateBuilder(): *LLVMBuilder +ext fun LLVMPositionBuilderAtEnd(builder: *LLVMBuilder, block: *LLVMBasicBlock) +ext fun LLVMGetParam(func: *LLVMValue, num: int): *LLVMValue +ext fun LLVMBuildAdd(builder: *LLVMBuilder, first: *LLVMValue, second: *LLVMValue, name: *char): *LLVMValue +ext fun LLVMBuildRet(builder: *LLVMBuilder, value: *LLVMValue): *LLVMValue +ext fun LLVMVerifyModule(M: *LLVMModule, Action: int, error: **char): int +var LLVMAbortProcessAction = 1 +ext fun LLVMDisposeMessage(error: *char) +ext fun LLVMLinkInMCJIT() +/*ext fun LLVMInitializeNativeTarget(): bool*/ +ext fun LLVMInitializeX86Target(): bool +ext fun LLVMCreateExecutionEngineForModule(engine: **LLVMExecutionEngine, M: *LLVMModule, error: **char): int +ext fun LLVMCreateGenericValueOfInt(Ty: *LLVMType, N: ulong, IsSigned: int): *LLVMGenericValue +ext fun LLVMRunFunction(EE: *LLVMExecutionEngine, F: *LLVMValue, NumArgs: uint, Args: **LLVMGenericValue): *LLVMGenericValue +ext fun LLVMGenericValueToInt(GenVal: *LLVMGenericValue, IsSigned: int): ulong + +#link("LLVM-3.8") + +fun main(argc: int, argv: **char): int { + var mod = LLVMModuleCreateWithName("my_module") + var param_types = vector(LLVMInt32Type(), LLVMInt32Type()) + var ret_type = LLVMFunctionType(LLVMInt32Type(), param_types.getBackingMemory(), (2) cast uint, 0) + var sum = LLVMAddFunction(mod, "sum", ret_type) + var entry = LLVMAppendBasicBlock(sum, "entry") + var builder = LLVMCreateBuilder() + LLVMPositionBuilderAtEnd(builder, entry) + var tmp = LLVMBuildAdd(builder, LLVMGetParam(sum,0), LLVMGetParam(sum,1), "tmp") + LLVMBuildRet(builder, tmp) + + var error = null() + LLVMVerifyModule(mod, LLVMAbortProcessAction, &error) + LLVMDisposeMessage(error) + + var engine: *LLVMExecutionEngine + error = null() + LLVMLinkInMCJIT() + /*LLVMInitializeNativeTarget()*/ + // LLVMInitializeNativeTarget is static/inline :/ + LLVMInitializeX86Target() + + if (LLVMCreateExecutionEngineForModule(&engine, mod, &error)) { + error("Failed to create execution engine") + } + if (error) { + println(string("error: ") + error) + LLVMDisposeMessage(error) + exit(1) + } + if (argc < 3) error(string("usage: ") + argv[0] + " x y") + var x = string_to_num(string(argv[1])) + var y = string_to_num(string(argv[2])) + var args = vector(LLVMCreateGenericValueOfInt(LLVMInt32Type(), x, 0), + LLVMCreateGenericValueOfInt(LLVMInt32Type(), y, 0)) + var res = LLVMRunFunction(engine, sum, 2u, args.getBackingMemory()) + println(string("result: ") + (LLVMGenericValueToInt(res, 0)) cast int) + return 0 +} + diff --git a/stdlib/string.krak b/stdlib/string.krak index 89959b0..0da50eb 100644 --- a/stdlib/string.krak +++ b/stdlib/string.krak @@ -239,6 +239,7 @@ obj string (Object, Serializable) { out.add(current) return out } + fun first(): char return data.first() fun last(): char return data.last() fun lines(): vector::vector return split('\n') fun split(delim: char): vector::vector {