more or less complete regarding basic operators
This commit is contained in:
parent
d2d7bb2034
commit
50de71572f
3 changed files with 63 additions and 53 deletions
|
|
@ -1,8 +1,9 @@
|
||||||
use crate::ast_compiler::Expression::Variable;
|
use crate::ast_compiler::Expression::Variable;
|
||||||
use crate::tokens::TokenType::{
|
use crate::tokens::TokenType::{
|
||||||
Bang, Bool, Char, Colon, Date, Eol, Equal, F32, F64, False, FloatingPoint, Greater,
|
Bang, Bool, Char, Colon, Date, Eol, Equal, F32, F64, False, FloatingPoint, Greater,
|
||||||
GreaterEqual, I32, I64, Identifier, Integer, LeftParen, Less, LessEqual, Let, ListType,
|
GreaterEqual, GreaterGreater, I32, I64, Identifier, Integer, LeftParen, Less, LessEqual,
|
||||||
MapType, Minus, Object, Plus, Print, RightParen, Slash, Star, Text, True, U32, U64,
|
LessLess, Let, ListType, MapType, Minus, Object, Plus, Print, RightParen, Slash, Star, Text,
|
||||||
|
True, U32, U64,
|
||||||
};
|
};
|
||||||
use crate::tokens::{Token, TokenType};
|
use crate::tokens::{Token, TokenType};
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
|
|
@ -105,59 +106,67 @@ impl AstCompiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expression(&mut self) -> anyhow::Result<Expression> {
|
fn expression(&mut self) -> anyhow::Result<Expression> {
|
||||||
self.equality()
|
self.or()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn or(&mut self) -> anyhow::Result<Expression> {
|
||||||
|
let mut expr = self.and()?;
|
||||||
|
self.binary(vec![TokenType::LogicalOr], expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn and(&mut self) -> anyhow::Result<Expression> {
|
||||||
|
let expr = self.bit_and()?;
|
||||||
|
self.binary(vec![TokenType::LogicalAnd], expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bit_and(&mut self) -> anyhow::Result<Expression> {
|
||||||
|
let expr = self.bit_or()?;
|
||||||
|
self.binary(vec![TokenType::BitAnd], expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bit_or(&mut self) -> anyhow::Result<Expression> {
|
||||||
|
let expr = self.bit_xor()?;
|
||||||
|
self.binary(vec![TokenType::BitOr], expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bit_xor(&mut self) -> anyhow::Result<Expression> {
|
||||||
|
let expr = self.equality()?;
|
||||||
|
self.binary(vec![TokenType::BitXor], expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn equality(&mut self) -> anyhow::Result<Expression> {
|
fn equality(&mut self) -> anyhow::Result<Expression> {
|
||||||
let mut expr = self.comparison()?;
|
let expr = self.comparison()?;
|
||||||
while self.match_token(vec![TokenType::BangEqual, TokenType::EqualEqual]) {
|
self.binary(vec![TokenType::EqualEqual, TokenType::BangEqual], expr)
|
||||||
let operator = self.previous().clone();
|
|
||||||
let right = self.comparison()?;
|
|
||||||
expr = Expression::Binary {
|
|
||||||
line: operator.line,
|
|
||||||
left: Box::new(expr),
|
|
||||||
operator,
|
|
||||||
right: Box::new(right),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Ok(expr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn comparison(&mut self) -> anyhow::Result<Expression> {
|
fn comparison(&mut self) -> anyhow::Result<Expression> {
|
||||||
let mut expr = self.term()?;
|
let expr = self.bitshift()?;
|
||||||
while self.match_token(vec![Greater, GreaterEqual, Less, LessEqual]) {
|
self.binary(vec![Greater, GreaterEqual, Less, LessEqual], expr)
|
||||||
let operator = self.previous().clone();
|
|
||||||
let right = self.term()?;
|
|
||||||
expr = Expression::Binary {
|
|
||||||
line: operator.line,
|
|
||||||
left: Box::new(expr),
|
|
||||||
operator,
|
|
||||||
right: Box::new(right),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
Ok(expr)
|
|
||||||
|
fn bitshift(&mut self) -> anyhow::Result<Expression> {
|
||||||
|
let mut expr = self.term()?;
|
||||||
|
self.binary(vec![GreaterGreater, LessLess], expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn term(&mut self) -> anyhow::Result<Expression> {
|
fn term(&mut self) -> anyhow::Result<Expression> {
|
||||||
let mut expr = self.factor()?;
|
let expr = self.factor()?;
|
||||||
while self.match_token(vec![Minus, Plus]) {
|
self.binary(vec![Minus, Plus], expr)
|
||||||
let operator = self.previous().clone();
|
|
||||||
let right = self.factor()?;
|
|
||||||
expr = Expression::Binary {
|
|
||||||
line: operator.line,
|
|
||||||
left: Box::new(expr),
|
|
||||||
operator,
|
|
||||||
right: Box::new(right),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Ok(expr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn factor(&mut self) -> anyhow::Result<Expression> {
|
fn factor(&mut self) -> anyhow::Result<Expression> {
|
||||||
let mut expr = self.unary()?;
|
let expr = self.unary()?;
|
||||||
while self.match_token(vec![Slash, Star]) {
|
self.binary(vec![Slash, Star], expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn binary(
|
||||||
|
&mut self,
|
||||||
|
types: Vec<TokenType>,
|
||||||
|
mut expr: Expression,
|
||||||
|
) -> anyhow::Result<Expression> {
|
||||||
|
while self.match_token(types.clone()) {
|
||||||
let operator = self.previous().clone();
|
let operator = self.previous().clone();
|
||||||
let right = self.unary()?;
|
let right = self.comparison()?;
|
||||||
expr = Expression::Binary {
|
expr = Expression::Binary {
|
||||||
line: operator.line,
|
line: operator.line,
|
||||||
left: Box::new(expr),
|
left: Box::new(expr),
|
||||||
|
|
@ -316,7 +325,7 @@ fn calculate_type(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match inferred_type {
|
match inferred_type {
|
||||||
Integer => I64,
|
Integer | I64 => I64,
|
||||||
FloatingPoint => F64,
|
FloatingPoint => F64,
|
||||||
Text => Text,
|
Text => Text,
|
||||||
Bool => Bool,
|
Bool => Bool,
|
||||||
|
|
@ -401,14 +410,16 @@ impl Expression {
|
||||||
pub fn infer_type(&self) -> TokenType {
|
pub fn infer_type(&self) -> TokenType {
|
||||||
match self {
|
match self {
|
||||||
Self::Binary {
|
Self::Binary {
|
||||||
line,
|
|
||||||
left,
|
left,
|
||||||
operator,
|
operator,
|
||||||
right,
|
right,
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
let left_type = left.infer_type();
|
let left_type = left.infer_type();
|
||||||
let right_type = right.infer_type();
|
let right_type = right.infer_type();
|
||||||
if left_type == right_type {
|
if vec![Greater, Less, GreaterEqual, LessEqual].contains(&operator.token_type) {
|
||||||
|
Bool
|
||||||
|
} else if left_type == right_type {
|
||||||
// map to determined numeric type if yet undetermined (32 or 64 bits)
|
// map to determined numeric type if yet undetermined (32 or 64 bits)
|
||||||
match left_type {
|
match left_type {
|
||||||
FloatingPoint => F64,
|
FloatingPoint => F64,
|
||||||
|
|
@ -426,6 +437,7 @@ impl Expression {
|
||||||
(FloatingPoint, _) => F64,
|
(FloatingPoint, _) => F64,
|
||||||
(Integer, FloatingPoint) => F64,
|
(Integer, FloatingPoint) => F64,
|
||||||
(Integer, _) => I64,
|
(Integer, _) => I64,
|
||||||
|
(I64, Integer) => I64,
|
||||||
(F64, _) => F64,
|
(F64, _) => F64,
|
||||||
(U64, U32) => U64,
|
(U64, U32) => U64,
|
||||||
(I64, I32) => I64,
|
(I64, I32) => I64,
|
||||||
|
|
@ -442,6 +454,7 @@ impl Expression {
|
||||||
match (left_type, right_type) {
|
match (left_type, right_type) {
|
||||||
(FloatingPoint, _) => F64,
|
(FloatingPoint, _) => F64,
|
||||||
(Integer, FloatingPoint) => F64,
|
(Integer, FloatingPoint) => F64,
|
||||||
|
(Integer, I64) => I64,
|
||||||
(I64, FloatingPoint) => F64,
|
(I64, FloatingPoint) => F64,
|
||||||
(F64, _) => F64,
|
(F64, _) => F64,
|
||||||
(U64, U32) => U64,
|
(U64, U32) => U64,
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,7 @@ use crate::ast_compiler::{Expression, Statement};
|
||||||
use crate::chunk::Chunk;
|
use crate::chunk::Chunk;
|
||||||
use crate::tokens::TokenType;
|
use crate::tokens::TokenType;
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use crate::vm::{
|
use crate::vm::{OP_ADD, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CONSTANT, OP_DEF_BOOL, OP_DEF_CHAR, OP_DEF_DATE, OP_DEF_F32, OP_DEF_F64, OP_DEF_I32, OP_DEF_I64, OP_DEF_LIST, OP_DEF_MAP, OP_DEF_STRING, OP_DEF_STRUCT, OP_DEFINE, OP_DIVIDE, OP_EQUAL, OP_GET, OP_GREATER, OP_GREATER_EQUAL, OP_LESS, OP_LESS_EQUAL, OP_MULTIPLY, OP_NEGATE, OP_NOT, OP_PRINT, OP_RETURN, OP_SHL, OP_SHR, OP_SUBTRACT, OP_AND, OP_OR};
|
||||||
OP_ADD, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CONSTANT, OP_DEF_BOOL, OP_DEF_CHAR, OP_DEF_DATE,
|
|
||||||
OP_DEF_F32, OP_DEF_F64, OP_DEF_I32, OP_DEF_I64, OP_DEF_LIST, OP_DEF_MAP, OP_DEF_STRING,
|
|
||||||
OP_DEF_STRUCT, OP_DEFINE, OP_DIVIDE, OP_EQUAL, OP_GET, OP_GREATER, OP_GREATER_EQUAL, OP_LESS,
|
|
||||||
OP_LESS_EQUAL, OP_MULTIPLY, OP_NEGATE, OP_NOT, OP_PRINT, OP_RETURN, OP_SHL, OP_SHR,
|
|
||||||
OP_SUBTRACT,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn compile(ast: Vec<Statement>) -> anyhow::Result<Chunk> {
|
pub fn compile(ast: Vec<Statement>) -> anyhow::Result<Chunk> {
|
||||||
let compiler = Compiler::new();
|
let compiler = Compiler::new();
|
||||||
|
|
@ -109,6 +103,8 @@ impl Compiler {
|
||||||
TokenType::GreaterEqual => self.emit_byte(OP_GREATER_EQUAL),
|
TokenType::GreaterEqual => self.emit_byte(OP_GREATER_EQUAL),
|
||||||
TokenType::Less => self.emit_byte(OP_LESS),
|
TokenType::Less => self.emit_byte(OP_LESS),
|
||||||
TokenType::LessEqual => self.emit_byte(OP_LESS_EQUAL),
|
TokenType::LessEqual => self.emit_byte(OP_LESS_EQUAL),
|
||||||
|
TokenType::LogicalAnd => self.emit_byte(OP_AND),
|
||||||
|
TokenType::LogicalOr => self.emit_byte(OP_OR),
|
||||||
_ => unimplemented!("binary other than plus, minus, star, slash"),
|
_ => unimplemented!("binary other than plus, minus, star, slash"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,9 @@ use crudlang::vm::{interpret, Vm};
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
let tokens = scan(r#"let a = 42
|
let tokens = scan(r#"let a = 1>2
|
||||||
print a"#);
|
print a"#);
|
||||||
|
// println!("{:?}", tokens);
|
||||||
match ast_compiler::compile(tokens) {
|
match ast_compiler::compile(tokens) {
|
||||||
Ok(statements) => {
|
Ok(statements) => {
|
||||||
println!("{:?}", statements);
|
println!("{:?}", statements);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue