mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +03:00
Introduce TypeTable
This commit is contained in:
parent
621a2f2a95
commit
a3446d3aea
@ -173,12 +173,16 @@ impl<'a> Compiler<'a> {
|
||||
}
|
||||
|
||||
/// Runs the type checker pass.
|
||||
pub fn type_checker_pass(&'a self, symbol_table: SymbolTable) -> Result<(SymbolTable, StructGraph, CallGraph)> {
|
||||
let (symbol_table, struct_graph, call_graph) = TypeChecker::do_pass((&self.ast, self.handler, symbol_table))?;
|
||||
pub fn type_checker_pass(
|
||||
&'a self,
|
||||
symbol_table: SymbolTable,
|
||||
) -> Result<(SymbolTable, TypeTable, StructGraph, CallGraph)> {
|
||||
let (symbol_table, type_table, struct_graph, call_graph) =
|
||||
TypeChecker::do_pass((&self.ast, self.handler, symbol_table))?;
|
||||
if self.compiler_options.output.type_checked_symbol_table {
|
||||
self.write_symbol_table_to_json("type_checked_symbol_table.json", &symbol_table)?;
|
||||
}
|
||||
Ok((symbol_table, struct_graph, call_graph))
|
||||
Ok((symbol_table, type_table, struct_graph, call_graph))
|
||||
}
|
||||
|
||||
/// Runs the loop unrolling pass.
|
||||
@ -265,7 +269,7 @@ impl<'a> Compiler<'a> {
|
||||
/// Runs the compiler stages.
|
||||
pub fn compiler_stages(&mut self) -> Result<(SymbolTable, StructGraph, CallGraph)> {
|
||||
let st = self.symbol_table_pass()?;
|
||||
let (st, struct_graph, call_graph) = self.type_checker_pass(st)?;
|
||||
let (st, _, struct_graph, call_graph) = self.type_checker_pass(st)?;
|
||||
|
||||
// TODO: Make this pass optional.
|
||||
let st = self.loop_unrolling_pass(st)?;
|
||||
|
@ -226,7 +226,7 @@ pub fn compile_and_process<'a>(parsed: &'a mut Compiler<'a>) -> Result<String, L
|
||||
|
||||
CheckUniqueNodeIds::new().visit_program(&parsed.ast.ast);
|
||||
|
||||
let (st, struct_graph, call_graph) = parsed.type_checker_pass(st)?;
|
||||
let (st, _, struct_graph, call_graph) = parsed.type_checker_pass(st)?;
|
||||
|
||||
CheckUniqueNodeIds::new().visit_program(&parsed.ast.ast);
|
||||
|
||||
|
@ -27,6 +27,12 @@ pub mod replacer;
|
||||
pub use replacer::*;
|
||||
|
||||
pub mod constant_propagation_table;
|
||||
pub mod symbol_table;
|
||||
pub use constant_propagation_table::*;
|
||||
|
||||
pub mod symbol_table;
|
||||
pub use symbol_table::*;
|
||||
|
||||
pub type TypeTable = IndexMap<NodeID, Type>;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use leo_ast::{NodeID, Type};
|
||||
|
@ -22,7 +22,7 @@ pub use variable_symbol::*;
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
use leo_ast::{normalize_json_value, remove_key_from_json, Function, NodeID, Struct, Type};
|
||||
use leo_ast::{normalize_json_value, remove_key_from_json, Function, Struct};
|
||||
use leo_errors::{AstError, Result};
|
||||
use leo_span::{Span, Symbol};
|
||||
|
||||
@ -50,8 +50,6 @@ pub struct SymbolTable {
|
||||
pub(crate) scope_index: usize,
|
||||
/// The sub-scopes of this scope.
|
||||
pub(crate) scopes: Vec<RefCell<SymbolTable>>,
|
||||
/// A mapping from node IDs to types.
|
||||
pub(crate) types: IndexMap<NodeID, Type>,
|
||||
}
|
||||
|
||||
impl SymbolTable {
|
||||
@ -105,11 +103,6 @@ impl SymbolTable {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Inserts a type for a node ID into the symbol table.
|
||||
pub fn insert_type(&mut self, node_id: NodeID, type_: Type) {
|
||||
self.types.insert(node_id, type_);
|
||||
}
|
||||
|
||||
/// Removes a variable from the symbol table.
|
||||
pub fn remove_variable_from_current_scope(&mut self, symbol: Symbol) {
|
||||
self.variables.remove(&symbol);
|
||||
@ -189,11 +182,6 @@ impl SymbolTable {
|
||||
self.scopes.get(index)
|
||||
}
|
||||
|
||||
/// Returns the type associated with the node ID, if it exists in the symbol table.
|
||||
pub fn lookup_type(&self, node_id: NodeID) -> Option<&Type> {
|
||||
self.types.get(&node_id)
|
||||
}
|
||||
|
||||
/// Serializes the symbol table into a JSON string.
|
||||
pub fn to_json_string(&self) -> Result<String> {
|
||||
Ok(serde_json::to_string_pretty(&self)
|
||||
|
@ -59,7 +59,7 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
|
||||
};
|
||||
// If the output type is known, add the expression and its associated type to the symbol table.
|
||||
if let Some(type_) = &output {
|
||||
self.symbol_table.borrow_mut().insert_type(input.id(), type_.clone());
|
||||
self.type_table.insert(input.id(), type_.clone());
|
||||
}
|
||||
// Return the output type.
|
||||
output
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{CallGraph, StructGraph, SymbolTable};
|
||||
use crate::{CallGraph, StructGraph, SymbolTable, TypeTable};
|
||||
|
||||
use leo_ast::{ArrayType, CoreConstant, CoreFunction, Identifier, IntegerType, MappingType, Node, Type, Variant};
|
||||
use leo_errors::{emitter::Handler, TypeCheckerError};
|
||||
@ -27,6 +27,8 @@ use std::cell::RefCell;
|
||||
pub struct TypeChecker<'a> {
|
||||
/// The symbol table for the program.
|
||||
pub(crate) symbol_table: RefCell<SymbolTable>,
|
||||
/// A mapping from nod IDs to their respective type.
|
||||
pub(crate) type_table: TypeTable,
|
||||
/// A dependency graph of the structs in program.
|
||||
pub(crate) struct_graph: StructGraph,
|
||||
/// The call graph for the program.
|
||||
@ -104,6 +106,7 @@ impl<'a> TypeChecker<'a> {
|
||||
// Note that the `struct_graph` and `call_graph` are initialized with their full node sets.
|
||||
Self {
|
||||
symbol_table: RefCell::new(symbol_table),
|
||||
type_table: Default::default(),
|
||||
struct_graph: StructGraph::new(struct_names),
|
||||
call_graph: CallGraph::new(function_names),
|
||||
handler,
|
||||
|
@ -27,20 +27,20 @@ pub use check_statements::*;
|
||||
pub mod checker;
|
||||
pub use checker::*;
|
||||
|
||||
use crate::{CallGraph, Pass, StructGraph, SymbolTable};
|
||||
use crate::{CallGraph, Pass, StructGraph, SymbolTable, TypeTable};
|
||||
|
||||
use leo_ast::{Ast, ProgramVisitor};
|
||||
use leo_errors::{emitter::Handler, Result};
|
||||
|
||||
impl<'a> Pass for TypeChecker<'a> {
|
||||
type Input = (&'a Ast, &'a Handler, SymbolTable);
|
||||
type Output = Result<(SymbolTable, StructGraph, CallGraph)>;
|
||||
type Output = Result<(SymbolTable, TypeTable, StructGraph, CallGraph)>;
|
||||
|
||||
fn do_pass((ast, handler, st): Self::Input) -> Self::Output {
|
||||
let mut visitor = TypeChecker::new(st, handler);
|
||||
visitor.visit_program(ast.as_repr());
|
||||
handler.last_err().map_err(|e| *e)?;
|
||||
|
||||
Ok((visitor.symbol_table.take(), visitor.struct_graph, visitor.call_graph))
|
||||
Ok((visitor.symbol_table.take(), visitor.type_table, visitor.struct_graph, visitor.call_graph))
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ impl Sample {
|
||||
fn bench_loop_unroller(&self, c: &mut Criterion) {
|
||||
self.bencher_after_parse(c, "loop unrolling pass", |mut compiler| {
|
||||
let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table");
|
||||
let (symbol_table, _struct_graph, _call_graph) =
|
||||
let (symbol_table, _, _struct_graph, _call_graph) =
|
||||
compiler.type_checker_pass(symbol_table).expect("failed to run type check pass");
|
||||
let start = Instant::now();
|
||||
let out = compiler.loop_unrolling_pass(symbol_table);
|
||||
@ -203,7 +203,7 @@ impl Sample {
|
||||
fn bench_ssa(&self, c: &mut Criterion) {
|
||||
self.bencher_after_parse(c, "full", |mut compiler| {
|
||||
let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table");
|
||||
let (symbol_table, _struct_graph, _call_graph) =
|
||||
let (symbol_table, _, _struct_graph, _call_graph) =
|
||||
compiler.type_checker_pass(symbol_table).expect("failed to run type check pass");
|
||||
let symbol_table = compiler.loop_unrolling_pass(symbol_table).expect("failed to run loop unrolling pass");
|
||||
let start = Instant::now();
|
||||
@ -217,7 +217,7 @@ impl Sample {
|
||||
fn bench_flattener(&self, c: &mut Criterion) {
|
||||
self.bencher_after_parse(c, "flattener pass", |mut compiler| {
|
||||
let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table");
|
||||
let (symbol_table, _struct_graph, _call_graph) =
|
||||
let (symbol_table, _, _struct_graph, _call_graph) =
|
||||
compiler.type_checker_pass(symbol_table).expect("failed to run type check pass");
|
||||
let symbol_table = compiler.loop_unrolling_pass(symbol_table).expect("failed to run loop unrolling pass");
|
||||
compiler.static_single_assignment_pass(&symbol_table).expect("failed to run ssa pass");
|
||||
@ -232,7 +232,7 @@ impl Sample {
|
||||
fn bench_inline(&self, c: &mut Criterion) {
|
||||
self.bencher_after_parse(c, "inliner pass", |mut compiler| {
|
||||
let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table");
|
||||
let (symbol_table, _struct_graph, call_graph) =
|
||||
let (symbol_table, _, _struct_graph, call_graph) =
|
||||
compiler.type_checker_pass(symbol_table).expect("failed to run type check pass");
|
||||
let symbol_table = compiler.loop_unrolling_pass(symbol_table).expect("failed to run loop unrolling pass");
|
||||
compiler.static_single_assignment_pass(&symbol_table).expect("failed to run ssa pass");
|
||||
@ -248,7 +248,7 @@ impl Sample {
|
||||
fn bench_dce(&self, c: &mut Criterion) {
|
||||
self.bencher_after_parse(c, "inliner pass", |mut compiler| {
|
||||
let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table");
|
||||
let (symbol_table, _struct_graph, call_graph) =
|
||||
let (symbol_table, _, _struct_graph, call_graph) =
|
||||
compiler.type_checker_pass(symbol_table).expect("failed to run type check pass");
|
||||
let symbol_table = compiler.loop_unrolling_pass(symbol_table).expect("failed to run loop unrolling pass");
|
||||
compiler.static_single_assignment_pass(&symbol_table).expect("failed to run ssa pass");
|
||||
@ -265,7 +265,7 @@ impl Sample {
|
||||
fn bench_codegen(&self, c: &mut Criterion) {
|
||||
self.bencher_after_parse(c, "inliner pass", |mut compiler| {
|
||||
let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table");
|
||||
let (symbol_table, struct_graph, call_graph) =
|
||||
let (symbol_table, _, struct_graph, call_graph) =
|
||||
compiler.type_checker_pass(symbol_table).expect("failed to run type check pass");
|
||||
let symbol_table = compiler.loop_unrolling_pass(symbol_table).expect("failed to run loop unrolling pass");
|
||||
compiler.static_single_assignment_pass(&symbol_table).expect("failed to run ssa pass");
|
||||
@ -286,7 +286,7 @@ impl Sample {
|
||||
let start = Instant::now();
|
||||
compiler.parse_program_from_string(input, name).expect("Failed to parse program");
|
||||
let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table");
|
||||
let (symbol_table, struct_graph, call_graph) =
|
||||
let (symbol_table, _, struct_graph, call_graph) =
|
||||
compiler.type_checker_pass(symbol_table).expect("failed to run type check pass");
|
||||
let symbol_table = compiler.loop_unrolling_pass(symbol_table).expect("failed to run loop unrolling pass");
|
||||
compiler.static_single_assignment_pass(&symbol_table).expect("failed to run ssa pass");
|
||||
|
Loading…
Reference in New Issue
Block a user