begin expression handling
This commit is contained in:
parent
6aa40a3e3e
commit
2851612e39
3 changed files with 128 additions and 23 deletions
12
src/main.rs
12
src/main.rs
|
@ -8,6 +8,7 @@ mod parser;
|
|||
fn log_ast_part(part: &ASTPart, prefix: String) {
|
||||
match part {
|
||||
ASTPart::Number(number) => println!("{}{}: Number: {}", prefix, number.pos, number.value),
|
||||
ASTPart::String(str) => println!("{}{}: String: {}", prefix, str.pos, str.value),
|
||||
ASTPart::Assigment(assigment) => {
|
||||
println!("{}{}: Assigment: {}", prefix, assigment.pos, assigment.variable);
|
||||
println!("{} Value:", prefix);
|
||||
|
@ -21,7 +22,16 @@ fn log_ast_part(part: &ASTPart, prefix: String) {
|
|||
log_ast_part(&operation.right, format!("{} ", prefix));
|
||||
},
|
||||
ASTPart::VarRead(var_read) => println!("{}{}: Variable Read: {}", prefix, var_read.pos, var_read.variable),
|
||||
_ => {}
|
||||
ASTPart::Call(call) => {
|
||||
println!("{}{}: Call:", prefix, call.pos);
|
||||
println!("{} Function:", prefix);
|
||||
log_ast_part(&call.function, format!("{} ", prefix));
|
||||
println!("{} Args:", prefix);
|
||||
for arg in &call.args {
|
||||
log_ast_part(&arg, format!("{} ", prefix));
|
||||
}
|
||||
},
|
||||
ASTPart::NOOP => println!("{}NOOP", prefix)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
137
src/parser.rs
137
src/parser.rs
|
@ -1,32 +1,49 @@
|
|||
use crate::lexer::{Token, TokenType};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ASTPart {
|
||||
String(AstString),
|
||||
Number(AstNumber),
|
||||
Assigment(AstAssigment),
|
||||
Operation(AstOperation),
|
||||
VarRead(AstVarRead),
|
||||
Call(AstCall),
|
||||
NOOP
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct AstString {
|
||||
pub value: String,
|
||||
pub pos: usize
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct AstNumber {
|
||||
pub value: i64,
|
||||
pub pos: usize
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct AstAssigment {
|
||||
pub variable: String,
|
||||
pub value: Box<ASTPart>,
|
||||
pub pos: usize
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct AstOperation {
|
||||
pub operator: String,
|
||||
pub left: Box<ASTPart>,
|
||||
pub right: Box<ASTPart>,
|
||||
pub pos: usize
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct AstVarRead {
|
||||
pub variable: String,
|
||||
pub pos: usize
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AstCall {
|
||||
pub function: Box<ASTPart>,
|
||||
pub args: Vec<ASTPart>,
|
||||
pub pos: usize
|
||||
}
|
||||
|
||||
fn is_end(input: &Token, end: &Vec<Token>) -> bool {
|
||||
for token in end {
|
||||
|
@ -36,41 +53,119 @@ fn is_end(input: &Token, end: &Vec<Token>) -> bool {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
fn next_operation(pos: &mut usize, input: &Vec<Token>, prev: ASTPart, op_ends: &Vec<Token>, parse_ends: &Vec<Token>) -> ASTPart {
|
||||
|
||||
fn read_call(variable: ASTPart, pos: &mut usize, input: &Vec<Token>) -> ASTPart {
|
||||
let mut args: Vec<ASTPart> = vec![];
|
||||
*pos += 1;
|
||||
let start_pos = *pos;
|
||||
while pos < &mut input.len() {
|
||||
let token = &input[*pos];
|
||||
if token.typ == TokenType::SEPARATOR && token.value == "," {
|
||||
*pos += 1;
|
||||
continue;
|
||||
}
|
||||
if token.typ == TokenType::SEPARATOR && token.value == String::from(")") {
|
||||
*pos += 1;
|
||||
break;
|
||||
}
|
||||
let ends: Vec<Token> = vec![
|
||||
Token { typ: TokenType::SEPARATOR, value: String::from(","), pos: 0 },
|
||||
Token { typ: TokenType::SEPARATOR, value: String::from(")"), pos: 0 }
|
||||
];
|
||||
let arg = read_exp(pos, input, &ends, &ends);
|
||||
args.push(arg);
|
||||
}
|
||||
return ASTPart::Call(AstCall { function: Box::new(variable), args: args, pos: start_pos });
|
||||
}
|
||||
|
||||
fn shunt(input: Vec<ASTPart>) -> ASTPart {
|
||||
for part in input {
|
||||
|
||||
}
|
||||
return ASTPart::NOOP;
|
||||
}
|
||||
fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends: &Vec<Token>) -> ASTPart {
|
||||
let mut expressions: Vec<ASTPart> = vec![];
|
||||
while pos < &mut input.len() {
|
||||
let token = &input[*pos];
|
||||
let mut next_token = &Token {
|
||||
typ: TokenType::OPEND,
|
||||
value: String::from("END"),
|
||||
pos: 0
|
||||
};
|
||||
if *pos+1 < input.len() {
|
||||
next_token = &input[*pos+1]
|
||||
}
|
||||
if is_end(token, &parse_ends) {
|
||||
break;
|
||||
}
|
||||
*pos += 1;
|
||||
if is_end(token, ends) {
|
||||
break;
|
||||
}
|
||||
if token.typ == TokenType::STRING {
|
||||
expressions.push(ASTPart::String(AstString { value: token.value.clone(), pos: token.pos }));
|
||||
} else if token.typ == TokenType::NUMBER {
|
||||
expressions.push(ASTPart::Number(AstNumber { value: token.value.parse().unwrap(), pos: token.pos }));
|
||||
} else if token.typ == TokenType::IDENTIFIER {
|
||||
if next_token.typ == TokenType::SEPARATOR && next_token.value == "(" {
|
||||
let var = ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos });
|
||||
expressions.push(read_call(var, pos, input));
|
||||
} else {
|
||||
expressions.push(ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos }));
|
||||
}
|
||||
} else if token.typ == TokenType::OPERATOR {
|
||||
expressions.push(ASTPart::Operation(AstOperation { operator: token.value.clone(), left: Box::new(ASTPart::NOOP), right: Box::new(ASTPart::NOOP), pos: token.pos }));
|
||||
} else {
|
||||
panic!("Unexpected {:?}({}) at {}", token.typ, token.value, token.pos);
|
||||
}
|
||||
}
|
||||
println!("{:?}", expressions);
|
||||
let shunted = shunt(expressions);
|
||||
return ASTPart::NOOP;
|
||||
}
|
||||
|
||||
fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, parse_ends: &Vec<Token>) -> ASTPart {
|
||||
let token = &input[*pos];
|
||||
if is_end(token, &parse_ends) {
|
||||
return prev;
|
||||
return ASTPart::NOOP;
|
||||
}
|
||||
*pos += 1;
|
||||
if is_end(token, &op_ends) {
|
||||
return prev;
|
||||
return ASTPart::NOOP;
|
||||
}
|
||||
if token.typ == TokenType::KEYWORD && token.value == "gethelj" {
|
||||
let variable = &input[*pos];
|
||||
*pos += 1;
|
||||
if variable.typ != TokenType::IDENTIFIER {
|
||||
panic!("Unexpected {:?} at {}", variable.typ, variable.pos)
|
||||
}
|
||||
let eq = &input[*pos];
|
||||
if eq.typ == TokenType::SEPARATOR && eq.value == "=" {
|
||||
if token.typ == TokenType::KEYWORD {
|
||||
if token.value == "gethelj" {
|
||||
let variable = &input[*pos];
|
||||
*pos += 1;
|
||||
if variable.typ != TokenType::IDENTIFIER {
|
||||
panic!("Unexpected {:?} at {}", variable.typ, variable.pos)
|
||||
}
|
||||
let eq = &input[*pos];
|
||||
if eq.typ == TokenType::SEPARATOR && eq.value == "=" {
|
||||
*pos += 1;
|
||||
}
|
||||
let value = read_exp(pos, input, op_ends, parse_ends);
|
||||
return ASTPart::Assigment(AstAssigment { variable: variable.value.clone(), value: Box::new(value), pos: token.pos });
|
||||
} else {
|
||||
panic!("Unexpected {:?}({}) at {}", token.typ, token.value, token.pos);
|
||||
}
|
||||
let value = next_operation(pos, input, ASTPart::NOOP, op_ends, parse_ends);
|
||||
return ASTPart::Assigment(AstAssigment { variable: variable.value.clone(), value: Box::new(value), pos: token.pos });
|
||||
} else if token.typ == TokenType::NUMBER {
|
||||
return next_operation(pos, input, ASTPart::Number(AstNumber { value: token.value.parse().unwrap(), pos: token.pos }), op_ends, parse_ends);
|
||||
} else if token.typ == TokenType::IDENTIFIER {
|
||||
return next_operation(pos, input, ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos }), op_ends, parse_ends);
|
||||
} else {
|
||||
panic!("Unexpected {:?} at {}", token.typ, token.pos);
|
||||
panic!("Unexpected {:?}({}) at {}", token.typ, token.value, token.pos);
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_internal(input: Vec<Token>, op_ends: Vec<Token>, parse_ends: Vec<Token>) -> Vec<ASTPart> {
|
||||
let mut out: Vec<ASTPart> = vec![];
|
||||
let mut pos = 0;
|
||||
while pos < input.len() {
|
||||
let op = next_operation(&mut pos, &input, ASTPart::NOOP, &op_ends, &parse_ends);
|
||||
out.push(op);
|
||||
let op = next_operation(&mut pos, &input, &op_ends, &parse_ends);
|
||||
match op {
|
||||
ASTPart::NOOP => {},
|
||||
_ => {
|
||||
out.push(op);
|
||||
}
|
||||
}
|
||||
if is_end(&input[pos], &parse_ends) {
|
||||
break;
|
||||
}
|
||||
|
|
2
test.as
2
test.as
|
@ -1,2 +1,2 @@
|
|||
gethelj a = 1
|
||||
gethelj b = a
|
||||
gethelj b = a + 2
|
Loading…
Add table
Add a link
Reference in a new issue