Skip to content

Commit

Permalink
Add BitwiseAnd and BitwiseOr operator and Add support for Reference a…
Browse files Browse the repository at this point in the history
…nd Dereference in lexer and parser (Not include the typer)
Jaredanwolfgang committed Dec 28, 2024
1 parent 95f7ece commit b474301
Showing 7 changed files with 95 additions and 8 deletions.
5 changes: 5 additions & 0 deletions src/ast/src/fmt.rs
Original file line number Diff line number Diff line change
@@ -114,6 +114,7 @@ impl fmt::Display for Value {
Value::Char(c) => write!(f, "{}: char", c),
Value::Bool(b) => write!(f, "{}: bool", b),
Value::Struct(s) => write!(f, "Struct({})", s),
Value::Pointer(p) => write!(f, "Pointer({})", p),
Value::Null => write!(f, "null")
}
}
@@ -131,6 +132,8 @@ impl fmt::Display for BinaryOperator {
BinaryOperator::And => write!(f, "&&"),
BinaryOperator::Or => write!(f, "||"),
BinaryOperator::Error => write!(f, "[BinaryOperatorError]"),
BinaryOperator::BitwiseAnd => write!(f, "&"),
BinaryOperator::BitwiseOr => write!(f, "|"),
}
}
}
@@ -143,6 +146,8 @@ impl fmt::Display for UnaryOperator {
UnaryOperator::Inc => write!(f, "++"),
UnaryOperator::Dec => write!(f, "--"),
UnaryOperator::Error => write!(f, "[UnaryOperatorError]"),
UnaryOperator::Ref => write!(f, "&"),
UnaryOperator::Deref => write!(f, "*"),
}
}
}
7 changes: 6 additions & 1 deletion src/ast/src/tree.rs
Original file line number Diff line number Diff line change
@@ -86,6 +86,7 @@ pub enum Value {
Char(char),
Bool(bool),
Struct(String),
Pointer(Box<Value>),
Null
}

@@ -99,6 +100,8 @@ pub enum BinaryOperator {
Mod, // %
And, // &&
Or, // ||
BitwiseAnd, // &
BitwiseOr, // |
Error
}

@@ -107,7 +110,9 @@ pub enum UnaryOperator {
Not, // !
Inc, // ++
Dec, // --
Error
Ref, //&
Deref, //*
Error,
}

#[derive(Clone, Debug, PartialEq)]
6 changes: 4 additions & 2 deletions src/lexer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -197,7 +197,7 @@ mod test {
fn operators() {
assert_lex(
"
++ -- ! * / % ^ + - < <= > >= == != && || =
++ -- ! * / % ^ + - < <= > >= == != && || = & |
",
&[
(OpIncrement, "++"),
@@ -217,7 +217,9 @@ mod test {
(OpNotEqual, "!="),
(OpAnd, "&&"),
(OpOr, "||"),
(OpAssign, "=")
(OpAssign, "="),
(OpBitwiseAnd, "&"),
(OpBitwiseOr, "|"),
][..]
);
}
8 changes: 6 additions & 2 deletions src/lexer/src/tokens.rs
Original file line number Diff line number Diff line change
@@ -90,16 +90,20 @@ pub enum Token {
OpMod,
#[token("^")]
OpPow,
#[token("&&")]
#[token("&&", priority = 5)]
OpAnd,
#[token("||")]
#[token("||", priority = 5)]
OpOr,
#[token("!")]
OpNot,
#[token("++")]
OpIncrement,
#[token("--")]
OpDecrement,
#[token("&", priority = 3)]
OpBitwiseAnd,
#[token("|", priority = 3)]
OpBitwiseOr,

// Punctuation
#[token(".", priority = 5)]
72 changes: 71 additions & 1 deletion src/parser/src/grammar.lalrpop
Original file line number Diff line number Diff line change
@@ -1211,12 +1211,55 @@ pub CompExpr: Box<tree::CompExpr> = {
lhs, tree::BinaryOperator::Sub, rhs
))
},

#[precedence(level="5")] #[assoc(side="left")]
<lhs:CompExpr> "&" <l:@L> <rhs:!> <r:@R> => {
let error = ErrorRecovery {
error: ParseError::User {
error: LexicalError::MissingLexeme(Span {
source: source.to_string(),
start: l,
end: l + 1
}, "Exp after &".to_string())
},
dropped_tokens: Vec::new(),
};
errors.push(error);
Box::new(tree::CompExpr::Error)
},
<l:@L> <lhs:CompExpr> "&" <rhs:CompExpr> <r:@R> => {
Box::new(tree::CompExpr::BinaryOperation (
lhs, tree::BinaryOperator::BitwiseAnd, rhs
))
},
<lhs:CompExpr> "|" <l:@L> <rhs:!> <r:@R> => {
let error = ErrorRecovery {
error: ParseError::User {
error: LexicalError::MissingLexeme(Span {
source: source.to_string(),
start: l,
end: l + 1
}, "Exp after |".to_string())
},
dropped_tokens: Vec::new(),
};
errors.push(error);
Box::new(tree::CompExpr::Error)
},
<l:@L> <lhs:CompExpr> "|" <rhs:CompExpr> <r:@R> => {
Box::new(tree::CompExpr::BinaryOperation (
lhs, tree::BinaryOperator::BitwiseOr, rhs
))
},
}

Specifier: tree::Value = {
<t:"typeint"> => tree::Value::Integer(0),
<t:"typeint"> "*" => tree::Value::Pointer(Box::new(tree::Value::Integer(0))),
<t:"typefloat"> => tree::Value::Float(0.0),
<t:"typefloat"> "*" => tree::Value::Pointer(Box::new(tree::Value::Float(0.0))),
<t:"typechar"> => tree::Value::Char(' '),
<t:"typechar"> "*" => tree::Value::Pointer(Box::new(tree::Value::Char(' '))),
<t:"typestr"> => tree::Value::String(String::new()),
<t:"void"> => tree::Value::Null,
"struct" <str: Identifier> => tree::Value::Struct(str)
@@ -1262,7 +1305,32 @@ Term: Box<tree::CompExpr> = {
<s:StructRef> => {
Box::new(tree::CompExpr::Variable(tree::Variable::StructReference(Box::new(s))))
},

"&" <ident:Identifier> => {
Box::new(tree::CompExpr::UnaryOperation(
tree::UnaryOperator::Ref,
Box::new(
tree::CompExpr::Variable(
tree::Variable::VarReference(
Box::new(ident),
Box::new(Vec::new())
)
)
)
))
},
"*" <ident:Identifier> => {
Box::new(tree::CompExpr::UnaryOperation(
tree::UnaryOperator::Deref,
Box::new(
tree::CompExpr::Variable(
tree::Variable::VarReference(
Box::new(ident),
Box::new(Vec::new())
)
),
)
))
},
// error recovery
<ident: Identifier> "(" ArgList? <l:@L> <missing:!> <r:@R> => {
let error = ErrorRecovery {
@@ -1362,6 +1430,8 @@ extern {
"=" => Token::OpAssign,
"++" => Token::OpIncrement,
"--" => Token::OpDecrement,
"&" => Token::OpBitwiseAnd,
"|" => Token::OpBitwiseOr,
"if" => Token::KeywordIf,
"else" => Token::KeywordElse,
"while" => Token::KeywordWhile,
2 changes: 2 additions & 0 deletions src/parser/src/lib.rs
Original file line number Diff line number Diff line change
@@ -221,6 +221,8 @@ mod tests {
"Struct: Struct Definition: obj with [Variable Declaration: a = [0: u32] with dimensions [], Variable Declaration: b = [ : char] with dimensions []]");
assert_parse(Parser::StmtParser, "#include \"../hi.h\"", "Include: ../hi.h");
assert_parse(Parser::StmtParser, "int a[1];", "GlobalVariable: [Variable Declaration: a = [0: u32] with dimensions [1: u32]]");
assert_parse(Parser::ProgramParser, "int main(){ int a; int *b = &a; int c = *b;}",
"Functions: Function: main:[Body: [Variable Declaration: a = [0: u32] with dimensions [], Variable Declaration: b = [Pointer(0: u32)] with dimensions []; Variable Assignment: b = (& a), Variable Declaration: c = [0: u32] with dimensions []; Variable Assignment: c = (* b)]]");
}

#[test]
3 changes: 1 addition & 2 deletions test/phase1/basic/test_1_r07.out
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
Error type A at Line 7: Unknown lexeme |
Error type A at Line 8: Unknown lexeme &
Functions: Function: test_1_r07:[Body: [Variable Declaration: a = [0: u32] with dimensions []; Variable Declaration: b = [0: u32] with dimensions []; Variable Declaration: c = [0: u32] with dimensions [], Variable Assignment: a = 1: u32, Variable Assignment: b = (a + 2: u32), Variable Assignment: c = (b - 3: u32), Variable Assignment: a = (c | 4: u32), Variable Assignment: b = (a & 5: u32)]]

0 comments on commit b474301

Please sign in to comment.