Compare commits

..

2 commits

Author SHA1 Message Date
vanten-s 1bc28d02ff
Added Variablesgit status 2023-09-17 16:27:06 +02:00
vanten-s a0f10931b8
Removed test.plonkus 2023-09-17 16:25:33 +02:00
6 changed files with 123 additions and 22 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
/target
Cargo.lock
test.plonkus

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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
}

View file

@ -1,4 +0,0 @@
fn main {
out(42 - 3 - 1,);
exit(,);
}