8000 Add initial draft of symtable module. · rmliddle/RustPython@215308d · GitHub
[go: up one dir, main page]

Skip to content

Commit 215308d

Browse files
committed
Add initial draft of symtable module.
1 parent 42b1b75 commit 215308d

File tree

8 files changed

+307
-82
lines changed

8 files changed

+307
-82
lines changed

compiler/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ extern crate log;
88

99
pub mod compile;
1010
pub mod error;
11-
mod symboltable;
11+
pub mod symboltable;

compiler/src/symboltable.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub fn statements_to_symbol_table(
3636
Ok(symbol_table)
3737
}
3838

39-
#[derive(Debug)]
39+
#[derive(Debug, Clone)]
4040
pub enum SymbolRole {
4141
Global,
4242
Nonlocal,
@@ -45,6 +45,7 @@ pub enum SymbolRole {
4545
}
4646

4747
/// Captures all symbols in the current scope, and has a list of subscopes in this scope.
48+
#[derive(Clone)]
4849
pub struct SymbolScope {
4950
/// A set of symbols present on this scope level.
5051
pub symbols: HashMap<String, SymbolRole>,

crawl_sourcecode.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
import ast
33
import sys
4+
import symtable
45

56
filename = sys.argv[1]
67
print('Crawling file:', filename)
@@ -31,3 +32,14 @@ def print_node(node, indent=0):
3132

3233
# print(ast.dump(t))
3334

35+
def print_table(table, indent=0):
36+
print(' '*indent, 'table:', table.get_name())
37+
print(' '*indent, ' ', 'Syms:')
38+
for sym in table.get_symbols():
39+
print(' '*indent, ' ', sym)
40+
print(' '*indent, ' ', 'Child tables:')
41+
for child in table.get_children():
42+
print_table(child, indent=indent+shift)
43+
44+
table = symtable.symtable(source, 'a', 'exec')
45+
print_table(table)

vm/src/builtins.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::obj::objtype::{self, PyClassRef};
2121
#[cfg(feature = "rustpython-compiler")]
2222
use rustpython_compiler::compile;
2323

24+
use crate::eval::get_compile_mode;
2425
use crate::frame::Scope;
2526
use crate::function::{single_or_tuple_any, Args, KwArgs, OptionalArg, PyFuncArgs};
2627
use crate::pyobject::{
@@ -110,20 +111,7 @@ fn builtin_compile(args: CompileArgs, vm: &VirtualMachine) -> PyResult<PyCodeRef
110111
// TODO: fix this newline bug:
111112
let source = format!("{}\n", source);
112113

113-
let mode = {
114-
let mode = &args.mode.value;
115-
if mode == "exec" {
116-
compile::Mode::Exec
117-
} else if mode == "eval" {
118-
compile::Mode::Eval
119-
} else if mode == "single" {
120-
compile::Mode::Single
121-
} else {
122-
return Err(
123-
vm.new_value_error("compile() mode must be 'exec', 'eval' or single'".to_string())
124-
);
125-
}
126-
};
114+
let mode = get_compile_mode(vm, &args.mode.value)?;
127115

128116
vm.compile(&source, &mode, args.filename.value.to_string())
129117
.map_err(|err| vm.new_syntax_error(&err))

vm/src/eval.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@ pub fn eval(vm: &VirtualMachine, source: &str, scope: Scope, source_path: &str)
1313
}
1414
}
1515

16+
pub fn get_compile_mode(vm: &VirtualMachine, mode: &str) -> PyResult<compile::Mode> {
17+
if mode == "exec" {
18+
Ok(compile::Mode::Exec)
19+
} else if mode == "eval" {
20+
Ok(compile::Mode::Eval)
21+
} else if mode == "single" {
22+
Ok(compile::Mode::Single)
23+
} else {
24+
Err(vm.new_value_error("compile() mode must be 'exec', 'eval' or single'".to_string()))
25+
}
26+
}
27+
1628
#[cfg(test)]
1729
mod tests {
1830
use super::eval;

vm/src/stdlib/ast.rs

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,9 @@ fn expression_to_ast(vm: &VirtualMachine, expression: &ast::Expression) -> PyRes
364364
comparators => comparators,
365365
})
366366
}
367-
ast::Expression::Identifier { name } => node!(vm, Identifier, {
368-
id => vm.ctx.new_str(name.clone())
367+
ast::Expression::Identifier { name } => node!(vm, Name, {
368+
id => vm.ctx.new_str(name.clone()),
369+
ctx => vm.ctx.none() // TODO: add context.
369370
}),
370371
ast::Expression::Lambda { args, body } => node!(vm, Lambda, {
371372
args => parameters_to_ast(vm, args)?,
@@ -470,6 +471,7 @@ fn expression_to_ast(vm: &VirtualMachine, expression: &ast::Expression) -> PyRes
470471
ast::Expression::Attribute { value, name } => node!(vm, Attribute, {
471472
value => expression_to_ast(vm, value)?,
472473
attr => vm.ctx.new_str(name.to_string()),
474+
ctx => vm.ctx.none()
473475
}),
474476
ast::Expression::Starred { value } => node!(vm, Starred, {
475477
value => expression_to_ast(vm, value)?
@@ -589,73 +591,71 @@ fn ast_parse(source: PyStringRef, vm: &VirtualMachine) -> PyResult<AstNodeRef> {
589591
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
590592
let ctx = &vm.ctx;
591593

592-
let ast_base = py_class!(ctx, "_ast.AST", ctx.object(), {});
594+
let ast_base = py_class!(ctx, "AST", ctx.object(), {});
593595
py_module!(vm, "ast", {
594596
"parse" => ctx.new_rustfunc(ast_parse),
595597
"AST" => ast_base.clone(),
596598
// TODO: There's got to be a better way!
597-
"alias" => py_class!(ctx, "_ast.alias", ast_base.clone(), {}),
598-
"arg" => py_class!(ctx, "_ast.arg", ast_base.clone(), {}),
599-
"arguments" => py_class!(ctx, "_ast.arguments", ast_base.clone(), {}),
600-
"Assign" => py_class!(ctx, "_ast.Assign", ast_base.clone(), {}),
601-
"AugAssign" => py_class!(ctx, "_ast.AugAssign", ast_base.clone(), {}),
602-
"AsyncFor" => py_class!(ctx, "_ast.AsyncFor", ast_base.clone(), {}),
603-
"AsyncFunctionDef" => py_class!(ctx, "_ast.AsyncFunctionDef", ast_base.clone(), {}),
604-
"Assert" => py_class!(ctx, "_ast.Assert", ast_base.clone(), {}),
605-
"Attribute" => py_class!(ctx, "_ast.Attribute", ast_base.clone(), {}),
606-
"Await" => py_class!(ctx, "_ast.Await", ast_base.clone(), {}),
607-
"BinOp" => py_class!(ctx, "_ast.BinOp", ast_base.clone(), {}),
608-
"BoolOp" => py_class!(ctx, "_ast.BoolOp", ast_base.clone(), {}),
609-
"Break" => py_class!(ctx, "_ast.Break", ast_base.clone(), {}),
610-
"Bytes" => py_class!(ctx, "_ast.Bytes", ast_base.clone(), {}),
611-
"Call" => py_class!(ctx, "_ast.Call", ast_base.clone(), {}),
612-
"ClassDef" => py_class!(ctx, "_ast.ClassDef", ast_base.clone(), {}),
613-
"Compare" => py_class!(ctx, "_ast.Compare", ast_base.clone(), {}),
614-
"comprehension" => py_class!(ctx, "_ast.comprehension", ast_base.clone(), {}),
615-
"Continue" => py_class!(ctx, "_ast.Continue", ast_base.clone(), {}),
616-
"Delete" => py_class!(ctx, "_ast.Delete", ast_base.clone(), {}),
617-
"Dict" => py_class!(ctx, "_ast.Dict", ast_base.clone(), {}),
618-
"DictComp" => py_class!(ctx, "_ast.DictComp", ast_base.clone(), {}),
619-
"Ellipsis" => py_class!(ctx, "_ast.Ellipsis", ast_base.clone(), {}),
620-
"Expr" => py_class!(ctx, "_ast.Expr", ast_base.clone(), {}),
621-
"ExceptHandler" => py_class!(ctx, "_ast.ExceptHandler", ast_base.clone(), {}),
622-
"For" => py_class!(ctx, "_ast.For", ast_base.clone(), {}),
623-
"FormattedValue" => py_class!(ctx, "_ast.FormattedValue", ast_base.clone(), {}),
624-
"FunctionDef" => py_class!(ctx, "_ast.FunctionDef", ast_base.clone(), {}),
625-
"GeneratorExp" => py_class!(ctx, "_ast.GeneratorExp", ast_base.clone(), {}),
626-
"Global" => py_class!(ctx, "_ast.Global", ast_base.clone(), {}),
627-
"Identifier" => py_class!(ctx, "_ast.Identifier", ast_base.clone(), {}),
628-
"If" => py_class!(ctx, "_ast.If", ast_base.clone(), {}),
629-
"IfExp" => py_class!(ctx, "_ast.IfExp", ast_base.clone(), {}),
630-
"Import" => py_class!(ctx, "_ast.Import", ast_base.clone(), {}),
631-
"ImportFrom" => py_class!(ctx, "_ast.ImportFrom", ast_base.clone(), {}),
632-
"JoinedStr" => py_class!(ctx, "_ast.JoinedStr", ast_base.clone(), {}),
633-
"keyword" => py_class!(ctx, "_ast.keyword", ast_base.clone(), {}),
634-
"Lambda" => py_class!(ctx, "_ast.Lambda", ast_base.clone(), {}),
635-
"List" => py_class!(ctx, "_ast.List", ast_base.clone(), {}),
636-
"ListComp" => py_class!(ctx, "_ast.ListComp", ast_base.clone(), {}),
637-
"Module" => py_class!(ctx, "_ast.Module", ast_base.clone(), {}),
638-
"NameConstant" => py_class!(ctx, "_ast.NameConstant", ast_base.clone(), {}),
639-
"NameConstant" => py_class!(ctx, "_ast.NameConstant", ast_base.clone(), {}),
640-
"NameConstant" => py_class!(ctx, "_ast.NameConstant", ast_base.clone(), {}),
641-
"Nonlocal" => py_class!(ctx, "_ast.Nonlocal", ast_base.clone(), {}),
642-
"Num" => py_class!(ctx, "_ast.Num", ast_base.clone(), {}),
643-
"Pass" => py_class!(ctx, "_ast.Pass", ast_base.clone(), {}),
644-
"Raise" => py_class!(ctx, "_ast.Raise", ast_base.clone(), {}),
645-
"Return" => py_class!(ctx, "_ast.Return", ast_base.clone(), {}),
646-
"Set" => py_class!(ctx, "_ast.Set", ast_base.clone(), {}),
647-
"SetComp" => py_class!(ctx, "_ast.SetComp", ast_base.clone(), {}),
648-
"Starred" => py_class!(ctx, "_ast.Starred", ast_base.clone(), {}),
649-
"Starred" => py_class!(ctx, "_ast.Starred", ast_base.clone(), {}),
650-
"Str" => py_class!(ctx, "_ast.Str", ast_base.clone(), {}),
651-
"Subscript" => py_class!(ctx, "_ast.Subscript", ast_base.clone(), {}),
652-
"Try" => py_class!(ctx, "_ast.Try", ast_base.clone(), {}),
653-
"Tuple" => py_class!(ctx, "_ast.Tuple", ast_base.clone(), {}),
654-
"UnaryOp" => py_class!(ctx, "_ast.UnaryOp", ast_base.clone(), {}),
655-
"While" => py_class!(ctx, "_ast.While", ast_base.clone(), {}),
656-
"With" => py_class!(ctx, "_ast.With", ast_base.clone(), {}),
657-
"withitem" => py_class!(ctx, "_ast.withitem", ast_base.clone(), {}),
658-
"Yield" => py_class!(ctx, "_ast.Yield", ast_base.clone(), {}),
659-
"YieldFrom" => py_class!(ctx, "_ast.YieldFrom", ast_base.clone(), {}),
599+
"alias" => py_class!(ctx, "alias", ast_base.clone(), {}),
600+
"arg" => py_class!(ctx, "arg", ast_base.clone(), {}),
601+
"arguments" => py_class!(ctx, "arguments", ast_base.clone(), {}),
602+
"Assign" => py_class!(ctx, "Assign", ast_base.clone(), {}),
603+
"AugAssign" => py_class!(ctx, "AugAssign", ast_base.clone(), {}),
604+
"AsyncFor" => py_class!(ctx, "AsyncFor", ast_base.clone(), {}),
605+
"AsyncFunctionDef" => py_class!(ctx, "AsyncFunctionDef", ast_base.clone(), {}),
606+
"Assert" => py_class!(ctx, "Assert", ast_base.clone(), {}),
607+
"Attribute" => py_class!(ctx, "Attribute", ast_base.clone(), {}),
608+
"Await" => py_class!(ctx, "Await", ast_base.clone(), {}),
609+
"BinOp" => py_class!(ctx, "BinOp", ast_base.clone(), {}),
610+
"BoolOp" => py_class!(ctx, "BoolOp", ast_base.clone(), {}),
611+
"Break" => py_class!(ctx, "Break", ast_base.clone(), {}),
612+
"Bytes" => py_class!(ctx, "Bytes", ast_base.clone(), {}),
613+
"Call" => py_class!(ctx, "Call", ast_base.clone(), {}),
614+
"ClassDef" => py_class!(ctx, "ClassDef", ast_base.clone(), {}),
615+
"Compare" => py_class!(ctx, "Compare", ast_base.clone(), {}),
616+
"comprehension" => py_class!(ctx, "comprehension", ast_base.clone(), {}),
617+
"Continue" => py_class!(ctx, "Continue", ast_base.clone(), {}),
618+
"Delete" => py_class!(ctx, "Delete", ast_base.clone(), {}),
619+
"Dict" => py_class!(ctx, "Dict", ast_base.clone(), {}),
620+
"DictComp" => py_class!(ctx, "DictComp", ast_base.clone(), {}),
621+
"Ellipsis" => py_class!(ctx, "Ellipsis", ast_base.clone(), {}),
622+
"Expr" => py_class!(ctx, "Expr", ast_base.clone(), {}),
623+
"ExceptHandler" => py_class!(ctx, "ExceptHandler", ast_base.clone(), {}),
624+
"For" => py_class!(ctx, "For", ast_base.clone(), {}),
625+
"FormattedValue" => py_class!(ctx, "FormattedValue", ast_base.clone(), {}),
626+
"FunctionDef" => py_class!(ctx, "FunctionDef", ast_base.clone(), {}),
627+
"GeneratorExp" => py_class!(ctx, "GeneratorExp", ast_base.clone(), {}),
628+
"Global" => py_class!(ctx, "Global", ast_base.clone(), {}),
629+
"If" => py_class!(ctx, "If", ast_base.clone(), {}),
630+
"IfExp" => py_class!(ctx, "IfExp", ast_base.clone(), {}),
631+
"Import" => py_class!(ctx, "Import", ast_base.clone(), {}),
632+
"ImportFrom" => py_class!(ctx, "ImportFrom", ast_base.clone(), {}),
633+
"JoinedStr" => py_class!(ctx, "JoinedStr", ast_base.clone(), {}),
634+
"keyword" => py_class!(ctx, "keyword", ast_base.clone(), {}),
635+
"Lambda" => py_class!(ctx, "Lambda", ast_base.clone(), {}),
636+
"List" => py_class!(ctx, "List", ast_base.clone(), {}),
637+
"ListComp" => py_class!(ctx, "ListComp", ast_base.clone(), {}),
638+
"Module" => py_class!(ctx, "Module", ast_base.clone(), {}),
639+
"Name" => py_class!(ctx, "Name", ast_base.clone(), {}),
640+
"NameConstant" => py_class!(ctx, "NameConstant", ast_base.clone(), {}),
641+
"Nonlocal" => py_class!(ctx, "Nonlocal", ast_base.clone(), {}),
642+
"Num" => py_class!(ctx, "Num", ast_base.clone(), {}),
643+
"Pass" => py_class!(ctx, "Pass", ast_base.clone(), {}),
644+
"Raise" => py_class!(ctx, "Raise", ast_base.clone(), {}),
645+
"Return" => py_class!(ctx, "Return", ast_base.clone(), {}),
646+
"Set" => py_class!(ctx, "Set", ast_base.clone(), {}),
647+
"SetComp" => py_class!(ctx, "SetComp", ast_base.clone(), {}),
648+
"Starred" => py_class!(ctx, "Starred", ast_base.clone(), {}),
649+
"Starred" => py_class!(ctx, "Starred", ast_base.clone(), {}),
650+
"Str" => py_class!(ctx, "Str", ast_base.clone(), {}),
651+
"Subscript" => py_class!(ctx, "Subscript", ast_base.clone(), {}),
652+
"Try" => py_class!(ctx, "Try", ast_base.clone(), {}),
653+
"Tuple" => py_class!(ctx, "Tuple", ast_base.clone(), {}),
654+
"UnaryOp" => py_class!(ctx, "UnaryOp", ast_base.clone(), {}),
655+
"While" => py_class!(ctx, "While", ast_base.clone(), {}),
656+
"With" => py_class!(ctx, "With", ast_base.clone(), {}),
657+
"withitem" => py_class!(ctx, "withitem", ast_base.clone(), {}),
658+
"Yield" => py_class!(ctx, "Yield", ast_base.clone(), {}),
659+
"YieldFrom" => py_class!(ctx, "YieldFrom", ast_base.clone(), {}),
660660
})
661661
}

vm/src/stdlib/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ mod random;
1919
mod re;
2020
pub mod socket;
2121
mod string;
22+
#[cfg(feature = "rustpython-compiler")]
23+
mod symtable;
2224
mod thread;
2325
mod time_module;
2426
#[cfg(feature = "rustpython-parser")]
@@ -59,6 +61,7 @@ pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
5961
"random".to_string() => Box::new(random::make_module),
6062
"_string".to_string() => Box::new(string::make_module),
6163
"struct".to_string() => Box::new(pystruct::make_module),
64+
"symtable".to_string() => Box::new(symtable::make_module),
6265
"_thread".to_string() => Box::new(thread::make_module),
6366
"time".to_string() => Box::new(time_module::make_module),
6467
"_weakref".to_string() => Box::new(weakref::make_module),

0 commit comments

Comments
 (0)
0