Skip to content

Commit

Permalink
fix(parser): change cast syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
MilkeeyCat committed Sep 7, 2024
1 parent dbacbbe commit 69f191d
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 146 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion programs/structs.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
1 change: 1 addition & 0 deletions src/lexer/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
23 changes: 2 additions & 21 deletions src/lexer/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub enum Token {
For,
Else,
Return,
As,

U8,
U16,
Expand All @@ -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::*;
Expand Down Expand Up @@ -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"),
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
196 changes: 75 additions & 121 deletions src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
]),
})
}
Expand Down Expand Up @@ -604,6 +605,15 @@ impl Parser {
}))
}

fn cast_expr(&mut self, expr: Expr) -> Result<Expr, ParserError> {
self.expect(&Token::As)?;

Ok(Expr::Cast(ExprCast {
expr: Box::new(expr),
type_: self.parse_type()?,
}))
}

fn unary_expr(&mut self) -> Result<Expr, ParserError> {
let op = UnOp::try_from(&self.next_token()?).map_err(|e| ParserError::Operator(e))?;
let expr = self.expr(Precedence::Prefix)?;
Expand All @@ -629,13 +639,6 @@ impl Parser {
fn grouped_expr(&mut self) -> Result<Expr, ParserError> {
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)?;

Expand Down Expand Up @@ -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,
};

Expand All @@ -703,133 +704,103 @@ 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)))),
})),
})),
],
),
(
"
{
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)))),
})),
}))],
),
(
"
Expand All @@ -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)))),
})),
})),
],
),
];
Expand Down
3 changes: 2 additions & 1 deletion src/parser/precedence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ pub enum Precedence {
Equality,
Sum,
Product,
Prefix,
Cast,
Prefix,
Access,
Call,
}
Expand All @@ -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,
Expand Down

0 comments on commit 69f191d

Please sign in to comment.