Added basic math operations

- cargo fmt
This commit is contained in:
Erin 2021-05-02 00:39:08 +02:00 committed by ondra05
parent 3794fd3c8f
commit 18a1343e11
4 changed files with 63 additions and 14 deletions

View file

@ -37,7 +37,10 @@ fn main() {
println!("{:#?}", ast); println!("{:#?}", ast);
} }
None => { None => {
println!("Hi [AbleScript {}] - AST Printer", env!("CARGO_PKG_VERSION")); println!(
"Hi [AbleScript {}] - AST Printer",
env!("CARGO_PKG_VERSION")
);
repl::repl(); repl::repl();
} }
} }

View file

@ -53,7 +53,11 @@ impl<'a> Parser<'a> {
let start = self.lexer.span().start; let start = self.lexer.span().start;
match token { match token {
Token::Identifier(_) => self.parse_ops(token).map(|x| x.into()), Token::Identifier(_)
| Token::Aboolean(_)
| Token::Boolean(_)
| Token::Integer(_)
| Token::String(_) => self.parse_ops(token),
// Control flow // Control flow
Token::If => self.if_cond(), Token::If => self.if_cond(),
@ -62,12 +66,6 @@ impl<'a> Parser<'a> {
Token::Function => self.function_declaration(), Token::Function => self.function_declaration(),
Token::BfFunction => self.bff_declaration(), Token::BfFunction => self.bff_declaration(),
// Literals
Token::String(x) => Ok(Expr::Literal(Value::Str(x)).into()),
Token::Integer(x) => Ok(Expr::Literal(Value::Int(x)).into()),
Token::Boolean(x) => Ok(Expr::Literal(Value::Bool(x)).into()),
Token::Aboolean(x) => Ok(Expr::Literal(Value::Abool(x)).into()),
// Prefix keywords // Prefix keywords
// Melo - ban variable from next usage (runtime error) // Melo - ban variable from next usage (runtime error)
Token::Melo => { Token::Melo => {

View file

@ -2,14 +2,59 @@ use super::*;
type ExprResult = Result<Expr, Error>; type ExprResult = Result<Expr, Error>;
#[macro_export]
macro_rules! gen_infix {
($($fn_name: ident => $type: tt);*$(;)?) => {$(
fn $fn_name(&mut self, left: Expr) -> ExprResult {
let next = self.lexer.next();
let right = self.ensure_expr(next)?;
Ok(Expr::$type { left: Box::new(left), right: Box::new(right) })
})*
};
}
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
/// Parse operations (got identifier/value) pub(super) fn parse_ops(&mut self, token: Token) -> ParseResult {
pub(super) fn parse_ops(&mut self, token: Token) -> ExprResult { let mut buf: Expr = self.ensure_expr(Some(token))?;
todo!()
loop {
buf = match self.lexer.next() {
Some(Token::Addition) => self.addition(buf)?,
Some(Token::Subtract) => self.subtract(buf)?,
Some(Token::Multiply) => self.multiply(buf)?,
Some(Token::Divide) => self.divide(buf)?,
_ => return Ok(buf.into()),
}
}
}
// Generate infix
gen_infix! {
addition => Add;
subtract => Subtract;
multiply => Multiply;
divide => Divide;
}
/// Ensure that input token is an expression
fn ensure_expr(&mut self, token: Option<Token>) -> ExprResult {
let token = token.ok_or(Error {
kind: ErrorKind::EndOfTokenStream,
position: self.lexer.span(),
})?;
match token {
Token::Boolean(b) => Ok(Expr::Literal(Value::Bool(b))),
Token::Integer(i) => Ok(Expr::Literal(Value::Int(i))),
Token::String(s) => Ok(Expr::Literal(Value::Str(s))),
Token::Aboolean(a) => Ok(Expr::Literal(Value::Abool(a))),
Token::Identifier(i) => Ok(Expr::Identifier(Iden(i))),
t => Err(self.unexpected_token(Some(t))),
}
} }
/// Parse function call /// Parse function call
fn fn_call(&mut self, iden: Iden) -> ExprResult { fn fn_call(&mut self, iden: Iden) -> ExprResult {
return todo!();
self.lexer.next(); self.lexer.next();
let mut args: Vec<Expr> = Vec::new(); let mut args: Vec<Expr> = Vec::new();

View file

@ -2,7 +2,10 @@ use crate::error::{Error, ErrorKind};
use crate::lexer::Token; use crate::lexer::Token;
use crate::variables::Abool; use crate::variables::Abool;
use super::{Parser, item::{Iden, Item}}; use super::{
item::{Iden, Item},
Parser,
};
pub fn abool2num(abool: Abool) -> i32 { pub fn abool2num(abool: Abool) -> i32 {
match abool { match abool {
@ -50,7 +53,7 @@ impl<'a> Parser<'a> {
self.lexer.slice(), self.lexer.slice(),
s s
), ),
None => format!("Unexpected token: `{}`)", self.lexer.slice(),), None => format!("Unexpected token: `{}`", self.lexer.slice(),),
}; };
Error { Error {
kind: ErrorKind::SyntaxError(error_msg), kind: ErrorKind::SyntaxError(error_msg),