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 {
|
pub enum Statement {
|
||||||
FunctionCall(String, Vec<ValueNode>),
|
FunctionCall(String, Vec<ValueNode>),
|
||||||
VariableDeclaration(String, ValueNode),
|
VariableDeclaration(String, ValueNode),
|
||||||
|
VariableAssignment(String, ValueNode),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ValueNode {
|
pub enum ValueNode {
|
||||||
Literal(Literal),
|
Literal(Literal),
|
||||||
Operator(Operator),
|
Operator(Operator),
|
||||||
|
Variable(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -36,6 +38,7 @@ pub enum Operator {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct AssemblerState {
|
pub struct AssemblerState {
|
||||||
pub functions: HashMap<String, Function>,
|
pub functions: HashMap<String, Function>,
|
||||||
|
pub variables: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Node {
|
pub trait Node {
|
||||||
|
@ -61,6 +64,7 @@ impl AssemblerState {
|
||||||
pub fn new() -> AssemblerState {
|
pub fn new() -> AssemblerState {
|
||||||
AssemblerState {
|
AssemblerState {
|
||||||
functions: get_default_functions(),
|
functions: get_default_functions(),
|
||||||
|
variables: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +118,8 @@ F-OUT JMP 0xFF"
|
||||||
assembly: Some(
|
assembly: Some(
|
||||||
"
|
"
|
||||||
exit:
|
exit:
|
||||||
F-OUT JMP 0xFF"
|
F-OUT JMP 0xFF
|
||||||
|
"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -127,7 +132,8 @@ impl Node for Function {
|
||||||
match &self.assembly {
|
match &self.assembly {
|
||||||
Some(v) => v.to_string(),
|
Some(v) => v.to_string(),
|
||||||
None => format!(
|
None => format!(
|
||||||
"{}:\n{}
|
"{}:
|
||||||
|
{}
|
||||||
;
|
;
|
||||||
; Pop the return address of the stack
|
; Pop the return address of the stack
|
||||||
;
|
;
|
||||||
|
@ -164,6 +170,8 @@ impl Node for Statement {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.variables.push(name.to_owned());
|
||||||
|
|
||||||
let argument_assembly: String = arguments
|
let argument_assembly: String = arguments
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|x| x.to_assembly(state))
|
.map(|x| x.to_assembly(state))
|
||||||
|
@ -176,9 +184,10 @@ impl Node for Statement {
|
||||||
.map(char::from)
|
.map(char::from)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
state.variables.pop();
|
||||||
|
|
||||||
format!(
|
format!(
|
||||||
"
|
";
|
||||||
;
|
|
||||||
; Stack
|
; Stack
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -209,8 +218,37 @@ F-OUT JMP 0xFF ; Jump to function
|
||||||
"
|
"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Statement::VariableDeclaration(_name, _value) => {
|
Statement::VariableDeclaration(name, value) => {
|
||||||
todo!()
|
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 {
|
match self {
|
||||||
ValueNode::Literal(v) => v.to_assembly(state),
|
ValueNode::Literal(v) => v.to_assembly(state),
|
||||||
ValueNode::Operator(o) => o.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 {
|
impl Node for Literal {
|
||||||
fn to_assembly(&self, _state: &mut AssemblerState) -> String {
|
fn to_assembly(&self, state: &mut AssemblerState) -> String {
|
||||||
match self {
|
match self {
|
||||||
Literal::Int(v) => {
|
Literal::Int(v) => {
|
||||||
|
state.variables.push(v.to_string());
|
||||||
format!(
|
format!(
|
||||||
"
|
";
|
||||||
;
|
|
||||||
; Stack
|
; Stack
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -255,9 +332,8 @@ impl Node for Operator {
|
||||||
fn to_assembly(&self, state: &mut AssemblerState) -> String {
|
fn to_assembly(&self, state: &mut AssemblerState) -> String {
|
||||||
match self {
|
match self {
|
||||||
Operator::Add(a, b) => {
|
Operator::Add(a, b) => {
|
||||||
format!(
|
let assembly = format!(
|
||||||
"
|
"{}
|
||||||
{}
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SE-OUT RAM-ADDR-U-IN 0xFF ; Set ram address to stack end
|
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),
|
a.to_assembly(state),
|
||||||
b.to_assembly(state)
|
b.to_assembly(state)
|
||||||
)
|
);
|
||||||
|
state.variables.pop();
|
||||||
|
assembly
|
||||||
}
|
}
|
||||||
Operator::Sub(a, b) => {
|
Operator::Sub(a, b) => {
|
||||||
format!(
|
format!(
|
||||||
"
|
"{}
|
||||||
{}
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SE-OUT RAM-ADDR-U-IN 0xFF ; Set ram address to stack end
|
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 tokens = tokeniser::tokenise(contents);
|
||||||
|
|
||||||
let functions = parse::ast(tokens);
|
let functions = dbg!(parse::ast(tokens));
|
||||||
|
|
||||||
let assembly = ast::to_assembly(functions);
|
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 {
|
if tokens.len() == 1 {
|
||||||
return match &tokens[0] {
|
return match &tokens[0] {
|
||||||
Token::Number(n) => ValueNode::Literal(Literal::Int(n.parse::<i64>().unwrap())),
|
Token::Number(n) => ValueNode::Literal(Literal::Int(n.parse::<i64>().unwrap())),
|
||||||
|
Token::Identifier(identifier) => ValueNode::Variable(identifier.to_owned()),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -111,13 +112,37 @@ fn parse_statement(
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
*i += 1;
|
||||||
|
|
||||||
let mut declaration_tokens: Vec<Token> = Vec::new();
|
let mut declaration_tokens: Vec<Token> = Vec::new();
|
||||||
while tokens[*i] != Token::Semi {
|
while tokens[*i] != Token::Semi {
|
||||||
*i += 1;
|
|
||||||
declaration_tokens.push(tokens[*i].clone());
|
declaration_tokens.push(tokens[*i].clone());
|
||||||
|
*i += 1;
|
||||||
}
|
}
|
||||||
Statement::VariableDeclaration(name, parse_math(&declaration_tokens))
|
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) => {
|
Token::Identifier(identifier) => {
|
||||||
*i += 1;
|
*i += 1;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ pub enum Keyword {
|
||||||
Return,
|
Return,
|
||||||
Function,
|
Function,
|
||||||
Let,
|
Let,
|
||||||
|
Assign,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TokenFinishedUnfinished {
|
enum TokenFinishedUnfinished {
|
||||||
|
@ -37,6 +38,7 @@ fn generate_keyword_map() -> HashMap<String, Keyword> {
|
||||||
keywords.insert("return".to_string(), K::Return);
|
keywords.insert("return".to_string(), K::Return);
|
||||||
keywords.insert("fn".to_string(), K::Function);
|
keywords.insert("fn".to_string(), K::Function);
|
||||||
keywords.insert("let".to_string(), K::Let);
|
keywords.insert("let".to_string(), K::Let);
|
||||||
|
keywords.insert("assign".to_string(), K::Assign);
|
||||||
|
|
||||||
keywords
|
keywords
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue