diff --git a/Cargo.toml b/Cargo.toml index 6811fed..2b01a9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] tracy-client = { version = "0.17.3", default-features = false } # for tracy v0.11.1 +nu-protocol = "*" [profile.profiling] inherits = "release" @@ -29,7 +30,6 @@ path = "src/lib.rs" insta = { version = "1.33.0", features = ["glob"] } tango-bench = "0.6" nu-parser = "0.99" -nu-protocol = "0.99" [[bench]] name = "benchmarks" diff --git a/src/ir_generator.rs b/src/ir_generator.rs new file mode 100644 index 0000000..ec57dee --- /dev/null +++ b/src/ir_generator.rs @@ -0,0 +1,187 @@ +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}; +use std::collections::HashMap; +use std::sync::Arc; + +/// Generates IR (Intermediate Representation) from nu AST. +pub struct IrGenerator<'a> { + // Immutable reference to a compiler after the typechecker pass + compiler: &'a Compiler, + block: IrBlock, + errors: Vec, +} + +impl<'a> IrGenerator<'a> { + pub fn new(compiler: &'a Compiler) -> Self { + Self { + compiler, + block: IrBlock { + instructions: vec![], + spans: vec![], + data: Arc::new([]), + ast: vec![], + comments: vec![], + register_count: 0, + file_count: 0, + }, + errors: vec![], + } + } + + /// 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) { + let mut instructions = vec![]; + let mut next_free_reg = RegId::new(0); + let mut last_reg = RegId::new(0); + let mut node_to_reg: HashMap = HashMap::new(); + for (i, ast_node) in self.compiler.ast_nodes.iter().enumerate() { + match ast_node { + AstNode::Plus | AstNode::Multiply => {} + AstNode::Int => { + let val = match std::str::from_utf8(self.compiler.get_span_contents(NodeId(i))) + { + Ok(val) => val, + Err(err) => { + self.error( + format!("failed to convert a node to string: {err}"), + NodeId(i), + ); + return; + } + }; + let val = match val.parse::() { + Ok(val) => val, + Err(err) => { + self.error( + format!("failed to convert a node to string: {err}"), + NodeId(i), + ); + return; + } + }; + instructions.push(Instruction::LoadLiteral { + dst: next_free_reg, + lit: Literal::Int(val), + }); + eprintln!("{} => {}", i, next_free_reg); + node_to_reg.insert(NodeId(i), next_free_reg); + next_free_reg = RegId::new(next_free_reg.get() + 1); + } + AstNode::BinaryOp { lhs, op, rhs } => { + let l = match node_to_reg.get(lhs) { + Some(l) => l, + None => { + self.error("failed to find register for given node".to_string(), *lhs); + return; + } + }; + let r = match node_to_reg.get(rhs) { + Some(r) => r, + None => { + self.error("failed to find register for given node".to_string(), *lhs); + return; + } + }; + let o = match self.node_to_operator(*op) { + Ok(o) => o, + Err(e) => { + self.errors.push(e); + return; + } + }; + instructions.push(Instruction::BinaryOp { + lhs_dst: *l, + op: o, + rhs: *r, + }); + last_reg = *l; + node_to_reg.insert(NodeId(i), *l); + } + _ => { + self.error(format!("node {:?} not suported yet", ast_node), NodeId(i)); + } + } + } + + instructions.push(Instruction::Return { src: last_reg }); + + let mut spans = vec![]; + let mut ast = vec![]; + for _ in 0..instructions.len() { + spans.push(Span { start: 0, end: 0 }); + ast.push(None); + } + self.block = IrBlock { + instructions, + spans, + data: Arc::new([]), + ast, + comments: Vec::new(), + register_count: next_free_reg.get(), + file_count: 0, + }; + } + + /// Returns generated IR block. + /// + /// Call `generate` before using this method and ensure there are no errors. + pub fn block(self) -> IrBlock { + self.block + } + + /// Returns errors encountered during IR generation step. + /// + /// Call `generate` before using this method. + pub fn errors(&self) -> &Vec { + &self.errors + } + + /// 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.block.register_count)); + result.push_str(&format!("file_count: {}\n", self.block.register_count)); + + for (idx, instruction) in self.block.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 + } + + fn node_to_operator(&self, node_id: NodeId) -> Result { + match self.compiler.get_node(node_id) { + AstNode::Plus => Ok(Operator::Math(Math::Plus)), + AstNode::Multiply => Ok(Operator::Math(Math::Multiply)), + node => Err(SourceError { + message: format!("unrecognized operator {:?}", node), + node_id, + severity: Severity::Error, + }), + } + } + + 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 39ebde3..ddae7b6 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 naming; pub mod parser; pub mod protocol; 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..04a3dcf 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,9 @@ snapshot_kind: text 19: bool 20: bool 21: bool +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 1): node Equal not suported yet +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..afc2815 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,10 @@ 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 +Error (NodeId 2): node Float not suported yet +Error (NodeId 0): failed to find register for given node 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..00be972 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,10 @@ snapshot_kind: text 41: list> 42: list> 43: list> +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 1): node Equal not suported yet +Error (NodeId 2): node Float not suported yet +Error (NodeId 0): failed to find register for given node 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 04a601d..ae9f3ed 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 @@ -85,3 +85,36 @@ snapshot_kind: text 34: int 35: any 36: any +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 0): node Name not suported yet +Error (NodeId 1): node Name not suported yet +Error (NodeId 2): node String not suported yet +Error (NodeId 7): node Call { parts: [NodeId(0), NodeId(1), NodeId(2), NodeId(6)] } not suported yet +Error (NodeId 8): node Name not suported yet +Error (NodeId 9): node Name not suported yet +Error (NodeId 10): node Name not suported yet +Error (NodeId 11): node Type { name: NodeId(10), params: None, optional: false } not suported yet +Error (NodeId 12): node Param { name: NodeId(9), ty: Some(NodeId(11)) } not suported yet +Error (NodeId 13): node Name not suported yet +Error (NodeId 14): node Name not suported yet +Error (NodeId 15): node Type { name: NodeId(14), params: None, optional: false } not suported yet +Error (NodeId 16): node Param { name: NodeId(13), ty: Some(NodeId(15)) } not suported yet +Error (NodeId 17): node Name not suported yet +Error (NodeId 18): node Name not suported yet +Error (NodeId 19): node Type { name: NodeId(18), params: None, optional: false } not suported yet +Error (NodeId 20): node Param { name: NodeId(17), ty: Some(NodeId(19)) } not suported yet +Error (NodeId 21): node Params([NodeId(12), NodeId(16), NodeId(20)]) not suported yet +Error (NodeId 22): node Variable not suported yet +Error (NodeId 23): node Variable not suported yet +Error (NodeId 24): node Variable not suported yet +Error (NodeId 25): node List([NodeId(22), NodeId(23), NodeId(24)]) not suported yet +Error (NodeId 26): node Block(BlockId(0)) not suported yet +Error (NodeId 27): node Def { name: NodeId(8), params: NodeId(21), return_ty: None, block: NodeId(26) } not suported yet +Error (NodeId 28): node Name not suported yet +Error (NodeId 29): node Name not suported yet +Error (NodeId 30): node String not suported yet +Error (NodeId 32): node String not suported yet +Error (NodeId 30): failed to find register for given node 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..e7297d8 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,21 @@ snapshot_kind: text 21: closure 22: stream 23: stream +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 0): node Variable not suported yet +Error (NodeId 1): node Name not suported yet +Error (NodeId 2): node Name not suported yet +Error (NodeId 3): node Type { name: NodeId(2), params: None, optional: false } not suported yet +Error (NodeId 4): node Param { name: NodeId(1), ty: Some(NodeId(3)) } not suported yet +Error (NodeId 5): node Name not suported yet +Error (NodeId 6): node Name not suported yet +Error (NodeId 7): node Type { name: NodeId(6), params: None, optional: false } not suported yet +Error (NodeId 8): node Param { name: NodeId(5), ty: Some(NodeId(7)) } not suported yet +Error (NodeId 9): node Params([NodeId(4), NodeId(8)]) not suported yet +Error (NodeId 10): node Variable not suported yet +Error (NodeId 12): node Variable not suported yet +Error (NodeId 13): node LessThan not suported yet +Error (NodeId 10): failed to find register for given node 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..a8dfda5 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,33 @@ snapshot_kind: text 22: list 23: () 24: () +==== IR ==== +register_count: 0 +file_count: 0 +0: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 0): node Name not suported yet +Error (NodeId 1): node Name not suported yet +Error (NodeId 2): node Param { name: NodeId(1), ty: None } not suported yet +Error (NodeId 3): node Name not suported yet +Error (NodeId 4): node Name not suported yet +Error (NodeId 5): node Type { name: NodeId(4), params: None, optional: false } not suported yet +Error (NodeId 6): node Param { name: NodeId(3), ty: Some(NodeId(5)) } not suported yet +Error (NodeId 7): node Name not suported yet +Error (NodeId 8): node Name not suported yet +Error (NodeId 9): node Name not suported yet +Error (NodeId 10): node Name not suported yet +Error (NodeId 11): node Type { name: NodeId(10), params: None, optional: false } not suported yet +Error (NodeId 12): node Params([NodeId(11)]) not suported yet +Error (NodeId 13): node Type { name: NodeId(9), params: Some(NodeId(12)), optional: false } not suported yet +Error (NodeId 14): node Params([NodeId(13)]) not suported yet +Error (NodeId 15): node Type { name: NodeId(8), params: Some(NodeId(14)), optional: false } not suported yet +Error (NodeId 16): node Param { name: NodeId(7), ty: Some(NodeId(15)) } not suported yet +Error (NodeId 17): node Params([NodeId(2), NodeId(6), NodeId(16)]) not suported yet +Error (NodeId 18): node Variable not suported yet +Error (NodeId 19): node Variable not suported yet +Error (NodeId 20): node Variable not suported yet +Error (NodeId 21): node List([NodeId(18), NodeId(19), NodeId(20)]) not suported yet +Error (NodeId 22): node Block(BlockId(0)) not suported yet +Error (NodeId 23): node Def { name: NodeId(0), params: NodeId(17), return_ty: None, block: NodeId(22) } not suported yet +Error (NodeId 24): node Block(BlockId(1)) 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..a53848f 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,16 @@ snapshot_kind: text 29: () 30: () 31: () +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 0): node Variable not suported yet +Error (NodeId 2): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(1), is_mutable: true } not suported yet +Error (NodeId 3): node Variable not suported yet +Error (NodeId 7): node List([NodeId(4), NodeId(5), NodeId(6)]) not suported yet +Error (NodeId 8): node Variable not suported yet +Error (NodeId 9): node Assignment not suported yet +Error (NodeId 10): node Variable not suported yet +Error (NodeId 12): node Variable not suported yet +Error (NodeId 10): failed to find register for given node 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..2dae3d8 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,14 @@ 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 0): node Variable not suported yet +Error (NodeId 2): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(1), is_mutable: true } not suported yet +Error (NodeId 3): node Variable not suported yet +Error (NodeId 7): node List([NodeId(4), NodeId(5), NodeId(6)]) not suported yet +Error (NodeId 8): node Variable not suported yet +Error (NodeId 9): node GreaterThan not suported yet +Error (NodeId 8): failed to find register for given node 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..7d302db 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,12 @@ snapshot_kind: text 17: int 18: int 19: int +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 0): node Variable not suported yet +Error (NodeId 2): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(1), is_mutable: false } not suported yet +Error (NodeId 3): node Variable not suported yet +Error (NodeId 4): node LessThan not suported yet +Error (NodeId 3): failed to find register for given node 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..85b9164 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,15 @@ snapshot_kind: text 6: error ==== TYPE ERRORS ==== Error (NodeId 0): The condition for if branch is not a boolean +==== IR ==== +register_count: 3 +file_count: 3 +0: LoadLiteral { dst: RegId(0), lit: Int(1) } +1: LoadLiteral { dst: RegId(1), lit: Int(4) } +2: LoadLiteral { dst: RegId(2), lit: Int(3) } +3: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 2): node Block(BlockId(0)) not suported yet +Error (NodeId 4): node Block(BlockId(1)) not suported yet +Error (NodeId 5): node If { condition: NodeId(0), then_block: NodeId(2), else_block: Some(NodeId(4)) } not suported yet +Error (NodeId 6): node Block(BlockId(2)) 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..b887168 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,33 @@ 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 +0: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 0): node Name not suported yet +Error (NodeId 1): node Name not suported yet +Error (NodeId 2): node Name not suported yet +Error (NodeId 3): node Name not suported yet +Error (NodeId 4): node Type { name: NodeId(3), params: None, optional: false } not suported yet +Error (NodeId 5): node Name not suported yet +Error (NodeId 6): node Type { name: NodeId(5), params: None, optional: false } not suported yet +Error (NodeId 7): node Params([NodeId(4), NodeId(6)]) not suported yet +Error (NodeId 8): node Type { name: NodeId(2), params: Some(NodeId(7)), optional: false } not suported yet +Error (NodeId 9): node Param { name: NodeId(1), ty: Some(NodeId(8)) } not suported yet +Error (NodeId 10): node Params([NodeId(9)]) not suported yet +Error (NodeId 11): node Variable not suported yet +Error (NodeId 12): node Block(BlockId(0)) not suported yet +Error (NodeId 13): node Def { name: NodeId(0), params: NodeId(10), return_ty: None, block: NodeId(12) } not suported yet +Error (NodeId 14): node Name not suported yet +Error (NodeId 15): node Name not suported yet +Error (NodeId 16): node Name not suported yet +Error (NodeId 17): node Params([]) not suported yet +Error (NodeId 18): node Type { name: NodeId(16), params: Some(NodeId(17)), optional: false } not suported yet +Error (NodeId 19): node Param { name: NodeId(15), ty: Some(NodeId(18)) } not suported yet +Error (NodeId 20): node Params([NodeId(19)]) not suported yet +Error (NodeId 21): node Variable not suported yet +Error (NodeId 22): node Block(BlockId(1)) not suported yet +Error (NodeId 23): node Def { name: NodeId(14), params: NodeId(20), return_ty: None, block: NodeId(22) } not suported yet +Error (NodeId 24): node Block(BlockId(2)) 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..19bee31 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,13 @@ snapshot_kind: text 2: () 3: int 4: int +==== IR ==== +register_count: 1 +file_count: 1 +0: LoadLiteral { dst: RegId(0), lit: Int(123) } +1: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 0): node Variable not suported yet +Error (NodeId 2): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(1), is_mutable: false } not suported yet +Error (NodeId 3): node Variable not suported yet +Error (NodeId 4): node Block(BlockId(0)) 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..4ea2c0d 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,37 @@ 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: 2 +file_count: 2 +0: LoadLiteral { dst: RegId(0), lit: Int(10) } +1: LoadLiteral { dst: RegId(1), lit: Int(123) } +2: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 0): node Variable not suported yet +Error (NodeId 1): node Name not suported yet +Error (NodeId 2): node Type { name: NodeId(1), params: None, optional: false } not suported yet +Error (NodeId 4): node Let { variable_name: NodeId(0), ty: Some(NodeId(2)), initializer: NodeId(3), is_mutable: false } not suported yet +Error (NodeId 5): node Variable not suported yet +Error (NodeId 6): node Name not suported yet +Error (NodeId 7): node Type { name: NodeId(6), params: None, optional: false } not suported yet +Error (NodeId 8): node String not suported yet +Error (NodeId 9): node Let { variable_name: NodeId(5), ty: Some(NodeId(7)), initializer: NodeId(8), is_mutable: false } not suported yet +Error (NodeId 10): node Variable not suported yet +Error (NodeId 11): node Name not suported yet +Error (NodeId 12): node Type { name: NodeId(11), params: None, optional: false } not suported yet +Error (NodeId 14): node Let { variable_name: NodeId(10), ty: Some(NodeId(12)), initializer: NodeId(13), is_mutable: false } not suported yet +Error (NodeId 15): node Variable not suported yet +Error (NodeId 16): node Name not suported yet +Error (NodeId 17): node Name not suported yet +Error (NodeId 18): node Name not suported yet +Error (NodeId 19): node Type { name: NodeId(18), params: None, optional: false } not suported yet +Error (NodeId 20): node Params([NodeId(19)]) not suported yet +Error (NodeId 21): node Type { name: NodeId(17), params: Some(NodeId(20)), optional: false } not suported yet +Error (NodeId 22): node Params([NodeId(21)]) not suported yet +Error (NodeId 23): node Type { name: NodeId(16), params: Some(NodeId(22)), optional: false } not suported yet +Error (NodeId 24): node String not suported yet +Error (NodeId 25): node List([NodeId(24)]) not suported yet +Error (NodeId 26): node List([NodeId(25)]) not suported yet +Error (NodeId 27): node Let { variable_name: NodeId(15), ty: Some(NodeId(23)), initializer: NodeId(26), is_mutable: false } not suported yet +Error (NodeId 28): node Block(BlockId(0)) 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..08915a2 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,29 @@ snapshot_kind: text 18: string 19: list 20: list +==== IR ==== +register_count: 10 +file_count: 10 +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: LoadLiteral { dst: RegId(3), lit: Int(0) } +4: LoadLiteral { dst: RegId(4), lit: Int(1) } +5: LoadLiteral { dst: RegId(5), lit: Int(2) } +6: LoadLiteral { dst: RegId(6), lit: Int(0) } +7: LoadLiteral { dst: RegId(7), lit: Int(1) } +8: LoadLiteral { dst: RegId(8), lit: Int(0) } +9: LoadLiteral { dst: RegId(9), lit: Int(1) } +10: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 3): node List([NodeId(0), NodeId(1), NodeId(2)]) not suported yet +Error (NodeId 7): node List([NodeId(4), NodeId(5), NodeId(6)]) not suported yet +Error (NodeId 8): node String not suported yet +Error (NodeId 9): node String not suported yet +Error (NodeId 10): node String not suported yet +Error (NodeId 11): node List([NodeId(8), NodeId(9), NodeId(10)]) not suported yet +Error (NodeId 14): node Float not suported yet +Error (NodeId 15): node List([NodeId(12), NodeId(13), NodeId(14)]) not suported yet +Error (NodeId 18): node String not suported yet +Error (NodeId 19): node List([NodeId(16), NodeId(17), NodeId(18)]) not suported yet +Error (NodeId 20): node Block(BlockId(0)) 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..1f6445b 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,15 @@ snapshot_kind: text 4: string 5: list 6: list +==== IR ==== +register_count: 1 +file_count: 1 +0: LoadLiteral { dst: RegId(0), lit: Int(1) } +1: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 0): node True not suported yet +Error (NodeId 1): node Null not suported yet +Error (NodeId 3): node String not suported yet +Error (NodeId 4): node String not suported yet +Error (NodeId 5): node List([NodeId(0), NodeId(1), NodeId(2), NodeId(3), NodeId(4)]) not suported yet +Error (NodeId 6): node Block(BlockId(0)) 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..059b11b 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,12 @@ 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 0): node Variable not suported yet +Error (NodeId 2): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(1), is_mutable: true } not suported yet +Error (NodeId 3): node Variable not suported yet +Error (NodeId 4): node GreaterThan not suported yet +Error (NodeId 3): failed to find register for given node 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..f691d85 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,12 @@ snapshot_kind: text 2: int 3: int 4: int +==== IR ==== +register_count: 2 +file_count: 2 +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) } +==== IR ERRORS ==== +Error (NodeId 4): node Block(BlockId(0)) not suported yet 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..d16b98e 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,16 @@ snapshot_kind: text 8: int 9: int 10: int +==== IR ==== +register_count: 4 +file_count: 4 +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: LoadLiteral { dst: RegId(3), lit: Int(4) } +4: BinaryOp { lhs_dst: RegId(1), op: Math(Multiply), rhs: RegId(2) } +5: BinaryOp { lhs_dst: RegId(0), op: Math(Plus), rhs: RegId(1) } +6: BinaryOp { lhs_dst: RegId(0), op: Math(Plus), rhs: RegId(3) } +7: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 10): node Block(BlockId(0)) not suported yet 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..eb40dba 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,14 @@ input_file: tests/mut_.nu 10: int 11: () 12: () +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 0): node Variable not suported yet +Error (NodeId 1): node Name not suported yet +Error (NodeId 2): node Type { name: NodeId(1), params: None, optional: false } not suported yet +Error (NodeId 4): node Let { variable_name: NodeId(0), ty: Some(NodeId(2)), initializer: NodeId(3), is_mutable: true } not suported yet +Error (NodeId 5): node Variable not suported yet +Error (NodeId 6): node Assignment not suported yet +Error (NodeId 5): failed to find register for given node 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..1d05b24 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,14 @@ 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: 2 +file_count: 2 +0: LoadLiteral { dst: RegId(0), lit: Int(1) } +1: LoadLiteral { dst: RegId(1), lit: Int(2) } +2: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 0): node String not suported yet +Error (NodeId 2): node String not suported yet +Error (NodeId 4): node Record { pairs: [(NodeId(0), NodeId(1)), (NodeId(2), NodeId(3))] } not suported yet +Error (NodeId 5): node Block(BlockId(0)) 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..d1b1aa3 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,14 @@ 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: 2 +file_count: 2 +0: LoadLiteral { dst: RegId(0), lit: Int(1) } +1: LoadLiteral { dst: RegId(1), lit: Int(2) } +2: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 0): node String not suported yet +Error (NodeId 2): node String not suported yet +Error (NodeId 4): node Record { pairs: [(NodeId(0), NodeId(1)), (NodeId(2), NodeId(3))] } not suported yet +Error (NodeId 5): node Block(BlockId(0)) 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..3df1651 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,14 @@ 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: 2 +file_count: 2 +0: LoadLiteral { dst: RegId(0), lit: Int(1) } +1: LoadLiteral { dst: RegId(1), lit: Int(2) } +2: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 0): node String not suported yet +Error (NodeId 2): node String not suported yet +Error (NodeId 4): node Record { pairs: [(NodeId(0), NodeId(1)), (NodeId(2), NodeId(3))] } not suported yet +Error (NodeId 5): node Block(BlockId(0)) 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..390902e 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,22 @@ 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 +0: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 0): node Variable not suported yet +Error (NodeId 1): node Name not suported yet +Error (NodeId 2): node Param { name: NodeId(1), ty: None } not suported yet +Error (NodeId 3): node Params([NodeId(2)]) not suported yet +Error (NodeId 4): node Variable not suported yet +Error (NodeId 5): node Block(BlockId(0)) not suported yet +Error (NodeId 6): node Closure { params: Some(NodeId(3)), block: NodeId(5) } not suported yet +Error (NodeId 7): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(6), is_mutable: false } not suported yet +Error (NodeId 8): node Variable not suported yet +Error (NodeId 9): node String not suported yet +Error (NodeId 10): node String not suported yet +Error (NodeId 11): node Record { pairs: [(NodeId(9), NodeId(10))] } not suported yet +Error (NodeId 12): node Let { variable_name: NodeId(8), ty: None, initializer: NodeId(11), is_mutable: false } not suported yet +Error (NodeId 13): node Block(BlockId(1)) 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..ce42149 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,11 @@ snapshot_kind: text 0: string 1: string 2: string +==== IR ==== +register_count: 0 +file_count: 0 +0: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 0): node String not suported yet +Error (NodeId 1): node String not suported yet +Error (NodeId 2): node Block(BlockId(0)) 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..57f6344 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,10 @@ 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 +Error (NodeId 2): node String not suported yet +Error (NodeId 0): failed to find register for given node 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..b08a458 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,19 @@ 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: 4 +file_count: 4 +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: LoadLiteral { dst: RegId(3), lit: Int(4) } +4: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 0): node String not suported yet +Error (NodeId 1): node String not suported yet +Error (NodeId 2): node List([NodeId(0), NodeId(1)]) not suported yet +Error (NodeId 5): node List([NodeId(3), NodeId(4)]) not suported yet +Error (NodeId 8): node List([NodeId(6), NodeId(7)]) not suported yet +Error (NodeId 9): node Table { header: NodeId(2), rows: [NodeId(5), NodeId(8)] } not suported yet +Error (NodeId 10): node Block(BlockId(0)) 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..3603d82 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,19 @@ 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: 4 +file_count: 4 +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: LoadLiteral { dst: RegId(3), lit: Int(4) } +4: Return { src: RegId(0) } +==== IR ERRORS ==== +Error (NodeId 0): node String not suported yet +Error (NodeId 1): node String not suported yet +Error (NodeId 2): node List([NodeId(0), NodeId(1)]) not suported yet +Error (NodeId 5): node List([NodeId(3), NodeId(4)]) not suported yet +Error (NodeId 8): node List([NodeId(6), NodeId(7)]) not suported yet +Error (NodeId 9): node Table { header: NodeId(2), rows: [NodeId(5), NodeId(8)] } not suported yet +Error (NodeId 10): node Block(BlockId(0)) 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..8a2dd5d 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,11 @@ snapshot_kind: text 11: () 12: () 13: () +==== IR ==== +register_count: 0 +file_count: 0 +==== IR ERRORS ==== +Error (NodeId 0): node Variable not suported yet +Error (NodeId 2): node Let { variable_name: NodeId(0), ty: None, initializer: NodeId(1), is_mutable: true } not suported yet +Error (NodeId 4): node LessThan not suported yet +Error (NodeId 4): unrecognized operator LessThan diff --git a/src/test.rs b/src/test.rs index fe5e0b4..1e788e2 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,3 +1,4 @@ +use crate::ir_generator::IrGenerator; use crate::resolver::Resolver; use crate::typechecker::Typechecker; use crate::{compiler::Compiler, parser::Parser}; @@ -35,6 +36,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 }