// Hidden vars (os, args, core_path, use_mcode) come from env // args[0] = script name, args[1..] = user args var load_internal = os.load_internal function use_embed(name) { return load_internal("js_" + name + "_use") } var fd = use_embed('fd') var json = use_embed('json') var use_cache = {} use_cache['fd'] = fd use_cache['os'] = os use_cache['json'] = json // Bootstrap: load tokenize.cm and parse.cm from pre-compiled AST JSON function use_basic(path) { if (use_cache[path]) return use_cache[path] var result = use_embed(replace(path, '/', '_')) use_cache[path] = result return result } var tok_ast_path = "tokenize.ast.json" var par_ast_path = "parse.ast.json" var tokenize_mod = mach_eval_ast("tokenize", text(fd.slurp(tok_ast_path)), {use: use_basic}) var parse_mod = mach_eval_ast("parse", text(fd.slurp(par_ast_path)), {use: use_basic}) var fold_ast_path = "fold.ast.json" var fold_mod = mach_eval_ast("fold", text(fd.slurp(fold_ast_path)), {use: use_basic}) // Optionally load mcode compiler module var mcode_mod = null var mcode_ast_path = "mcode.ast.json" if (use_mcode) { mcode_mod = mach_eval_ast("mcode", text(fd.slurp(mcode_ast_path)), {use: use_basic}) } // analyze: tokenize + parse, check for errors function analyze(src, filename) { var tok_result = tokenize_mod(src, filename) var ast = parse_mod(tok_result.tokens, src, filename, tokenize_mod) var _i = 0 var prev_line = -1 var prev_msg = null var e = null var msg = null var line = null var col = null var has_errors = ast.errors != null && length(ast.errors) > 0 if (has_errors) { while (_i < length(ast.errors)) { e = ast.errors[_i] msg = e.message line = e.line col = e.column if (msg != prev_msg || line != prev_line) { if (line != null && col != null) { print(`${filename}:${text(line)}:${text(col)}: error: ${msg}`) } else { print(`${filename}: error: ${msg}`) } } prev_line = line prev_msg = msg _i = _i + 1 } disrupt } ast = fold_mod(ast) return ast } // Run AST through either mcode or mach pipeline function run_ast(name, ast, env) { var compiled = null if (use_mcode) { compiled = mcode_mod(ast) return mcode_run(name, json.encode(compiled), env) } return mach_eval_ast(name, json.encode(ast), env) } // use() with ƿit pipeline for .cm modules function use(path) { var file_path = path + '.cm' var script = null var ast = null var result = null if (use_cache[path]) return use_cache[path] // Check CWD first, then core_path if (!fd.is_file(file_path)) file_path = core_path + '/' + path + '.cm' if (fd.is_file(file_path)) { script = text(fd.slurp(file_path)) ast = analyze(script, file_path) result = run_ast(path, ast, {use: use}) use_cache[path] = result return result } // Fallback to embedded C module result = use_embed(replace(path, '/', '_')) use_cache[path] = result return result } // Load and run the user's program var program = args[0] var script_file = program // Add .ce extension if not already present if (!ends_with(script_file, '.ce') && !ends_with(script_file, '.cm')) script_file = program + '.ce' var user_args = [] var _j = 1 while (_j < length(args)) { push(user_args, args[_j]) _j = _j + 1 } var script = text(fd.slurp(script_file)) var ast = analyze(script, script_file) run_ast(program, ast, {use: use, args: user_args, json: json})