From 1bc28d02ffa9e900717ab22e8a8df6686b6846cc Mon Sep 17 00:00:00 2001 From: vanten-s Date: Sun, 17 Sep 2023 16:27:06 +0200 Subject: [PATCH] Added Variablesgit status --- src/ast.rs | 109 ++++++++++++++++++++++++++++++++++++++++------- src/main.rs | 2 +- src/parse.rs | 27 +++++++++++- src/tokeniser.rs | 2 + 4 files changed, 122 insertions(+), 18 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 8c56714..bdeb2f6 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -14,12 +14,14 @@ pub struct Function { pub enum Statement { FunctionCall(String, Vec), VariableDeclaration(String, ValueNode), + VariableAssignment(String, ValueNode), } #[derive(Debug, Clone)] pub enum ValueNode { Literal(Literal), Operator(Operator), + Variable(String), } #[derive(Debug, Clone)] @@ -36,6 +38,7 @@ pub enum Operator { #[derive(Debug, Clone)] pub struct AssemblerState { pub functions: HashMap, + pub variables: Vec, } pub trait Node { @@ -61,6 +64,7 @@ impl AssemblerState { pub fn new() -> AssemblerState { AssemblerState { functions: get_default_functions(), + variables: Vec::new(), } } } @@ -114,8 +118,9 @@ F-OUT JMP 0xFF" assembly: Some( " exit: -F-OUT JMP 0xFF" - .to_string(), +F-OUT JMP 0xFF +" + .to_string(), ), }, ); @@ -127,7 +132,8 @@ impl Node for Function { match &self.assembly { Some(v) => v.to_string(), None => format!( - "{}:\n{} + "{}: +{} ; ; Pop the return address of the stack ; @@ -164,6 +170,8 @@ impl Node for Statement { todo!() } + state.variables.push(name.to_owned()); + let argument_assembly: String = arguments .into_iter() .map(|x| x.to_assembly(state)) @@ -176,9 +184,10 @@ impl Node for Statement { .map(char::from) .collect(); + state.variables.pop(); + format!( - " -; + "; ; Stack ; @@ -209,8 +218,37 @@ F-OUT JMP 0xFF ; Jump to function " ) } - Statement::VariableDeclaration(_name, _value) => { - todo!() + Statement::VariableDeclaration(name, value) => { + let assembly = value.to_assembly(state); + state.variables.pop(); + state.variables.push(name.to_owned()); + assembly + } + Statement::VariableAssignment(name, value) => { + let value_assembly = value.to_assembly(state); + state.variables.pop(); + + let stack_pos = state.variables.len() + - state.variables.iter().position(|x| x == name).unwrap() + - 1; + + format!( + "{value_assembly} +SE-OUT RAM-ADDR-U-IN 0xFF ; Move RAM Pointer To Correct Position +RAM-OUT C-IN 0xFF ; Move The Contents Of The RAM To The C Register + +ROM-OUT FLAGS-IN 0x80 ; Subtract Mode +SE-OUT A-IN 0xFF ; Fetch SE +ROM-OUT B-IN 0x01 ; Subtract 1 +ALU-OUT SE-IN 0xFF ; Output SE-1 into SE + +SE-OUT A-IN 0xFF ; Fetch SE +ROM-OUT B-IN {stack_pos} ; Subtract Stack Position From SE +ALU-OUT RAM-ADDR-U-IN 0xFF ; Move RAM Pointer To Correct Position +C-OUT RAM-IN 0xFF +ROM-OUT FLAGS-IN 0x00 ; Add Mode +" + ) } } } @@ -221,17 +259,56 @@ impl Node for ValueNode { match self { ValueNode::Literal(v) => v.to_assembly(state), ValueNode::Operator(o) => o.to_assembly(state), + ValueNode::Variable(name) => { + if !state.variables.contains(name) { + todo!(); + } + + let stack_position = state.variables.len() + - state.variables.iter().position(|x| x == name).unwrap() + - 1; + + dbg!(&state.variables); + state.variables.push(name.to_owned()); + + format!( + "; +; Get From Stack +; + +; Get value of variable {name} + +ROM-OUT FLAGS-IN 0x80 ; Subtract Mode +SE-OUT A-IN 0xFF ; Fetch SE +ROM-OUT B-IN {stack_position} ; Subtract Position Of Variable In Stack +ALU-OUT RAM-ADDR-U-IN 0xFF ; Set RAM Address To Position Of Variable In RAM +ROM-OUT FLAGS-IN 0x00 ; Add Mode +RAM-OUT C-IN 0xFF ; Put Variable Value In C Register + +; +; Push To Top Of Stack +; + +; Add One To SE + +ROM-OUT B-IN 0x01 +ALU-OUT SE-IN 0xFF +SE-OUT RAM-ADDR-U-IN 0xFF +C-OUT RAM-IN 0xFF +" + ) + } } } } impl Node for Literal { - fn to_assembly(&self, _state: &mut AssemblerState) -> String { + fn to_assembly(&self, state: &mut AssemblerState) -> String { match self { Literal::Int(v) => { + state.variables.push(v.to_string()); format!( - " -; + "; ; Stack ; @@ -255,9 +332,8 @@ impl Node for Operator { fn to_assembly(&self, state: &mut AssemblerState) -> String { match self { Operator::Add(a, b) => { - format!( - " -{} + let assembly = format!( + "{} {} SE-OUT RAM-ADDR-U-IN 0xFF ; Set ram address to stack end @@ -290,12 +366,13 @@ C-OUT RAM-IN 0xFF ; Store address after jump in ram ", a.to_assembly(state), b.to_assembly(state) - ) + ); + state.variables.pop(); + assembly } Operator::Sub(a, b) => { format!( - " -{} + "{} {} SE-OUT RAM-ADDR-U-IN 0xFF ; Set ram address to stack end diff --git a/src/main.rs b/src/main.rs index 87c1654..a50ee9e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ fn main() { let tokens = tokeniser::tokenise(contents); - let functions = parse::ast(tokens); + let functions = dbg!(parse::ast(tokens)); let assembly = ast::to_assembly(functions); diff --git a/src/parse.rs b/src/parse.rs index d258998..1b2cfbd 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -28,6 +28,7 @@ fn parse_math(tokens: &Vec) -> ValueNode { if tokens.len() == 1 { return match &tokens[0] { Token::Number(n) => ValueNode::Literal(Literal::Int(n.parse::().unwrap())), + Token::Identifier(identifier) => ValueNode::Variable(identifier.to_owned()), _ => todo!(), }; } @@ -111,13 +112,37 @@ fn parse_statement( _ => todo!(), }; + *i += 1; + let mut declaration_tokens: Vec = Vec::new(); while tokens[*i] != Token::Semi { - *i += 1; declaration_tokens.push(tokens[*i].clone()); + *i += 1; } Statement::VariableDeclaration(name, parse_math(&declaration_tokens)) } + Token::Keyword(Keyword::Assign) => { + *i += 1; + let name = match tokens[*i].clone() { + Token::Identifier(identifier) => identifier, + _ => todo!(), + }; + + *i += 1; + match tokens[*i].clone() { + Token::Equals => {} + _ => todo!(), + }; + + *i += 1; + + let mut declaration_tokens: Vec = Vec::new(); + while tokens[*i] != Token::Semi { + declaration_tokens.push(tokens[*i].clone()); + *i += 1; + } + Statement::VariableAssignment(name, parse_math(&declaration_tokens)) + } Token::Identifier(identifier) => { *i += 1; diff --git a/src/tokeniser.rs b/src/tokeniser.rs index db94792..c031b65 100644 --- a/src/tokeniser.rs +++ b/src/tokeniser.rs @@ -19,6 +19,7 @@ pub enum Keyword { Return, Function, Let, + Assign, } enum TokenFinishedUnfinished { @@ -37,6 +38,7 @@ fn generate_keyword_map() -> HashMap { keywords.insert("return".to_string(), K::Return); keywords.insert("fn".to_string(), K::Function); keywords.insert("let".to_string(), K::Let); + keywords.insert("assign".to_string(), K::Assign); keywords }