From 0e3386150f053bff31e37cff6d68579bb35eacc9 Mon Sep 17 00:00:00 2001 From: Tomasz Zurkowski Date: Sat, 21 Dec 2024 14:33:28 +0100 Subject: [PATCH] Initial generation of IR from nu AST. The initial implementation only handles simple math expressions, the focus is primarily on introducing new structs, agreeing on naming and adding the output to insta tests. --- Cargo.toml | 2 +- src/ir_generator.rs | 193 ++++++++++++++++++ src/lib.rs | 1 + src/main.rs | 7 + ...test__node_output@binary_ops_exact.nu.snap | 7 + ...t__node_output@binary_ops_mismatch.nu.snap | 5 + ...t__node_output@binary_ops_subtypes.nu.snap | 6 + ...nu_parser__test__node_output@calls.nu.snap | 5 + ...parser__test__node_output@closure3.nu.snap | 5 + ...w_nu_parser__test__node_output@def.nu.snap | 5 + ...w_nu_parser__test__node_output@for.nu.snap | 5 + ...st__node_output@for_break_continue.nu.snap | 5 + ...w_nu_parser__test__node_output@if_.nu.snap | 5 + ...rser__test__node_output@invalid_if.nu.snap | 5 + ...r__test__node_output@invalid_types.nu.snap | 5 + ..._nu_parser__test__node_output@let_.nu.snap | 5 + ...er__test__node_output@let_mismatch.nu.snap | 5 + ..._nu_parser__test__node_output@list.nu.snap | 5 + ...parser__test__node_output@literals.nu.snap | 5 + ..._nu_parser__test__node_output@loop.nu.snap | 5 + ..._nu_parser__test__node_output@math.nu.snap | 7 + ..._test__node_output@math_precedence.nu.snap | 11 + ..._nu_parser__test__node_output@mut_.nu.snap | 6 + ...u_parser__test__node_output@record.nu.snap | 5 + ..._parser__test__node_output@record2.nu.snap | 5 + ..._parser__test__node_output@record3.nu.snap | 5 + ..._parser__test__node_output@reparse.nu.snap | 5 + ...u_parser__test__node_output@string.nu.snap | 5 + ...test__node_output@string_operation.nu.snap | 5 + ...nu_parser__test__node_output@table.nu.snap | 5 + ...u_parser__test__node_output@table2.nu.snap | 5 + ...nu_parser__test__node_output@while.nu.snap | 5 + src/test.rs | 5 + 33 files changed, 359 insertions(+), 1 deletion(-) create mode 100644 src/ir_generator.rs diff --git a/Cargo.toml b/Cargo.toml index 066d2cd..0e77da1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] tracy-client = { version = "0.17.3", default-features = false } # for tracy v0.11.1 logos = "0.15" +nu-protocol = "0.101" [profile.profiling] inherits = "release" @@ -30,7 +31,6 @@ path = "src/lib.rs" insta = { version = "1.33.0", features = ["glob"] } tango-bench = "0.6" nu-parser = "0.101" -nu-protocol = "0.101" nu-cmd-lang = "0.101" [[bench]] diff --git a/src/ir_generator.rs b/src/ir_generator.rs new file mode 100644 index 0000000..c9150db --- /dev/null +++ b/src/ir_generator.rs @@ -0,0 +1,193 @@ +use crate::compiler::Compiler; +use crate::errors::{Severity, SourceError}; +use crate::parser::{AstNode, NodeId}; +use nu_protocol::ast::{Math, Operator}; +use nu_protocol::ir::{Instruction, IrBlock, Literal}; +use nu_protocol::{RegId, Span}; + +/// Generates IR (Intermediate Representation) from nu AST. +pub struct IrGenerator<'a> { + // Immutable reference to a compiler after the typechecker pass + compiler: &'a Compiler, + errors: Vec, + + instructions: Vec, + register_count: u32, + file_count: u32, +} + +impl<'a> IrGenerator<'a> { + pub fn new(compiler: &'a Compiler) -> Self { + Self { + compiler, + errors: Default::default(), + instructions: Default::default(), + register_count: 0, + file_count: 0, + } + } + + /// Generates the IR from the given state of the compiler. + /// After this is called, use `block` and `errors` to get the result. + pub fn generate(&mut self) { + if self.compiler.ast_nodes.is_empty() { + return; + } + let Some(reg) = self.generate_node(NodeId(self.compiler.ast_nodes.len() - 1)) else { + return; + }; + self.instructions.push(Instruction::Return { src: reg }); + } + + /// Returns generated IR block. + /// + /// Call `generate` before using this method and ensure there are no errors. + pub fn block(self) -> IrBlock { + // TODO: properly generate the spans + // TODO: figure out what to do with AST, as this parser has different + // representation of AST than the old parser. + let mut spans = vec![]; + let mut ast = vec![]; + for _ in 0..(self.instructions.len()) { + spans.push(Span { start: 0, end: 0 }); + ast.push(None); + } + IrBlock { + instructions: self.instructions, + spans, + data: Default::default(), + ast, + comments: Default::default(), + register_count: self.register_count, + file_count: self.file_count, + } + } + + /// Returns errors encountered during IR generation step. + /// + /// Call `generate` before using this method. + pub fn errors(&self) -> &Vec { + &self.errors + } + + /// Prints the internal state to standard output. + pub fn print(&self) { + let output = self.display_state(); + print!("{output}"); + } + + /// Displays the state of the IR generator. + /// The output can be used for human debugging and for snapshot tests. + pub fn display_state(&self) -> String { + let mut result = String::new(); + result.push_str("==== IR ====\n"); + result.push_str(&format!("register_count: {}\n", self.register_count)); + result.push_str(&format!("file_count: {}\n", self.file_count)); + + for (idx, instruction) in self.instructions.iter().enumerate() { + result.push_str(&format!("{}: {:?}\n", idx, instruction)); + } + + if !self.errors.is_empty() { + result.push_str("==== IR ERRORS ====\n"); + for error in &self.errors { + result.push_str(&format!( + "{:?} (NodeId {}): {}\n", + error.severity, error.node_id.0, error.message + )); + } + } + result + } + + // Returns unused register. + fn next_register(&mut self) -> RegId { + let r = RegId::new(self.register_count); + self.register_count += 1; + r + } + + fn span_to_string(&mut self, node_id: NodeId) -> Option { + match std::str::from_utf8(self.compiler.get_span_contents(node_id)) { + Ok(val) => Some(val.to_string()), + Err(err) => { + self.error( + format!("failed to convert a node to string: {err}"), + node_id, + ); + None + } + } + } + + fn span_to_i64(&mut self, node_id: NodeId) -> Option { + match self.span_to_string(node_id)?.parse::() { + Ok(val) => Some(val), + Err(err) => { + self.error( + format!("failed to convert a node to string: {err}"), + node_id, + ); + None + } + } + } + + fn generate_node(&mut self, node_id: NodeId) -> Option { + let ast_node = &self.compiler.ast_nodes[node_id.0]; + match ast_node { + AstNode::Int => { + let next_reg = self.next_register(); + let val = self.span_to_i64(node_id)?; + self.instructions.push(Instruction::LoadLiteral { + dst: next_reg, + lit: Literal::Int(val), + }); + Some(next_reg) + } + AstNode::Block(block_id) => { + let block = &self.compiler.blocks[block_id.0]; + let mut last = None; + for id in &block.nodes { + last = self.generate_node(*id); + last?; + } + last + } + AstNode::BinaryOp { lhs, op, rhs } => { + let l = self.generate_node(*lhs)?; + let r = self.generate_node(*rhs)?; + let o = self.node_to_operator(*op)?; + self.instructions.push(Instruction::BinaryOp { + lhs_dst: l, + op: o, + rhs: r, + }); + Some(l) + } + _ => { + self.error(format!("node {:?} not suported yet", ast_node), node_id); + None + } + } + } + + fn node_to_operator(&mut self, node_id: NodeId) -> Option { + match self.compiler.get_node(node_id) { + AstNode::Plus => Some(Operator::Math(Math::Plus)), + AstNode::Multiply => Some(Operator::Math(Math::Multiply)), + node => { + self.error(format!("unrecognized operator {:?}", node), node_id); + None + } + } + } + + fn error(&mut self, message: impl Into, node_id: NodeId) { + self.errors.push(SourceError { + message: message.into(), + node_id, + severity: Severity::Error, + }); + } +} diff --git a/src/lib.rs b/src/lib.rs index 7a28cdf..6d74421 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ pub mod compiler; pub mod errors; +pub mod ir_generator; pub mod lexer; pub mod parser; pub mod protocol; diff --git a/src/main.rs b/src/main.rs index 60b3ac8..9aef8f2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ use std::process::exit; use new_nu_parser::compiler::Compiler; +use new_nu_parser::ir_generator::IrGenerator; use new_nu_parser::lexer::lex; use new_nu_parser::parser::Parser; use new_nu_parser::resolver::Resolver; @@ -74,6 +75,12 @@ fn main() { typechecker.print(); } + let mut ir_generator = IrGenerator::new(&compiler); + ir_generator.generate(); + if do_print { + ir_generator.print(); + } + compiler.merge_types(typechecker.to_types()); } } diff --git a/src/snapshots/new_nu_parser__test__node_output@binary_ops_exact.nu.snap b/src/snapshots/new_nu_parser__test__node_output@binary_ops_exact.nu.snap index cb8c98e..1c11672 100644 --- a/src/snapshots/new_nu_parser__test__node_output@binary_ops_exact.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@binary_ops_exact.nu.snap @@ -52,3 +52,10 @@ snapshot_kind: text 19: bool 20: bool 21: bool +==== IR ==== +register_count: 2 +file_count: 0 +0: LoadLiteral { dst: RegId(0), lit: Int(1) } +1: LoadLiteral { dst: RegId(1), lit: Int(1) } +==== IR ERRORS ==== +Error (NodeId 1): unrecognized operator Equal diff --git a/src/snapshots/new_nu_parser__test__node_output@binary_ops_mismatch.nu.snap b/src/snapshots/new_nu_parser__test__node_output@binary_ops_mismatch.nu.snap index 44a614a..2800f7e 100644 --- a/src/snapshots/new_nu_parser__test__node_output@binary_ops_mismatch.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@binary_ops_mismatch.nu.snap @@ -38,3 +38,8 @@ snapshot_kind: text Error (NodeId 1): type mismatch: unsupported addition between string and float Error (NodeId 5): type mismatch: unsupported append between string and float Error (NodeId 9): type mismatch: unsupported logical operation between bool and string +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 0): node String not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@binary_ops_subtypes.nu.snap b/src/snapshots/new_nu_parser__test__node_output@binary_ops_subtypes.nu.snap index 180d535..f1cf494 100644 --- a/src/snapshots/new_nu_parser__test__node_output@binary_ops_subtypes.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@binary_ops_subtypes.nu.snap @@ -96,3 +96,9 @@ snapshot_kind: text 41: list> 42: list> 43: list> +==== IR ==== +register_count: 1 +file_count: 0 +0: LoadLiteral { dst: RegId(0), lit: Int(1) } +==== IR ERRORS ==== +Error (NodeId 2): node Float not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@calls.nu.snap b/src/snapshots/new_nu_parser__test__node_output@calls.nu.snap index 4f4a03e..01b2108 100644 --- a/src/snapshots/new_nu_parser__test__node_output@calls.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@calls.nu.snap @@ -90,3 +90,8 @@ snapshot_kind: text 36: unknown 37: stream 38: stream +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 7): node Call { parts: [NodeId(0), NodeId(1), NodeId(2), NodeId(6)] } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@closure3.nu.snap b/src/snapshots/new_nu_parser__test__node_output@closure3.nu.snap index 958f620..20bd057 100644 --- a/src/snapshots/new_nu_parser__test__node_output@closure3.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@closure3.nu.snap @@ -59,3 +59,8 @@ snapshot_kind: text 21: closure 22: stream 23: stream +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 19): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(18), is_mutable: false } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@def.nu.snap b/src/snapshots/new_nu_parser__test__node_output@def.nu.snap index 578a66a..fbda6c4 100644 --- a/src/snapshots/new_nu_parser__test__node_output@def.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@def.nu.snap @@ -61,3 +61,8 @@ snapshot_kind: text 22: list 23: () 24: () +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 23): node Def { name: NodeId(0), params: NodeId(17), return_ty: None, block: NodeId(22) } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@for.nu.snap b/src/snapshots/new_nu_parser__test__node_output@for.nu.snap index 9e8eec1..75889ed 100644 --- a/src/snapshots/new_nu_parser__test__node_output@for.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@for.nu.snap @@ -77,3 +77,8 @@ snapshot_kind: text 29: () 30: () 31: () +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 2): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(1), is_mutable: true } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@for_break_continue.nu.snap b/src/snapshots/new_nu_parser__test__node_output@for_break_continue.nu.snap index d16f9b1..86ad7e5 100644 --- a/src/snapshots/new_nu_parser__test__node_output@for_break_continue.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@for_break_continue.nu.snap @@ -80,3 +80,8 @@ snapshot_kind: text ==== TYPE ERRORS ==== Error (NodeId 12): unsupported ast node 'Break' in typechecker Error (NodeId 19): unsupported ast node 'Continue' in typechecker +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 2): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(1), is_mutable: true } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@if_.nu.snap b/src/snapshots/new_nu_parser__test__node_output@if_.nu.snap index 4b2ae9e..6eada57 100644 --- a/src/snapshots/new_nu_parser__test__node_output@if_.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@if_.nu.snap @@ -52,3 +52,8 @@ snapshot_kind: text 17: int 18: int 19: int +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 2): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(1), is_mutable: false } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@invalid_if.nu.snap b/src/snapshots/new_nu_parser__test__node_output@invalid_if.nu.snap index 31b0d0d..e96d1b5 100644 --- a/src/snapshots/new_nu_parser__test__node_output@invalid_if.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@invalid_if.nu.snap @@ -26,3 +26,8 @@ snapshot_kind: text 6: error ==== TYPE ERRORS ==== Error (NodeId 0): The condition for if branch is not a boolean +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 5): node If { condition: NodeId(0), then_block: NodeId(2), else_block: Some(NodeId(4)) } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@invalid_types.nu.snap b/src/snapshots/new_nu_parser__test__node_output@invalid_types.nu.snap index c1c4eaf..84a69aa 100644 --- a/src/snapshots/new_nu_parser__test__node_output@invalid_types.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@invalid_types.nu.snap @@ -66,3 +66,8 @@ snapshot_kind: text ==== TYPE ERRORS ==== Error (NodeId 7): list must have only one type parameter (to allow selection of types, use oneof -- WIP) Error (NodeId 17): list must have one type parameter +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 13): node Def { name: NodeId(0), params: NodeId(10), return_ty: None, block: NodeId(12) } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@let_.nu.snap b/src/snapshots/new_nu_parser__test__node_output@let_.nu.snap index 509718d..c151562 100644 --- a/src/snapshots/new_nu_parser__test__node_output@let_.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@let_.nu.snap @@ -19,3 +19,8 @@ snapshot_kind: text 2: () 3: int 4: int +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 2): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(1), is_mutable: false } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@let_mismatch.nu.snap b/src/snapshots/new_nu_parser__test__node_output@let_mismatch.nu.snap index fa35d31..d7abbf5 100644 --- a/src/snapshots/new_nu_parser__test__node_output@let_mismatch.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@let_mismatch.nu.snap @@ -70,3 +70,8 @@ snapshot_kind: text ==== TYPE ERRORS ==== Error (NodeId 13): initializer does not match declared type Error (NodeId 26): initializer does not match declared type +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 4): node Let { variable_name: NodeId(0), ty: Some(NodeId(2)), initializer: NodeId(3), is_mutable: false } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@list.nu.snap b/src/snapshots/new_nu_parser__test__node_output@list.nu.snap index 9c3caf4..fa681ca 100644 --- a/src/snapshots/new_nu_parser__test__node_output@list.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@list.nu.snap @@ -50,3 +50,8 @@ snapshot_kind: text 18: string 19: list 20: list +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 3): node List([NodeId(0), NodeId(1), NodeId(2)]) not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@literals.nu.snap b/src/snapshots/new_nu_parser__test__node_output@literals.nu.snap index c5ed093..db77463 100644 --- a/src/snapshots/new_nu_parser__test__node_output@literals.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@literals.nu.snap @@ -22,3 +22,8 @@ snapshot_kind: text 4: string 5: list 6: list +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 5): node List([NodeId(0), NodeId(1), NodeId(2), NodeId(3), NodeId(4)]) not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@loop.nu.snap b/src/snapshots/new_nu_parser__test__node_output@loop.nu.snap index 31e10e0..8b4fb48 100644 --- a/src/snapshots/new_nu_parser__test__node_output@loop.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@loop.nu.snap @@ -47,3 +47,8 @@ snapshot_kind: text 16: unknown ==== TYPE ERRORS ==== Error (NodeId 15): unsupported ast node 'Loop { block: NodeId(14) }' in typechecker +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 2): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(1), is_mutable: true } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@math.nu.snap b/src/snapshots/new_nu_parser__test__node_output@math.nu.snap index bfec583..dc8f2ae 100644 --- a/src/snapshots/new_nu_parser__test__node_output@math.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@math.nu.snap @@ -18,3 +18,10 @@ snapshot_kind: text 2: int 3: int 4: int +==== IR ==== +register_count: 2 +file_count: 0 +0: LoadLiteral { dst: RegId(0), lit: Int(3) } +1: LoadLiteral { dst: RegId(1), lit: Int(4) } +2: BinaryOp { lhs_dst: RegId(0), op: Math(Plus), rhs: RegId(1) } +3: Return { src: RegId(0) } diff --git a/src/snapshots/new_nu_parser__test__node_output@math_precedence.nu.snap b/src/snapshots/new_nu_parser__test__node_output@math_precedence.nu.snap index 12c6fa7..01dc14b 100644 --- a/src/snapshots/new_nu_parser__test__node_output@math_precedence.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@math_precedence.nu.snap @@ -30,3 +30,14 @@ snapshot_kind: text 8: int 9: int 10: int +==== IR ==== +register_count: 4 +file_count: 0 +0: LoadLiteral { dst: RegId(0), lit: Int(1) } +1: LoadLiteral { dst: RegId(1), lit: Int(2) } +2: LoadLiteral { dst: RegId(2), lit: Int(3) } +3: BinaryOp { lhs_dst: RegId(1), op: Math(Multiply), rhs: RegId(2) } +4: BinaryOp { lhs_dst: RegId(0), op: Math(Plus), rhs: RegId(1) } +5: LoadLiteral { dst: RegId(3), lit: Int(4) } +6: BinaryOp { lhs_dst: RegId(0), op: Math(Plus), rhs: RegId(3) } +7: Return { src: RegId(0) } diff --git a/src/snapshots/new_nu_parser__test__node_output@mut_.nu.snap b/src/snapshots/new_nu_parser__test__node_output@mut_.nu.snap index 1c9b477..fdda7b3 100644 --- a/src/snapshots/new_nu_parser__test__node_output@mut_.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@mut_.nu.snap @@ -2,6 +2,7 @@ source: src/test.rs expression: evaluate_example(path) input_file: tests/mut_.nu +snapshot_kind: text --- ==== COMPILER ==== 0: Variable (4 to 5) "x" @@ -34,3 +35,8 @@ input_file: tests/mut_.nu 10: int 11: () 12: () +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 4): node Let { variable_name: NodeId(0), ty: Some(NodeId(2)), initializer: NodeId(3), is_mutable: true } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@record.nu.snap b/src/snapshots/new_nu_parser__test__node_output@record.nu.snap index 78342df..700e2c5 100644 --- a/src/snapshots/new_nu_parser__test__node_output@record.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@record.nu.snap @@ -22,3 +22,8 @@ snapshot_kind: text 5: unknown ==== TYPE ERRORS ==== Error (NodeId 4): unsupported ast node 'Record { pairs: [(NodeId(0), NodeId(1)), (NodeId(2), NodeId(3))] }' in typechecker +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 4): node Record { pairs: [(NodeId(0), NodeId(1)), (NodeId(2), NodeId(3))] } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@record2.nu.snap b/src/snapshots/new_nu_parser__test__node_output@record2.nu.snap index 997c199..40aefcf 100644 --- a/src/snapshots/new_nu_parser__test__node_output@record2.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@record2.nu.snap @@ -22,3 +22,8 @@ snapshot_kind: text 5: unknown ==== TYPE ERRORS ==== Error (NodeId 4): unsupported ast node 'Record { pairs: [(NodeId(0), NodeId(1)), (NodeId(2), NodeId(3))] }' in typechecker +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 4): node Record { pairs: [(NodeId(0), NodeId(1)), (NodeId(2), NodeId(3))] } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@record3.nu.snap b/src/snapshots/new_nu_parser__test__node_output@record3.nu.snap index a112130..c46df00 100644 --- a/src/snapshots/new_nu_parser__test__node_output@record3.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@record3.nu.snap @@ -22,3 +22,8 @@ snapshot_kind: text 5: unknown ==== TYPE ERRORS ==== Error (NodeId 4): unsupported ast node 'Record { pairs: [(NodeId(0), NodeId(1)), (NodeId(2), NodeId(3))] }' in typechecker +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 4): node Record { pairs: [(NodeId(0), NodeId(1)), (NodeId(2), NodeId(3))] } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@reparse.nu.snap b/src/snapshots/new_nu_parser__test__node_output@reparse.nu.snap index cf35634..9076c1b 100644 --- a/src/snapshots/new_nu_parser__test__node_output@reparse.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@reparse.nu.snap @@ -41,3 +41,8 @@ snapshot_kind: text 13: () ==== TYPE ERRORS ==== Error (NodeId 11): unsupported ast node 'Record { pairs: [(NodeId(9), NodeId(10))] }' in typechecker +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 7): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(6), is_mutable: false } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@string.nu.snap b/src/snapshots/new_nu_parser__test__node_output@string.nu.snap index 795baaa..79654e4 100644 --- a/src/snapshots/new_nu_parser__test__node_output@string.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@string.nu.snap @@ -14,3 +14,8 @@ snapshot_kind: text 0: string 1: string 2: string +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 0): node String not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@string_operation.nu.snap b/src/snapshots/new_nu_parser__test__node_output@string_operation.nu.snap index 155175f..ccd1f2b 100644 --- a/src/snapshots/new_nu_parser__test__node_output@string_operation.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@string_operation.nu.snap @@ -18,3 +18,8 @@ snapshot_kind: text 2: string 3: string 4: string +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 0): node String not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@table.nu.snap b/src/snapshots/new_nu_parser__test__node_output@table.nu.snap index 8b8cdd9..9cc85a8 100644 --- a/src/snapshots/new_nu_parser__test__node_output@table.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@table.nu.snap @@ -32,3 +32,8 @@ snapshot_kind: text 10: unknown ==== TYPE ERRORS ==== Error (NodeId 9): unsupported ast node 'Table { header: NodeId(2), rows: [NodeId(5), NodeId(8)] }' in typechecker +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 9): node Table { header: NodeId(2), rows: [NodeId(5), NodeId(8)] } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@table2.nu.snap b/src/snapshots/new_nu_parser__test__node_output@table2.nu.snap index 1c8eb5d..46ed72c 100644 --- a/src/snapshots/new_nu_parser__test__node_output@table2.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@table2.nu.snap @@ -32,3 +32,8 @@ snapshot_kind: text 10: unknown ==== TYPE ERRORS ==== Error (NodeId 9): unsupported ast node 'Table { header: NodeId(2), rows: [NodeId(5), NodeId(8)] }' in typechecker +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 9): node Table { header: NodeId(2), rows: [NodeId(5), NodeId(8)] } not suported yet diff --git a/src/snapshots/new_nu_parser__test__node_output@while.nu.snap b/src/snapshots/new_nu_parser__test__node_output@while.nu.snap index 520476d..f3cc1b8 100644 --- a/src/snapshots/new_nu_parser__test__node_output@while.nu.snap +++ b/src/snapshots/new_nu_parser__test__node_output@while.nu.snap @@ -38,3 +38,8 @@ snapshot_kind: text 11: () 12: () 13: () +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 2): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(1), is_mutable: true } not suported yet diff --git a/src/test.rs b/src/test.rs index 18df3cf..0b4d356 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,3 +1,4 @@ +use crate::ir_generator::IrGenerator; use crate::lexer::lex; use crate::resolver::Resolver; use crate::typechecker::Typechecker; @@ -44,6 +45,10 @@ fn evaluate_example(fname: &Path) -> String { compiler.merge_types(typechecker.to_types()); + let mut ir_generator = IrGenerator::new(&compiler); + ir_generator.generate(); + result.push_str(&ir_generator.display_state()); + result }