Better Expressions And Function Calling Syntax

This commit is contained in:
vanten 2023-09-24 13:24:52 +02:00
parent 8f98528a15
commit ae22ff77da
Signed by: vanten-s
GPG key ID: DE3060396884D3F2
3 changed files with 168 additions and 92 deletions

View file

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

View file

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

View file

@ -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;
}
declaration_tokens.push(argument_tokens);
*i += 1;
if tokens[*i] == Token::CloseParanthesis {
break;
}
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)
}