Better Expressions And Function Calling Syntax
This commit is contained in:
parent
8f98528a15
commit
ae22ff77da
48
src/ast.rs
48
src/ast.rs
|
@ -13,9 +13,9 @@ pub struct Function {
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Statement {
|
||||
FunctionCall(String, Vec<ValueNode>),
|
||||
VariableDeclaration(String, ValueNode),
|
||||
VariableAssignment(String, ValueNode),
|
||||
FunctionCall(String, Vec<Expression>),
|
||||
VariableDeclaration(String, Expression),
|
||||
VariableAssignment(String, Expression),
|
||||
Scope(Vec<Statement>),
|
||||
}
|
||||
|
||||
|
@ -24,17 +24,16 @@ pub enum Expression {
|
|||
Literal(Literal),
|
||||
Variable(String),
|
||||
Unary(Unary, Box<Expression>),
|
||||
Grouping(Box<Expression>),
|
||||
Binary(BinOp, Box<Expression>, Box<Expression>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Unary {
|
||||
PointerTo,
|
||||
ValueFrom,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum BinOp {
|
||||
Plus,
|
||||
Minus,
|
||||
|
@ -309,12 +308,14 @@ ROM-OUT FLAGS-IN 0x00 ; Add Mode
|
|||
}
|
||||
}
|
||||
|
||||
impl Node for ValueNode {
|
||||
impl Node for Expression {
|
||||
fn to_assembly(&self, state: &mut AssemblerState) -> String {
|
||||
match self {
|
||||
ValueNode::Literal(v) => v.to_assembly(state),
|
||||
ValueNode::Operator(o) => o.to_assembly(state),
|
||||
ValueNode::Variable(name) => {
|
||||
Expression::Literal(v) => v.to_assembly(state),
|
||||
Expression::Binary(o, expr_1, expr_2) => {
|
||||
expr_1.to_assembly(state) + &expr_2.to_assembly(state) + &o.to_assembly(state)
|
||||
}
|
||||
Expression::Variable(name) => {
|
||||
if !state.variables.contains(name) {
|
||||
dbg!(&name);
|
||||
dbg!(&state.variables);
|
||||
|
@ -355,6 +356,9 @@ C-OUT RAM-IN 0xFF
|
|||
"
|
||||
)
|
||||
}
|
||||
Expression::Unary(operator, expr) => {
|
||||
expr.to_assembly(state) + &operator.to_assembly(state)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,14 +389,12 @@ ROM-OUT RAM-IN {v}; Store literal value in RAM"
|
|||
}
|
||||
}
|
||||
|
||||
impl Node for Operator {
|
||||
impl Node for BinOp {
|
||||
fn to_assembly(&self, state: &mut AssemblerState) -> String {
|
||||
match self {
|
||||
Operator::Add(a, b) => {
|
||||
BinOp::Plus => {
|
||||
let assembly = format!(
|
||||
"{}
|
||||
{}
|
||||
|
||||
"
|
||||
SE-OUT RAM-ADDR-U-IN 0xFF ; Set ram address to stack end
|
||||
RAM-OUT C-IN 0xFF ; Output top address onto output register
|
||||
|
||||
|
@ -421,17 +423,13 @@ ALU-OUT SE-IN 0xFF ; Store
|
|||
ALU-OUT RAM-ADDR-U-IN 0xFF ; Store in RAM address
|
||||
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) => {
|
||||
BinOp::Minus => {
|
||||
format!(
|
||||
"{}
|
||||
{}
|
||||
|
||||
"
|
||||
SE-OUT RAM-ADDR-U-IN 0xFF ; Set ram address to stack end
|
||||
RAM-OUT C-IN 0xFF ; Output top address onto output register
|
||||
|
||||
|
@ -462,14 +460,18 @@ ALU-OUT SE-IN 0xFF ; Store
|
|||
ALU-OUT RAM-ADDR-U-IN 0xFF ; Store in RAM address
|
||||
C-OUT RAM-IN 0xFF ; Store address after jump in ram
|
||||
",
|
||||
a.to_assembly(state),
|
||||
b.to_assembly(state)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for Unary {
|
||||
fn to_assembly(&self, state: &mut AssemblerState) -> String {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_assembly(functions: Vec<Function>) -> String {
|
||||
let mut final_product: String = "".to_owned();
|
||||
let mut std_function_assembly = "".to_owned();
|
||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -1,28 +1,17 @@
|
|||
use crate::tokeniser::Token;
|
||||
|
||||
mod ast;
|
||||
mod parse;
|
||||
mod tokeniser;
|
||||
|
||||
fn main() {
|
||||
// let filename: &str = &std::env::args().collect::<Vec<String>>()[1];
|
||||
let filename: &str = &std::env::args().collect::<Vec<String>>()[1];
|
||||
|
||||
// let contents = std::fs::read_to_string(filename).expect(&format!("No file named {}", filename));
|
||||
let contents = std::fs::read_to_string(filename).expect(&format!("No file named {}", filename));
|
||||
|
||||
// let tokens = tokeniser::tokenise(contents);
|
||||
let tokens = tokeniser::tokenise(contents);
|
||||
|
||||
// let functions = dbg!(parse::ast(tokens));
|
||||
let functions = dbg!(parse::ast(tokens));
|
||||
|
||||
// let assembly = ast::to_assembly(functions);
|
||||
let assembly = ast::to_assembly(functions);
|
||||
|
||||
// println!("{}", assembly);
|
||||
|
||||
let mut i: usize = 0;
|
||||
let tokens: Vec<tokeniser::Token> = vec![
|
||||
Token::OpenParanthesis,
|
||||
Token::Star,
|
||||
Token::Number("2".to_string()),
|
||||
Token::CloseParanthesis,
|
||||
];
|
||||
dbg!(parse::parse_expression(&tokens, &mut i));
|
||||
println!("{}", assembly);
|
||||
}
|
||||
|
|
187
src/parse.rs
187
src/parse.rs
|
@ -70,30 +70,16 @@ fn parse_basic(tokens: &Vec<Token>, i: &mut usize) -> Expression {
|
|||
let literal = match &tokens[*i] {
|
||||
Token::Identifier(identifier) => Expression::Variable(identifier.to_owned()),
|
||||
Token::Number(number) => Expression::Literal(Literal::Int(number.parse::<i64>().unwrap())),
|
||||
_ => todo!(),
|
||||
_other => {
|
||||
dbg!(&i);
|
||||
dbg!(_other);
|
||||
todo!()
|
||||
}
|
||||
};
|
||||
*i += 1;
|
||||
literal
|
||||
}
|
||||
|
||||
fn parse_grouping(tokens: &Vec<Token>, i: &mut usize) -> Expression {
|
||||
match &tokens[*i] {
|
||||
Token::OpenParanthesis => {
|
||||
*i += 1;
|
||||
}
|
||||
_ => todo!(),
|
||||
};
|
||||
|
||||
let inner_expression = parse_expression(tokens, i);
|
||||
|
||||
match &tokens[*i] {
|
||||
Token::CloseParanthesis => {}
|
||||
_ => todo!(),
|
||||
};
|
||||
|
||||
inner_expression
|
||||
}
|
||||
|
||||
// TODO: replace parse_math with this recursive function
|
||||
pub fn parse_expression(tokens: &Vec<Token>, i: &mut usize) -> Expression {
|
||||
#[derive(Debug)]
|
||||
|
@ -103,11 +89,17 @@ pub fn parse_expression(tokens: &Vec<Token>, i: &mut usize) -> Expression {
|
|||
Unary(Unary),
|
||||
}
|
||||
|
||||
let start_i = *i;
|
||||
let mut in_expressions_and_operators: Vec<OpExpr> = Vec::new();
|
||||
|
||||
loop {
|
||||
in_expressions_and_operators.push(match &tokens[*i] {
|
||||
Token::OpenParanthesis => OpExpr::Expression(parse_grouping(tokens, i)),
|
||||
Token::OpenParanthesis => {
|
||||
*i += 1;
|
||||
let expr = OpExpr::Expression(parse_expression(tokens, i));
|
||||
*i += 1;
|
||||
expr
|
||||
}
|
||||
Token::Plus => {
|
||||
*i += 1;
|
||||
OpExpr::BinOp(BinOp::Plus)
|
||||
|
@ -124,12 +116,123 @@ pub fn parse_expression(tokens: &Vec<Token>, i: &mut usize) -> Expression {
|
|||
*i += 1;
|
||||
OpExpr::Unary(Unary::PointerTo)
|
||||
}
|
||||
Token::Number(_) => OpExpr::Expression(parse_basic(tokens, i)),
|
||||
Token::Number(_) => {
|
||||
dbg!(OpExpr::Expression(parse_basic(tokens, i)))
|
||||
}
|
||||
Token::Identifier(_) => OpExpr::Expression(parse_basic(tokens, i)),
|
||||
_other => break,
|
||||
});
|
||||
}
|
||||
dbg!(in_expressions_and_operators);
|
||||
Expression::Variable("a".to_string())
|
||||
|
||||
dbg!(&i);
|
||||
dbg!(&in_expressions_and_operators);
|
||||
|
||||
if in_expressions_and_operators.len() == 1 {
|
||||
return match &in_expressions_and_operators.pop().unwrap() {
|
||||
OpExpr::Expression(expression) => expression.to_owned(),
|
||||
_ => {
|
||||
todo!()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
*i = start_i;
|
||||
|
||||
let prioritizing_order_binops: Vec<Vec<BinOp>> = vec![vec![BinOp::Plus, BinOp::Minus]];
|
||||
|
||||
let prioritizing_order_unaryops: Vec<Vec<Unary>> =
|
||||
vec![vec![Unary::ValueFrom, Unary::PointerTo]];
|
||||
|
||||
let mut ordered_ops: Vec<(usize, bool)> = Vec::new();
|
||||
|
||||
for prioritizing_order in prioritizing_order_binops {
|
||||
for j in (0..in_expressions_and_operators.len()).rev() {
|
||||
let operator = match &in_expressions_and_operators[j] {
|
||||
OpExpr::BinOp(binop) => binop,
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
if prioritizing_order.contains(operator) {
|
||||
ordered_ops.push((j, true));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
for prioritizing_order in prioritizing_order_unaryops {
|
||||
for j in (0..in_expressions_and_operators.len()).rev() {
|
||||
let operator = match &in_expressions_and_operators[j] {
|
||||
OpExpr::Unary(unary) => unary,
|
||||
_other => continue,
|
||||
};
|
||||
|
||||
if prioritizing_order.contains(operator) {
|
||||
ordered_ops.push((j, false));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let this_operator = ordered_ops.get(0);
|
||||
|
||||
let this_operator = match this_operator {
|
||||
Some(val) => val.to_owned(),
|
||||
None => return parse_basic(tokens, i),
|
||||
};
|
||||
|
||||
dbg!(this_operator);
|
||||
|
||||
match this_operator {
|
||||
(index, true) => {
|
||||
let mut start_vec = Vec::new();
|
||||
|
||||
for i in 0..(index + *i) {
|
||||
start_vec.push(tokens[i].clone());
|
||||
}
|
||||
|
||||
start_vec.push(Token::Semi);
|
||||
dbg!(&start_vec);
|
||||
|
||||
let start = parse_expression(&start_vec, i);
|
||||
// let start = Expression::Literal(Literal::Int(42));
|
||||
|
||||
dbg!(&start);
|
||||
|
||||
*i += 1;
|
||||
|
||||
dbg!(&i);
|
||||
let end = parse_expression(tokens, i);
|
||||
|
||||
Expression::Binary(
|
||||
match &in_expressions_and_operators[index] {
|
||||
OpExpr::BinOp(binop) => binop.to_owned(),
|
||||
_other => {
|
||||
dbg!(start);
|
||||
dbg!(end);
|
||||
dbg!(_other);
|
||||
todo!()
|
||||
}
|
||||
},
|
||||
Box::new(start),
|
||||
Box::new(end),
|
||||
)
|
||||
}
|
||||
(index, false) => {
|
||||
*i += 1;
|
||||
|
||||
let end = parse_expression(tokens, i);
|
||||
|
||||
Expression::Unary(
|
||||
match &in_expressions_and_operators[index] {
|
||||
OpExpr::Unary(unary) => unary.to_owned(),
|
||||
_other => {
|
||||
dbg!(end);
|
||||
dbg!(_other);
|
||||
todo!()
|
||||
}
|
||||
},
|
||||
Box::new(end),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_statements(tokens: &Vec<Token>, i: &mut usize) -> Vec<Statement> {
|
||||
|
@ -156,13 +259,7 @@ fn parse_statements(tokens: &Vec<Token>, i: &mut usize) -> Vec<Statement> {
|
|||
};
|
||||
|
||||
*i += 1;
|
||||
|
||||
let mut declaration_tokens: Vec<Token> = Vec::new();
|
||||
while tokens[*i] != Token::Semi {
|
||||
declaration_tokens.push(tokens[*i].clone());
|
||||
*i += 1;
|
||||
}
|
||||
Statement::VariableDeclaration(name, parse_math(&declaration_tokens))
|
||||
Statement::VariableDeclaration(name, parse_expression(tokens, i))
|
||||
}
|
||||
Token::Keyword(Keyword::Assign) => {
|
||||
*i += 1;
|
||||
|
@ -179,39 +276,27 @@ fn parse_statements(tokens: &Vec<Token>, i: &mut usize) -> Vec<Statement> {
|
|||
|
||||
*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))
|
||||
Statement::VariableAssignment(name, parse_expression(tokens, i))
|
||||
}
|
||||
Token::Identifier(identifier) => {
|
||||
*i += 1;
|
||||
|
||||
let mut declaration_tokens: Vec<Vec<Token>> = Vec::new();
|
||||
let mut arguments: Vec<Expression> = Vec::new();
|
||||
|
||||
*i += 1;
|
||||
while tokens[*i] != Token::CloseParanthesis {
|
||||
let mut argument_tokens: Vec<Token> = Vec::new();
|
||||
while tokens[*i] != Token::Comma {
|
||||
argument_tokens.push(tokens[*i].clone());
|
||||
*i += 1;
|
||||
if tokens[*i] == Token::CloseParanthesis {
|
||||
break;
|
||||
}
|
||||
declaration_tokens.push(argument_tokens);
|
||||
*i += 1;
|
||||
dbg!(&i);
|
||||
dbg!(tokens);
|
||||
dbg!(&tokens[*i]);
|
||||
arguments.push(parse_expression(tokens, i));
|
||||
}
|
||||
|
||||
*i += 1;
|
||||
|
||||
let mut arguments: Vec<ValueNode> = Vec::new();
|
||||
|
||||
for token_vec in &declaration_tokens {
|
||||
if token_vec == &Vec::new() {
|
||||
continue;
|
||||
}
|
||||
arguments.push(parse_math(token_vec));
|
||||
}
|
||||
dbg!(&arguments);
|
||||
|
||||
Statement::FunctionCall(identifier.to_owned(), arguments)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue