def let(self, vm, bindings): variables = list(bindings[Symbol('variables')] or []) values = list(bindings[Symbol('values')] or []) if len(values) != len(variables): raise SyntaxError('let bindings need a value') compiler = mania.compiler.SimpleCompiler(types.Nil()) for name in variables: if ':' in name.value and any(c != ':' for c in name.value): raise types.ExpandError() compiler.builder.add( instructions.Store(compiler.builder.constant(name))) for node in bindings[Symbol('body')]: compiler.compile_any(node) compiler.builder.add(instructions.Eval()) compiler.builder.add(instructions.Return()) size = compiler.builder.index() compiler.builder.add(instructions.LoadCode(0, size)) compiler.builder.add(instructions.BuildFunction()) if Symbol('name') in bindings: name = bindings[Symbol('name')] if ':' in name.value and any(c != ':' for c in name.value): raise types.ExpandError() compiler.builder.add( instructions.Store(compiler.builder.constant(name))) compiler.builder.add( instructions.Load(compiler.builder.constant(name))) for value in values: compiler.compile_any(value) compiler.builder.add(instructions.Eval()) compiler.builder.add(instructions.Call(len(values))) compiler.builder.add(instructions.Return()) entry_point = compiler.builder.index() compiler.builder.add(instructions.LoadCode(size, entry_point - size)) compiler.builder.add(instructions.BuildFunction()) compiler.builder.add(instructions.Call(0)) module = compiler.builder.module module.entry_point = entry_point return [ module.code(module.entry_point, len(module) - module.entry_point) ]
def compile_function(self, bindings): parameters = bindings[Symbol('parameters')] or [] body = bindings[Symbol('body')] or [] compiler = mania.compiler.SimpleCompiler(types.Nil()) empty_check = None for i, parameter in enumerate(parameters): if ':' in parameter.value and any(c != ':' for c in parameter.value): raise types.ExpandError() if i + 1 < len(parameters) and isinstance(parameters[i + 1], Ellipsis): if i + 2 < len(parameters): raise mania.types.ExpandError() empty_check = compiler.builder.add(None) compiler.compile_any(types.Nil()) loop = compiler.builder.add(instructions.BuildPair()) end = compiler.builder.add(None) compiler.builder.add(instructions.Jump(loop)) index = compiler.builder.index() compiler.compile_any(types.Nil()) store = compiler.builder.add(instructions.Reverse()) compiler.builder.add( instructions.Store(compiler.builder.constant(parameter))) if empty_check is not None: compiler.builder.replace(end, instructions.JumpIfSize(1, store)) compiler.builder.replace(empty_check, instructions.JumpIfEmpty(index)) break for node in body: compiler.compile_any(node) compiler.builder.add(instructions.Eval()) compiler.builder.add(instructions.Return()) compiler.builder.entry_point = compiler.builder.index() compiler.builder.add( instructions.LoadCode(0, compiler.builder.entry_point)) compiler.builder.add(instructions.BuildFunction()) return compiler
def define_value(vm, bindings): name = bindings[Symbol('name')] if ':' in name.value and any(c != ':' for c in name.value): raise types.ExpandError() compiler = mania.compiler.SimpleCompiler(types.Nil()) compiler.compile_any(bindings[Symbol('value')]) compiler.builder.add(instructions.Eval()) compiler.builder.add(instructions.Duplicate(1)) compiler.builder.add( instructions.Store(compiler.builder.constant(name))) module = compiler.builder.module return [ module.code(module.entry_point, len(module) - module.entry_point) ]
def define_module(self, vm, bindings): name = bindings[Symbol('name')] if ':' in name.value and '' in name.value.split(':'): raise types.ExpandError() code = Pair.from_sequence( [Symbol('define-module'), name, bindings[Symbol('exports')]]) code.concat(bindings[Symbol('body')]) compiler = mania.compiler.SimpleCompiler(name) compiler.compile_any(code) compiler.builder.add(mania.instructions.Eval()) compiler.builder.add(mania.instructions.Exit()) module = compiler.builder.module vm.process.scheduler.node.registered_modules[name] = module return []
def define_module(self, vm, bindings): name = bindings[Symbol('name')] if ':' in name.value and '' in name.value.split(':'): raise types.ExpandError() compiler = mania.compiler.SimpleCompiler(name) for element in bindings[Symbol('body')]: compiler.compile_any(element) compiler.builder.add(instructions.Eval()) compiler.compile_any(name) compiler.compile_any(bindings[Symbol('exports')]) compiler.builder.add(instructions.BuildModule()) compiler.builder.add(instructions.Exit()) module = compiler.builder.module return [ module.code(module.entry_point, len(module) - module.entry_point) ]