MAJOR refactoring and scopes

This commit is contained in:
vanten-s 2023-09-17 21:52:14 +02:00
parent 1bc28d02ff
commit 3753f6d8f5
Signed by: vanten-s
GPG key ID: DE3060396884D3F2
3 changed files with 166 additions and 141 deletions

View file

@ -7,6 +7,7 @@ use std::collections::HashMap;
pub struct Function { pub struct Function {
pub name: String, pub name: String,
pub statements: Vec<Statement>, pub statements: Vec<Statement>,
pub n_args: u64,
assembly: Option<String>, assembly: Option<String>,
} }
@ -15,6 +16,7 @@ pub enum Statement {
FunctionCall(String, Vec<ValueNode>), FunctionCall(String, Vec<ValueNode>),
VariableDeclaration(String, ValueNode), VariableDeclaration(String, ValueNode),
VariableAssignment(String, ValueNode), VariableAssignment(String, ValueNode),
Scope(Vec<Statement>),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -46,10 +48,11 @@ pub trait Node {
} }
impl Function { impl Function {
pub fn new(name: String, statements: Vec<Statement>) -> Function { pub fn new(name: String, n_args: u64, statements: Vec<Statement>) -> Function {
Function { Function {
name, name,
statements, statements,
n_args,
assembly: None, assembly: None,
} }
} }
@ -74,8 +77,9 @@ fn get_default_functions() -> HashMap<String, Function> {
functions.insert( functions.insert(
"out".to_string(), "out".to_string(),
Function { Function {
name: "exit".to_string(), name: "out".to_string(),
statements: vec![], statements: vec![],
n_args: 1,
assembly: Some( assembly: Some(
" "
out: out:
@ -115,6 +119,7 @@ F-OUT JMP 0xFF"
Function { Function {
name: "exit".to_string(), name: "exit".to_string(),
statements: vec![], statements: vec![],
n_args: 0,
assembly: Some( assembly: Some(
" "
exit: exit:
@ -165,13 +170,50 @@ F-OUT JMP 0xFF
impl Node for Statement { impl Node for Statement {
fn to_assembly(&self, state: &mut AssemblerState) -> String { fn to_assembly(&self, state: &mut AssemblerState) -> String {
match self { match self {
Statement::Scope(statements) => {
let init_assembly = "
ROM-OUT FLAGS-IN 0x00
SE-OUT A-IN 0xFF
ROM-OUT B-IN 0x01
ALU-OUT SE-IN 0xFF
"
.to_string();
state.variables.push("start scope".to_string());
let statement_assembly = statements
.iter()
.map(|x| x.to_assembly(state))
.collect::<Vec<String>>()
.join("\n");
let mut stop_assembly = "".to_string();
while state.variables.contains(&"start scope".to_string()) {
stop_assembly += &format!(
"
ROM-OUT FLAGS-IN 0x80
SE-OUT A-IN 0xFF
ROM-OUT B-IN 0x01
ALU-OUT SE-IN 0xFF
ROM-OUT FLAGS-IN 0x00"
);
state.variables.pop();
}
format!(
"{init_assembly}
{statement_assembly}
{stop_assembly}"
)
}
Statement::FunctionCall(name, arguments) => { Statement::FunctionCall(name, arguments) => {
if !state.functions.contains_key(name) { if !state.functions.contains_key(name) {
todo!() todo!()
} }
state.variables.push(name.to_owned());
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,6 +226,10 @@ impl Node for Statement {
.map(char::from) .map(char::from)
.collect(); .collect();
for _ in 0..state.functions.get(name).unwrap().n_args {
state.variables.pop();
}
state.variables.pop(); state.variables.pop();
format!( format!(
@ -261,6 +307,8 @@ impl Node for ValueNode {
ValueNode::Operator(o) => o.to_assembly(state), ValueNode::Operator(o) => o.to_assembly(state),
ValueNode::Variable(name) => { ValueNode::Variable(name) => {
if !state.variables.contains(name) { if !state.variables.contains(name) {
dbg!(&name);
dbg!(&state.variables);
todo!(); todo!();
} }
@ -268,7 +316,6 @@ impl Node for ValueNode {
- state.variables.iter().position(|x| x == name).unwrap() - state.variables.iter().position(|x| x == name).unwrap()
- 1; - 1;
dbg!(&state.variables);
state.variables.push(name.to_owned()); state.variables.push(name.to_owned());
format!( format!(

View file

@ -4,20 +4,6 @@ use crate::ast::*;
use crate::tokeniser::Keyword; use crate::tokeniser::Keyword;
use crate::tokeniser::Token; use crate::tokeniser::Token;
#[derive(Clone, Debug)]
enum ParseState {
Function(Function),
Statement(Function),
None(Vec<Function>),
}
impl Function {
fn push_statement(&mut self, statement: Statement) -> Function {
self.statements.push(statement);
self.to_owned()
}
}
fn parse_math(tokens: &Vec<Token>) -> ValueNode { fn parse_math(tokens: &Vec<Token>) -> ValueNode {
let mut prioritizing_order: HashMap<i64, HashSet<Token>> = HashMap::new(); let mut prioritizing_order: HashMap<i64, HashSet<Token>> = HashMap::new();
prioritizing_order.insert(0, HashSet::from([Token::Plus, Token::Minus])); prioritizing_order.insert(0, HashSet::from([Token::Plus, Token::Minus]));
@ -80,145 +66,135 @@ fn parse_math(tokens: &Vec<Token>) -> ValueNode {
}; };
} }
fn parse_statement( fn parse_statements(tokens: &Vec<Token>, starting_i: usize) -> (Vec<Statement>, usize) {
parse_state: &mut ParseState, let mut i = starting_i;
i: &mut usize, let mut statements = Vec::new();
tokens: &Vec<Token>, while i < tokens.len() {
functions: &Vec<Function>, statements.push(match &tokens[i] {
) -> ParseState { Token::OpenSquiglyBracket => {
let mut current_function = match parse_state { let (statements, added_to_i) = parse_statements(tokens, i + 1);
ParseState::Statement(f) => f.to_owned(), i = added_to_i + 1;
_ => todo!(), Statement::Scope(statements)
}; }
Token::Keyword(Keyword::Let) => {
i += 1;
let name = match tokens[i].clone() {
Token::Identifier(identifier) => identifier,
_ => todo!(),
};
if tokens[i.to_owned()] == Token::CloseSquiglyBracket { i += 1;
let mut functions = functions.to_owned(); match tokens[i].clone() {
functions.push(current_function); Token::Equals => {}
_ => todo!(),
};
return ParseState::None(functions); 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))
}
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;
let mut declaration_tokens: Vec<Vec<Token>> = 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;
}
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));
}
Statement::FunctionCall(identifier.to_owned(), arguments)
}
Token::CloseSquiglyBracket => {
return (statements, i);
}
Token::Semi => {
i += 1;
continue;
}
_other => {
dbg!(_other);
todo!()
}
});
} }
(statements, i)
let statement = match &tokens[i.to_owned()] {
Token::Keyword(Keyword::Let) => {
*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::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;
let mut declaration_tokens: Vec<Vec<Token>> = 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;
}
*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));
}
Statement::FunctionCall(identifier.to_owned(), arguments)
}
_other => {
todo!()
}
};
current_function.push_statement(statement);
return ParseState::Statement(current_function);
} }
pub fn ast(tokens: Vec<Token>) -> Vec<Function> { pub fn ast(tokens: Vec<Token>) -> Vec<Function> {
let mut parse_state = ParseState::None(Vec::new());
let mut functions: Vec<Function> = Vec::new(); let mut functions: Vec<Function> = Vec::new();
let mut i = 0; let mut i = 0;
while i < tokens.len() { while i < tokens.len() {
parse_state = match &parse_state { match &tokens[i] {
ParseState::None(funcs) => { Token::Keyword(Keyword::Function) => {
functions = funcs.to_owned(); let (statements, added_to_i) = parse_statements(&tokens, i + 4);
// Expect function and shit let statements = vec![Statement::Scope(statements)];
match &tokens[i] { let function_name = match &tokens[i + 1] {
Token::Keyword(keyword) => match keyword { Token::Identifier(identifier) => identifier.to_owned(),
Keyword::Function => {
ParseState::Function(Function::new("".to_string(), Vec::new()))
}
_ => todo!(),
},
_ => todo!(), _ => todo!(),
} };
let n_args = match &tokens[i + 2] {
Token::Number(num) => num.parse::<u64>().unwrap(),
_ => todo!(),
};
i += added_to_i;
functions.push(Function::new(function_name, n_args, statements));
} }
ParseState::Function(func) => match &tokens[i] { _other => {
Token::Identifier(identifier) => { dbg!(&functions);
ParseState::Function(Function::new(identifier.to_owned(), Vec::new())) dbg!(i);
} dbg!(_other);
Token::OpenSquiglyBracket => ParseState::Statement(func.to_owned()), todo!();
_ => todo!(),
},
ParseState::Statement(_function) => {
parse_statement(&mut parse_state, &mut i, &tokens, &functions)
} }
}; };
i += 1; i += 1;
} }
match parse_state { functions
ParseState::None(v) => v,
_ => todo!(),
}
} }

View file

@ -20,6 +20,7 @@ pub enum Keyword {
Function, Function,
Let, Let,
Assign, Assign,
If,
} }
enum TokenFinishedUnfinished { enum TokenFinishedUnfinished {
@ -39,6 +40,7 @@ fn generate_keyword_map() -> HashMap<String, Keyword> {
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.insert("assign".to_string(), K::Assign);
keywords.insert("if".to_string(), K::If);
keywords keywords
} }