WIP -- Expressions should know what their span is
This commit is contained in:
8
rust_compiler/Cargo.lock
generated
8
rust_compiler/Cargo.lock
generated
@@ -1071,18 +1071,18 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.8.30"
|
version = "0.8.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ea879c944afe8a2b25fef16bb4ba234f47c694565e97383b36f3a878219065c"
|
checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy-derive",
|
"zerocopy-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "zerocopy-derive"
|
||||||
version = "0.8.30"
|
version = "0.8.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf955aa904d6040f70dc8e9384444cb1030aed272ba3cb09bbc4ab9e7c1f34f5"
|
checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|||||||
@@ -129,17 +129,62 @@ impl<'a> Parser<'a> {
|
|||||||
/// Parses all the input from the tokenizer buffer and returns the resulting expression
|
/// Parses all the input from the tokenizer buffer and returns the resulting expression
|
||||||
/// Expressions are returned in a root block expression node
|
/// Expressions are returned in a root block expression node
|
||||||
pub fn parse_all(&mut self) -> Result<Option<tree_node::Expression>, Error> {
|
pub fn parse_all(&mut self) -> Result<Option<tree_node::Expression>, Error> {
|
||||||
let mut expressions = Vec::<Expression>::new();
|
// peek at what the first token would be and extract the line and col
|
||||||
|
let (start_line, start_col) = self
|
||||||
|
.tokenizer
|
||||||
|
.peek()?
|
||||||
|
.map(|tok| (tok.line, tok.column))
|
||||||
|
.unwrap_or((1, 1));
|
||||||
|
|
||||||
|
let mut expressions = Vec::<Spanned<Expression>>::new();
|
||||||
|
|
||||||
while let Some(expression) = self.parse()? {
|
while let Some(expression) = self.parse()? {
|
||||||
expressions.push(expression);
|
expressions.push(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(Expression::Block(BlockExpression(expressions))))
|
if expressions.is_empty() {
|
||||||
|
let span = Span {
|
||||||
|
start_line,
|
||||||
|
end_line: start_line,
|
||||||
|
start_col,
|
||||||
|
end_col: start_col,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(Some(Expression::Block(Spanned {
|
||||||
|
node: BlockExpression(expressions),
|
||||||
|
span,
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.tokenizer.seek(SeekFrom::Current(-1))?;
|
||||||
|
|
||||||
|
// Ignore the EOF, we want the previous token to define what the end of the source is.
|
||||||
|
let (end_line, end_col) = self
|
||||||
|
.tokenizer
|
||||||
|
.peek()?
|
||||||
|
.map(|tok| {
|
||||||
|
(
|
||||||
|
tok.line,
|
||||||
|
tok.column + tok.original_string.unwrap_or_default().len(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap_or((start_line, start_col));
|
||||||
|
|
||||||
|
let span = Span {
|
||||||
|
start_line,
|
||||||
|
end_line,
|
||||||
|
start_col,
|
||||||
|
end_col,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Some(Expression::Block(Spanned {
|
||||||
|
node: BlockExpression(expressions),
|
||||||
|
span,
|
||||||
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses the input from the tokenizer buffer and returns the resulting expression
|
/// Parses the input from the tokenizer buffer and returns the resulting expression
|
||||||
pub fn parse(&mut self) -> Result<Option<tree_node::Expression>, Error> {
|
pub fn parse(&mut self) -> Result<Option<Spanned<tree_node::Expression>>, Error> {
|
||||||
self.assign_next()?;
|
self.assign_next()?;
|
||||||
let expr = self.expression()?;
|
let expr = self.expression()?;
|
||||||
|
|
||||||
@@ -163,7 +208,12 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parses an expression, handling binary operations with correct precedence.
|
/// Parses an expression, handling binary operations with correct precedence.
|
||||||
fn expression(&mut self) -> Result<Option<tree_node::Expression>, Error> {
|
fn expression(&mut self) -> Result<Option<Spanned<tree_node::Expression>>, Error> {
|
||||||
|
let (start_line, end_line) = self
|
||||||
|
.current_token
|
||||||
|
.map(|tok| (tok.line, tok.column))
|
||||||
|
.ok_or(Error::UnexpectedEOF)?;
|
||||||
|
|
||||||
// Parse the Left Hand Side (unary/primary expression)
|
// Parse the Left Hand Side (unary/primary expression)
|
||||||
let lhs = self.unary()?;
|
let lhs = self.unary()?;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
use super::sys_call::SysCall;
|
use super::sys_call::SysCall;
|
||||||
use tokenizer::token::Number;
|
use tokenizer::token::Number;
|
||||||
|
|
||||||
@@ -20,12 +22,12 @@ impl std::fmt::Display for Literal {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum BinaryExpression {
|
pub enum BinaryExpression {
|
||||||
Add(Box<Expression>, Box<Expression>),
|
Add(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
Multiply(Box<Expression>, Box<Expression>),
|
Multiply(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
Divide(Box<Expression>, Box<Expression>),
|
Divide(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
Subtract(Box<Expression>, Box<Expression>),
|
Subtract(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
Exponent(Box<Expression>, Box<Expression>),
|
Exponent(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
Modulo(Box<Expression>, Box<Expression>),
|
Modulo(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for BinaryExpression {
|
impl std::fmt::Display for BinaryExpression {
|
||||||
@@ -43,15 +45,15 @@ impl std::fmt::Display for BinaryExpression {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum LogicalExpression {
|
pub enum LogicalExpression {
|
||||||
And(Box<Expression>, Box<Expression>),
|
And(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
Or(Box<Expression>, Box<Expression>),
|
Or(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
Not(Box<Expression>),
|
Not(Box<Spanned<Expression>>),
|
||||||
Equal(Box<Expression>, Box<Expression>),
|
Equal(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
NotEqual(Box<Expression>, Box<Expression>),
|
NotEqual(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
GreaterThan(Box<Expression>, Box<Expression>),
|
GreaterThan(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
GreaterThanOrEqual(Box<Expression>, Box<Expression>),
|
GreaterThanOrEqual(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
LessThan(Box<Expression>, Box<Expression>),
|
LessThan(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
LessThanOrEqual(Box<Expression>, Box<Expression>),
|
LessThanOrEqual(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for LogicalExpression {
|
impl std::fmt::Display for LogicalExpression {
|
||||||
@@ -73,7 +75,7 @@ impl std::fmt::Display for LogicalExpression {
|
|||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct AssignmentExpression {
|
pub struct AssignmentExpression {
|
||||||
pub identifier: String,
|
pub identifier: String,
|
||||||
pub expression: Box<Expression>,
|
pub expression: Box<Spanned<Expression>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for AssignmentExpression {
|
impl std::fmt::Display for AssignmentExpression {
|
||||||
@@ -102,7 +104,7 @@ impl std::fmt::Display for FunctionExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct BlockExpression(pub Vec<Expression>);
|
pub struct BlockExpression(pub Vec<Spanned<Expression>>);
|
||||||
|
|
||||||
impl std::fmt::Display for BlockExpression {
|
impl std::fmt::Display for BlockExpression {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
@@ -170,9 +172,9 @@ impl std::fmt::Display for DeviceDeclarationExpression {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct IfExpression {
|
pub struct IfExpression {
|
||||||
pub condition: Box<Expression>,
|
pub condition: Box<Spanned<Expression>>,
|
||||||
pub body: BlockExpression,
|
pub body: Spanned<BlockExpression>,
|
||||||
pub else_branch: Option<Box<Expression>>,
|
pub else_branch: Option<Box<Spanned<Expression>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for IfExpression {
|
impl std::fmt::Display for IfExpression {
|
||||||
@@ -187,7 +189,7 @@ impl std::fmt::Display for IfExpression {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct LoopExpression {
|
pub struct LoopExpression {
|
||||||
pub body: BlockExpression,
|
pub body: Spanned<BlockExpression>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for LoopExpression {
|
impl std::fmt::Display for LoopExpression {
|
||||||
@@ -198,7 +200,7 @@ impl std::fmt::Display for LoopExpression {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct WhileExpression {
|
pub struct WhileExpression {
|
||||||
pub condition: Box<Expression>,
|
pub condition: Box<Spanned<Expression>>,
|
||||||
pub body: BlockExpression,
|
pub body: BlockExpression,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,27 +210,58 @@ impl std::fmt::Display for WhileExpression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub struct Span {
|
||||||
|
pub start_line: usize,
|
||||||
|
pub end_line: usize,
|
||||||
|
pub start_col: usize,
|
||||||
|
pub end_col: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct Spanned<T> {
|
||||||
|
pub span: Span,
|
||||||
|
pub node: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> std::fmt::Display for Spanned<T>
|
||||||
|
where
|
||||||
|
T: std::fmt::Display,
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Deref for Spanned<T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum Expression {
|
pub enum Expression {
|
||||||
Assignment(AssignmentExpression),
|
Assignment(Spanned<AssignmentExpression>),
|
||||||
Binary(BinaryExpression),
|
Binary(Spanned<BinaryExpression>),
|
||||||
Block(BlockExpression),
|
Block(Spanned<BlockExpression>),
|
||||||
Break,
|
Break(Span),
|
||||||
Continue,
|
Continue(Span),
|
||||||
Declaration(String, Box<Expression>),
|
Declaration(String, Box<Spanned<Expression>>),
|
||||||
DeviceDeclaration(DeviceDeclarationExpression),
|
DeviceDeclaration(Spanned<DeviceDeclarationExpression>),
|
||||||
Function(FunctionExpression),
|
Function(Spanned<FunctionExpression>),
|
||||||
If(IfExpression),
|
If(Spanned<IfExpression>),
|
||||||
Invocation(InvocationExpression),
|
Invocation(Spanned<InvocationExpression>),
|
||||||
Literal(Literal),
|
Literal(Spanned<Literal>),
|
||||||
Logical(LogicalExpression),
|
Logical(Spanned<LogicalExpression>),
|
||||||
Loop(LoopExpression),
|
Loop(Spanned<LoopExpression>),
|
||||||
Negation(Box<Expression>),
|
Negation(Box<Spanned<Expression>>),
|
||||||
Priority(Box<Expression>),
|
Priority(Box<Spanned<Expression>>),
|
||||||
Return(Box<Expression>),
|
Return(Box<Spanned<Expression>>),
|
||||||
Syscall(SysCall),
|
Syscall(Spanned<SysCall>),
|
||||||
Variable(String),
|
Variable(Spanned<String>),
|
||||||
While(WhileExpression),
|
While(Spanned<WhileExpression>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Expression {
|
impl std::fmt::Display for Expression {
|
||||||
@@ -237,8 +270,8 @@ impl std::fmt::Display for Expression {
|
|||||||
Expression::Assignment(e) => write!(f, "{}", e),
|
Expression::Assignment(e) => write!(f, "{}", e),
|
||||||
Expression::Binary(e) => write!(f, "{}", e),
|
Expression::Binary(e) => write!(f, "{}", e),
|
||||||
Expression::Block(e) => write!(f, "{}", e),
|
Expression::Block(e) => write!(f, "{}", e),
|
||||||
Expression::Break => write!(f, "break"),
|
Expression::Break(_) => write!(f, "break"),
|
||||||
Expression::Continue => write!(f, "continue"),
|
Expression::Continue(_) => write!(f, "continue"),
|
||||||
Expression::Declaration(id, e) => write!(f, "(let {} = {})", id, e),
|
Expression::Declaration(id, e) => write!(f, "(let {} = {})", id, e),
|
||||||
Expression::DeviceDeclaration(e) => write!(f, "{}", e),
|
Expression::DeviceDeclaration(e) => write!(f, "{}", e),
|
||||||
Expression::Function(e) => write!(f, "{}", e),
|
Expression::Function(e) => write!(f, "{}", e),
|
||||||
|
|||||||
Reference in New Issue
Block a user