|
|
|
|
@@ -1,11 +1,9 @@
|
|
|
|
|
#! /usr/bin/env python
|
|
|
|
|
"""Generate Rust code from an ASDL description."""
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
import sys
|
|
|
|
|
import textwrap
|
|
|
|
|
|
|
|
|
|
import json
|
|
|
|
|
import textwrap
|
|
|
|
|
|
|
|
|
|
from argparse import ArgumentParser
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
@@ -13,7 +11,7 @@ from pathlib import Path
|
|
|
|
|
import asdl
|
|
|
|
|
|
|
|
|
|
TABSIZE = 4
|
|
|
|
|
AUTOGEN_MESSAGE = "// File automatically generated by {}.\n\n"
|
|
|
|
|
AUTOGEN_MESSAGE = "// File automatically generated by {}.\n"
|
|
|
|
|
|
|
|
|
|
builtin_type_mapping = {
|
|
|
|
|
'identifier': 'Ident',
|
|
|
|
|
@@ -390,9 +388,9 @@ class ClassDefVisitor(EmitVisitor):
|
|
|
|
|
self.emit(f"impl {structname} {{", depth)
|
|
|
|
|
self.emit(f"#[extend_class]", depth + 1)
|
|
|
|
|
self.emit("fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) {", depth + 1)
|
|
|
|
|
fields = ",".join(f"ctx.new_str({json.dumps(f.name)})" for f in fields)
|
|
|
|
|
fields = ",".join(f"ctx.new_str(ascii!({json.dumps(f.name)})).into()" for f in fields)
|
|
|
|
|
self.emit(f'class.set_str_attr("_fields", ctx.new_list(vec![{fields}]));', depth + 2)
|
|
|
|
|
attrs = ",".join(f"ctx.new_str({json.dumps(attr.name)})" for attr in attrs)
|
|
|
|
|
attrs = ",".join(f"ctx.new_str(ascii!({json.dumps(attr.name)})).into()" for attr in attrs)
|
|
|
|
|
self.emit(f'class.set_str_attr("_attributes", ctx.new_list(vec![{attrs}]));', depth + 2)
|
|
|
|
|
self.emit("}", depth + 1)
|
|
|
|
|
self.emit("}", depth)
|
|
|
|
|
@@ -401,7 +399,7 @@ class ExtendModuleVisitor(EmitVisitor):
|
|
|
|
|
|
|
|
|
|
def visitModule(self, mod):
|
|
|
|
|
depth = 0
|
|
|
|
|
self.emit("pub fn extend_module_nodes(vm: &VirtualMachine, module: &crate::PyObj) {", depth)
|
|
|
|
|
self.emit("pub fn extend_module_nodes(vm: &VirtualMachine, module: &PyObject) {", depth)
|
|
|
|
|
self.emit("extend_module!(vm, module, {", depth + 1)
|
|
|
|
|
for dfn in mod.dfns:
|
|
|
|
|
self.visit(dfn, depth + 2)
|
|
|
|
|
@@ -488,7 +486,7 @@ class TraitImplVisitor(EmitVisitor):
|
|
|
|
|
self.emit("let _dict = _node.as_object().dict().unwrap();", depth)
|
|
|
|
|
for f in fields:
|
|
|
|
|
self.emit(f"_dict.set_item({json.dumps(f.name)}, {rust_field(f.name)}.ast_to_object(_vm), _vm).unwrap();", depth)
|
|
|
|
|
self.emit("_node.into_object()", depth)
|
|
|
|
|
self.emit("_node.into()", depth)
|
|
|
|
|
|
|
|
|
|
def make_pattern(self, fields):
|
|
|
|
|
return ",".join(rust_field(f.name) for f in fields)
|
|
|
|
|
@@ -505,7 +503,7 @@ class TraitImplVisitor(EmitVisitor):
|
|
|
|
|
self.emit("} else", depth)
|
|
|
|
|
|
|
|
|
|
self.emit("{", depth)
|
|
|
|
|
msg = f'format!("expected some sort of {sumname}, but got {{}}",_vm.to_repr(&_object)?)'
|
|
|
|
|
msg = f'format!("expected some sort of {sumname}, but got {{}}",_object.repr(_vm)?)'
|
|
|
|
|
self.emit(f"return Err(_vm.new_type_error({msg}));", depth + 1)
|
|
|
|
|
self.emit("})", depth)
|
|
|
|
|
|
|
|
|
|
@@ -549,8 +547,8 @@ class ChainOfVisitors:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def write_ast_def(mod, typeinfo, f):
|
|
|
|
|
f.write('pub use crate::location::Location;\n')
|
|
|
|
|
f.write('pub use crate::constant::*;\n')
|
|
|
|
|
f.write('pub use crate::location::Location;\n')
|
|
|
|
|
f.write('\n')
|
|
|
|
|
f.write('type Ident = String;\n')
|
|
|
|
|
f.write('\n')
|
|
|
|
|
@@ -574,8 +572,13 @@ def write_ast_def(mod, typeinfo, f):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def write_ast_mod(mod, f):
|
|
|
|
|
f.write('use super::*;\n')
|
|
|
|
|
f.write('\n')
|
|
|
|
|
f.write(textwrap.dedent("""
|
|
|
|
|
#![allow(clippy::all)]
|
|
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
use crate::common::ascii;
|
|
|
|
|
|
|
|
|
|
"""))
|
|
|
|
|
|
|
|
|
|
c = ChainOfVisitors(ClassDefVisitor(f),
|
|
|
|
|
TraitImplVisitor(f),
|
|
|
|
|
|