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