Compare commits
No commits in common. "1bc28d02ffa9e900717ab22e8a8df6686b6846cc" and "6c6bac142b5bb04cb7505af1a0c947bdc162a967" have entirely different histories.
1bc28d02ff
...
6c6bac142b
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,2 @@
|
||||||
/target
|
/target
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
test.plonkus
|
|
||||||
|
|
109
src/ast.rs
109
src/ast.rs
|
@ -14,14 +14,12 @@ 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)]
|
||||||
|
@ -38,7 +36,6 @@ 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 {
|
||||||
|
@ -64,7 +61,6 @@ impl AssemblerState {
|
||||||
pub fn new() -> AssemblerState {
|
pub fn new() -> AssemblerState {
|
||||||
AssemblerState {
|
AssemblerState {
|
||||||
functions: get_default_functions(),
|
functions: get_default_functions(),
|
||||||
variables: Vec::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,9 +114,8 @@ F-OUT JMP 0xFF"
|
||||||
assembly: Some(
|
assembly: Some(
|
||||||
"
|
"
|
||||||
exit:
|
exit:
|
||||||
F-OUT JMP 0xFF
|
F-OUT JMP 0xFF"
|
||||||
"
|
.to_string(),
|
||||||
.to_string(),
|
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -132,8 +127,7 @@ 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
|
||||||
;
|
;
|
||||||
|
@ -170,8 +164,6 @@ 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))
|
||||||
|
@ -184,10 +176,9 @@ impl Node for Statement {
|
||||||
.map(char::from)
|
.map(char::from)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
state.variables.pop();
|
|
||||||
|
|
||||||
format!(
|
format!(
|
||||||
";
|
"
|
||||||
|
;
|
||||||
; Stack
|
; Stack
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -218,37 +209,8 @@ F-OUT JMP 0xFF ; Jump to function
|
||||||
"
|
"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Statement::VariableDeclaration(name, value) => {
|
Statement::VariableDeclaration(_name, _value) => {
|
||||||
let assembly = value.to_assembly(state);
|
todo!()
|
||||||
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
|
|
||||||
"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,56 +221,17 @@ 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
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -332,8 +255,9 @@ 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) => {
|
||||||
let assembly = 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
|
||||||
|
@ -366,13 +290,12 @@ 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 = dbg!(parse::ast(tokens));
|
let functions = parse::ast(tokens);
|
||||||
|
|
||||||
let assembly = ast::to_assembly(functions);
|
let assembly = ast::to_assembly(functions);
|
||||||
|
|
||||||
|
|
27
src/parse.rs
27
src/parse.rs
|
@ -28,7 +28,6 @@ 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!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -112,37 +111,13 @@ 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 {
|
||||||
declaration_tokens.push(tokens[*i].clone());
|
|
||||||
*i += 1;
|
*i += 1;
|
||||||
|
declaration_tokens.push(tokens[*i].clone());
|
||||||
}
|
}
|
||||||
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,7 +19,6 @@ pub enum Keyword {
|
||||||
Return,
|
Return,
|
||||||
Function,
|
Function,
|
||||||
Let,
|
Let,
|
||||||
Assign,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TokenFinishedUnfinished {
|
enum TokenFinishedUnfinished {
|
||||||
|
@ -38,7 +37,6 @@ 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
|
||||||
}
|
}
|
||||||
|
|
4
test.plonkus
Normal file
4
test.plonkus
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
fn main {
|
||||||
|
out(42 - 3 - 1,);
|
||||||
|
exit(,);
|
||||||
|
}
|
Loading…
Reference in a new issue