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 /target
Cargo.lock Cargo.lock
test.plonkus

View file

@ -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,8 +118,9 @@ 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

View file

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

View file

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

View file

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

View file

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