Added Variablesgit status
This commit is contained in:
		
							parent
							
								
									a0f10931b8
								
							
						
					
					
						commit
						1bc28d02ff
					
				
							
								
								
									
										107
									
								
								src/ast.rs
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								src/ast.rs
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -14,12 +14,14 @@ pub struct Function {
 | 
			
		|||
pub enum Statement {
 | 
			
		||||
    FunctionCall(String, Vec<ValueNode>),
 | 
			
		||||
    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<String, Function>,
 | 
			
		||||
    pub variables: Vec<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait Node {
 | 
			
		||||
| 
						 | 
				
			
			@ -61,6 +64,7 @@ impl AssemblerState {
 | 
			
		|||
    pub fn new() -> AssemblerState {
 | 
			
		||||
        AssemblerState {
 | 
			
		||||
            functions: get_default_functions(),
 | 
			
		||||
            variables: Vec::new(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -114,7 +118,8 @@ F-OUT   JMP           0xFF"
 | 
			
		|||
            assembly: Some(
 | 
			
		||||
                "
 | 
			
		||||
exit:
 | 
			
		||||
F-OUT JMP 0xFF"
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								src/parse.rs
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/parse.rs
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -28,6 +28,7 @@ fn parse_math(tokens: &Vec<Token>) -> ValueNode {
 | 
			
		|||
    if tokens.len() == 1 {
 | 
			
		||||
        return match &tokens[0] {
 | 
			
		||||
            Token::Number(n) => ValueNode::Literal(Literal::Int(n.parse::<i64>().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<Token> = 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<Token> = 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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,7 @@ pub enum Keyword {
 | 
			
		|||
    Return,
 | 
			
		||||
    Function,
 | 
			
		||||
    Let,
 | 
			
		||||
    Assign,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum TokenFinishedUnfinished {
 | 
			
		||||
| 
						 | 
				
			
			@ -37,6 +38,7 @@ fn generate_keyword_map() -> HashMap<String, Keyword> {
 | 
			
		|||
    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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue