diff --git a/README.md b/README.md index 3ba9192..15beb1f 100644 --- a/README.md +++ b/README.md @@ -69,5 +69,5 @@ type SmolInt = u8; ### Casting -It's good ol' `(type)epxr`. Also we don't cast integer variables for ya. +Use keyword `as` for casting expressions. Also we don't cast integer variables for ya. No implicit conversions! Only integer literals can be promoted to bigger type diff --git a/programs/structs.mk b/programs/structs.mk index ca34e73..b511fe4 100644 --- a/programs/structs.mk +++ b/programs/structs.mk @@ -24,5 +24,5 @@ fn main() -> u8 { }; baz.value = 42; - return (u8)baz.value + baz.bar.value + baz.bar.foo.value; + return baz.value as u8 + baz.bar.value + baz.bar.foo.value; } diff --git a/src/lexer/lexer.rs b/src/lexer/lexer.rs index e2bbfc2..11f2865 100644 --- a/src/lexer/lexer.rs +++ b/src/lexer/lexer.rs @@ -130,6 +130,7 @@ impl Lexer { "for" => Token::For, "else" => Token::Else, "return" => Token::Return, + "as" => Token::As, "u8" => Token::U8, "u16" => Token::U16, "u32" => Token::U32, diff --git a/src/lexer/token.rs b/src/lexer/token.rs index 20552c2..652a986 100644 --- a/src/lexer/token.rs +++ b/src/lexer/token.rs @@ -48,6 +48,7 @@ pub enum Token { For, Else, Return, + As, U8, U16, @@ -63,27 +64,6 @@ pub enum Token { Void, } -impl Token { - pub fn is_type(&self, scope: &Scope) -> bool { - match &self { - Token::U8 - | Token::U16 - | Token::U32 - | Token::U64 - | Token::I8 - | Token::I16 - | Token::I32 - | Token::I64 - | Token::Usize - | Token::Isize - | Token::Bool - | Token::Void => true, - Token::Ident(ident) => scope.find_type(ident).is_some(), - _ => false, - } - } -} - impl Display for Token { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { use Token::*; @@ -131,6 +111,7 @@ impl Display for Token { For => write!(f, "for"), Else => write!(f, "else"), Return => write!(f, "return"), + As => write!(f, "as"), U8 => write!(f, "u8"), U16 => write!(f, "u16"), U32 => write!(f, "u32"), diff --git a/src/lib.rs b/src/lib.rs index 5c09e68..5b56675 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,9 +3,9 @@ pub mod codegen; pub mod compile; pub mod lexer; pub mod parser; +pub mod passes; pub mod register; pub mod scope; pub mod symbol_table; pub mod type_table; pub mod types; -pub mod passes; diff --git a/src/parser/parser.rs b/src/parser/parser.rs index b8cc55e..8cef21b 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -67,6 +67,7 @@ impl Parser { (Token::LParen, Self::bin_expr), (Token::Period, Self::struct_access), (Token::LBracket, Self::array_access), + (Token::As, Self::cast_expr), ]), }) } @@ -604,6 +605,15 @@ impl Parser { })) } + fn cast_expr(&mut self, expr: Expr) -> Result { + self.expect(&Token::As)?; + + Ok(Expr::Cast(ExprCast { + expr: Box::new(expr), + type_: self.parse_type()?, + })) + } + fn unary_expr(&mut self) -> Result { let op = UnOp::try_from(&self.next_token()?).map_err(|e| ParserError::Operator(e))?; let expr = self.expr(Precedence::Prefix)?; @@ -629,13 +639,6 @@ impl Parser { fn grouped_expr(&mut self) -> Result { self.expect(&Token::LParen)?; - //if self.cur_token.is_type(&self.scope) { - // let type_ = self.parse_type()?; - // self.expect(&Token::RParen)?; - // let expr = self.expr(Precedence::Cast)?; - - // Ok(Expr::Cast(ExprCast::new(type_, Box::new(expr)))) - //} else { let expr = self.expr(Precedence::default())?; self.expect(&Token::RParen)?; @@ -692,8 +695,6 @@ mod test { BinOp, Expr, ExprBinary, ExprCast, ExprIdent, ExprLit, ExprUnary, ParserError, Stmt, StmtVarDecl, UIntLitRepr, UnOp, }, - scope::Scope, - symbol_table::{Symbol, SymbolLocal}, types::Type, }; @@ -703,64 +704,54 @@ mod test { ( " { - 1 * 2 + 3 / (4 + (u8)1); + 1 * 2 + 3 / (4 + 1 as u8); } ", - vec![Stmt::Expr(Expr::Binary(ExprBinary::new( - BinOp::Add, - Expr::Binary(ExprBinary::new( - BinOp::Mul, - Expr::Lit(ExprLit::UInt(UIntLitRepr::new(1))), - Expr::Lit(ExprLit::UInt(UIntLitRepr::new(2))), - &Scope::new(), - )?), - Expr::Binary(ExprBinary::new( - BinOp::Div, - Expr::Lit(ExprLit::UInt(UIntLitRepr::new(3))), - Expr::Binary(ExprBinary::new( - BinOp::Add, - Expr::Lit(ExprLit::UInt(UIntLitRepr::new(4))), - Expr::Cast(ExprCast::new( + vec![Stmt::Expr(Expr::Binary(ExprBinary { + op: BinOp::Add, + left: Box::new(Expr::Binary(ExprBinary { + op: BinOp::Mul, + left: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(1)))), + right: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(2)))), + })), + right: Box::new(Expr::Binary(ExprBinary { + op: BinOp::Div, + left: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(3)))), + right: Box::new(Expr::Binary(ExprBinary { + op: BinOp::Add, + left: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(4)))), + right: Box::new(Expr::Cast(ExprCast::new( Type::U8, Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(1)))), - )), - &Scope::new(), - )?), - &Scope::new(), - )?), - &Scope::new(), - )?))], + ))), + })), + })), + }))], ), ( " { let foo: u8; - foo = (u8)-1 + 5; + foo = -1 as u8 + 5; } ", vec![ Stmt::VarDecl(StmtVarDecl::new(Type::U8, "foo".to_owned(), None)), - Stmt::Expr(Expr::Binary(ExprBinary::new( - BinOp::Assign, - Expr::Ident(ExprIdent("foo".to_owned())), - Expr::Binary(ExprBinary::new( - BinOp::Add, - Expr::Cast(ExprCast::new( + Stmt::Expr(Expr::Binary(ExprBinary { + op: BinOp::Assign, + left: Box::new(Expr::Ident(ExprIdent("foo".to_owned()))), + right: Box::new(Expr::Binary(ExprBinary { + op: BinOp::Add, + left: Box::new(Expr::Cast(ExprCast::new( Type::U8, Box::new(Expr::Unary(ExprUnary::new( UnOp::Negative, Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(1)))), ))), - )), - Expr::Lit(ExprLit::UInt(UIntLitRepr::new(5))), - &Scope::new(), - )?), - &Scope::from(vec![Symbol::Local(SymbolLocal { - name: "foo".to_string(), - type_: Type::U8, - offset: Default::default(), - })]), - )?)), + ))), + right: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(5)))), + })), + })), ], ), ( @@ -768,68 +759,48 @@ mod test { { let foo: u8; let bar: i8; - bar = (i8)foo + 5 / 10; + bar = foo as i8 + 5 / 10; } ", vec![ Stmt::VarDecl(StmtVarDecl::new(Type::U8, "foo".to_owned(), None)), Stmt::VarDecl(StmtVarDecl::new(Type::I8, "bar".to_owned(), None)), - Stmt::Expr(Expr::Binary(ExprBinary::new( - BinOp::Assign, - Expr::Ident(ExprIdent("bar".to_owned())), - Expr::Binary(ExprBinary::new( - BinOp::Add, - Expr::Cast(ExprCast::new( + Stmt::Expr(Expr::Binary(ExprBinary { + op: BinOp::Assign, + left: Box::new(Expr::Ident(ExprIdent("bar".to_owned()))), + right: Box::new(Expr::Binary(ExprBinary { + op: BinOp::Add, + left: Box::new(Expr::Cast(ExprCast::new( Type::I8, Box::new(Expr::Ident(ExprIdent("foo".to_owned()))), - )), - Expr::Binary(ExprBinary::new( - BinOp::Div, - Expr::Lit(ExprLit::UInt(UIntLitRepr::new(5))), - Expr::Lit(ExprLit::UInt(UIntLitRepr::new(10))), - &Scope::new(), - )?), - &Scope::from(vec![Symbol::Local(SymbolLocal { - name: "foo".to_string(), - type_: Type::U8, - offset: Default::default(), - })]), - )?), - &Scope::from(vec![ - Symbol::Local(SymbolLocal { - name: "bar".to_string(), - type_: Type::I8, - offset: Default::default(), - }), - Symbol::Local(SymbolLocal { - name: "foo".to_string(), - type_: Type::U8, - offset: Default::default(), - }), - ]), - )?)), + ))), + right: Box::new(Expr::Binary(ExprBinary { + op: BinOp::Div, + left: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(5)))), + right: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(10)))), + })), + })), + })), ], ), ( " { - (i8)1 + 2 / 3; + 1 as i8 + 2 / 3; } ", - vec![Stmt::Expr(Expr::Binary(ExprBinary::new( - BinOp::Add, - Expr::Cast(ExprCast::new( + vec![Stmt::Expr(Expr::Binary(ExprBinary { + op: BinOp::Add, + left: Box::new(Expr::Cast(ExprCast::new( Type::I8, Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(1)))), - )), - Expr::Binary(ExprBinary::new( - BinOp::Div, - Expr::Lit(ExprLit::UInt(UIntLitRepr::new(2))), - Expr::Lit(ExprLit::UInt(UIntLitRepr::new(3))), - &Scope::new(), - )?), - &Scope::new(), - )?))], + ))), + right: Box::new(Expr::Binary(ExprBinary { + op: BinOp::Div, + left: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(2)))), + right: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(3)))), + })), + }))], ), ( " @@ -843,32 +814,15 @@ mod test { vec![ Stmt::VarDecl(StmtVarDecl::new(Type::U8, "a".to_owned(), None)), Stmt::VarDecl(StmtVarDecl::new(Type::U8, "b".to_owned(), None)), - Stmt::Expr(Expr::Binary(ExprBinary::new( - BinOp::Assign, - Expr::Ident(ExprIdent("a".to_owned())), - Expr::Binary(ExprBinary::new( - BinOp::Assign, - Expr::Ident(ExprIdent("b".to_owned())), - Expr::Lit(ExprLit::UInt(UIntLitRepr::new(69))), - &Scope::from(vec![Symbol::Local(SymbolLocal { - name: "b".to_string(), - type_: Type::U8, - offset: Default::default(), - })]), - )?), - &Scope::from(vec![ - Symbol::Local(SymbolLocal { - name: "a".to_string(), - type_: Type::U8, - offset: Default::default(), - }), - Symbol::Local(SymbolLocal { - name: "b".to_string(), - type_: Type::U8, - offset: Default::default(), - }), - ]), - )?)), + Stmt::Expr(Expr::Binary(ExprBinary { + op: BinOp::Assign, + left: Box::new(Expr::Ident(ExprIdent("a".to_owned()))), + right: Box::new(Expr::Binary(ExprBinary { + op: BinOp::Assign, + left: Box::new(Expr::Ident(ExprIdent("b".to_owned()))), + right: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(69)))), + })), + })), ], ), ]; diff --git a/src/parser/precedence.rs b/src/parser/precedence.rs index 084d4e9..7113d95 100644 --- a/src/parser/precedence.rs +++ b/src/parser/precedence.rs @@ -11,8 +11,8 @@ pub enum Precedence { Equality, Sum, Product, - Prefix, Cast, + Prefix, Access, Call, } @@ -28,6 +28,7 @@ impl From<&Token> for Precedence { Token::Equal | Token::NotEqual => Self::Equality, Token::Assign => Self::Assign, Token::LParen => Self::Call, + Token::As => Self::Cast, Token::Period | Token::LBracket => Self::Access, Token::And => Self::LogicalAnd, Token::Or => Self::LogicalOr,