Files
RustAst/src/ast/parser.rs
T
Brummel 007446a167 Update various types to use their own definitions
This commit refactors several modules to use the defined types from
`ast::types` and `ast::nodes` directly, rather than using fully
qualified paths. This improves code readability and reduces redundancy.

Specifically, the following changes were made:

- In `analyzer.rs`, `crate::ast::types::Identity` and
  `crate::ast::types::Purity` are now used directly.
- In `binder.rs`, `crate::ast::types::NodeIdentity`,
  `crate::ast::types::SourceLocation`,
  `crate::ast::types::RecordLayout`, and `crate::ast::types::Value` are
  now used directly.
- In `macros.rs`, types like `Address`, `VirtualId`, `NodeIdentity`,
  `SourceLocation`, `StaticType`, and `Purity` are now used directly.
- In `optimizer/engine.rs`, `Address<VirtualId>` is now used directly.
- In `type_checker.rs`, `BoundPhase`, `Signature`, `Keyword`, and
  `RecordLayout` are now used directly.
- In `environment.rs`, `CompilerScope`, `LocalInfo`, `CapturePass`,
  `AnalyzedPhase`, `NativeFunction`, and `Closure` are now used
  directly.
- In `nodes.rs`, `RecordLayout`, `Keyword`, `Purity`, and `StaticType`
  are now used directly.
- In `parser.rs`, `SourceLocation` and `NodeIdentity` are now used
  directly.
- In `rtl/math.rs`, `NativeFunction`, `Purity`, `Signature`,
  `StaticType`, `Value`, `RefCell`, and `Rc` are now used directly.
- In `rtl/streams.rs`, `ScalarValue`, `SeriesMember`, `Object`,
  `PipeFn`, `Value`, `VM`, `RingBuffer`, `RecordSeries`, `SeriesView`,
  `build_map_stream`, and `build_pipeline_node` are now used directly.
- In `rtl/type_registry.rs`, `RecordLayout`, `Keyword`, `Purity`,
  `Signature`, `StaticType`, and `Value` are now used directly.
- In `vm.rs`, `RecordSeries`, `SeriesView`, `build_map_stream`,
  `build_pipeline_node`, `StreamNode`, `Object`, and `PipeFn` are now
  used directly.
- In `utils/tester.rs`, `TypedNode` is now used directly.
2026-03-22 18:30:56 +01:00

545 lines
17 KiB
Rust

use crate::ast::diagnostics::Diagnostics;
use crate::ast::lexer::{Lexer, Token, TokenKind};
use crate::ast::nodes::{Symbol, SyntaxKind, SyntaxNode};
use crate::ast::types::{Identity, Keyword, NodeIdentity, SourceLocation, Value};
use std::rc::Rc;
pub struct Parser<'a> {
lexer: Lexer<'a>,
current_token: Token,
pub diagnostics: Diagnostics,
}
impl<'a> Parser<'a> {
pub fn new(input: &'a str) -> Self {
let mut lexer = Lexer::new(input);
let mut diagnostics = Diagnostics::new();
let current_token = match lexer.next_token() {
Ok(t) => t,
Err(e) => {
diagnostics.push_error(e, None);
Token {
kind: TokenKind::EOF,
location: SourceLocation { line: 1, col: 1 },
}
}
};
Self {
lexer,
current_token,
diagnostics,
}
}
fn advance(&mut self) -> Token {
let next = match self.lexer.next_token() {
Ok(t) => t,
Err(e) => {
self.diagnostics
.push_error(e, Some(NodeIdentity::new(self.current_token.location)));
Token {
kind: TokenKind::EOF,
location: self.current_token.location,
}
}
};
std::mem::replace(&mut self.current_token, next)
}
fn peek(&self) -> &TokenKind {
&self.current_token.kind
}
pub fn parse_expression(&mut self) -> SyntaxNode {
let token_loc = self.current_token.location;
let identity = NodeIdentity::new(token_loc);
match self.peek() {
TokenKind::LeftParen => self.parse_list(),
TokenKind::LeftBracket => self.parse_vector_literal(),
TokenKind::LeftBrace => self.parse_record_literal(),
TokenKind::Quote => {
self.advance(); // consume '
let expr = self.parse_expression();
SyntaxNode {
identity: identity.clone(),
kind: SyntaxKind::Call {
callee: Rc::new(self.make_id_node("quote", identity.clone())),
args: Rc::new(SyntaxNode {
identity,
kind: SyntaxKind::Tuple {
elements: vec![Rc::new(expr)],
},
ty: (),
}),
},
ty: (),
}
}
TokenKind::Backtick => {
self.advance(); // consume `
let expr = self.parse_expression();
SyntaxNode {
identity,
kind: SyntaxKind::Template(Rc::new(expr)),
ty: (),
}
}
TokenKind::Tilde => {
self.advance(); // consume ~
if *self.peek() == TokenKind::At {
self.advance(); // consume @
let expr = self.parse_expression();
SyntaxNode {
identity,
kind: SyntaxKind::Splice(Rc::new(expr)),
ty: (),
}
} else {
let expr = self.parse_expression();
SyntaxNode {
identity,
kind: SyntaxKind::Placeholder(Rc::new(expr)),
ty: (),
}
}
}
_ => self.parse_atom(),
}
}
pub fn at_eof(&self) -> bool {
matches!(self.current_token.kind, TokenKind::EOF)
}
fn synchronize(&mut self) {
while !self.at_eof() {
match self.peek() {
TokenKind::RightParen | TokenKind::RightBracket | TokenKind::RightBrace => {
self.advance();
return;
}
_ => {
self.advance();
}
}
}
}
fn parse_atom(&mut self) -> SyntaxNode {
let token = self.advance();
let identity = NodeIdentity::new(token.location);
let kind = match token.kind {
TokenKind::Integer(n) => SyntaxKind::Constant(Value::Int(n)),
TokenKind::Float(n) => SyntaxKind::Constant(Value::Float(n)),
TokenKind::String(s) => SyntaxKind::Constant(Value::Text(s)),
TokenKind::Keyword(k) => SyntaxKind::Constant(Value::Keyword(Keyword::intern(&k))),
TokenKind::Identifier(id) => match id.as_ref() {
"..." => SyntaxKind::Nop,
s if s.starts_with('.') && s.len() > 1 => {
SyntaxKind::FieldAccessor(Keyword::intern(&s[1..]))
}
_ => SyntaxKind::Identifier {
symbol: id.into(),
binding: (),
},
},
TokenKind::EOF => SyntaxKind::Error, // Error already logged by advance
_ => {
self.diagnostics.push_error(
format!("Unexpected token in atom: {:?}", token.kind),
Some(identity.clone()),
);
SyntaxKind::Error
}
};
SyntaxNode {
identity,
kind,
ty: (),
}
}
fn parse_list(&mut self) -> SyntaxNode {
let start_loc = self.advance().location; // consume '('
let identity = NodeIdentity::new(start_loc);
if *self.peek() == TokenKind::RightParen {
self.diagnostics.push_error(
"Empty list () is not a valid expression",
Some(identity.clone()),
);
self.advance(); // consume )
return SyntaxNode {
identity,
kind: SyntaxKind::Error,
ty: (),
};
}
let head = self.parse_expression();
let node = if let SyntaxKind::Identifier { ref symbol, .. } = head.kind {
match symbol.name.as_ref() {
"if" => self.parse_if(identity),
"fn" => self.parse_fn(identity),
"pipe" => self.parse_pipe(identity),
"again" => self.parse_again(identity),
"def" => self.parse_def(identity),
"assign" => self.parse_assign(identity),
"do" => self.parse_do(identity),
"macro" => self.parse_macro_decl(identity),
_ => self.parse_call(head, identity),
}
} else {
self.parse_call(head, identity)
};
self.expect(TokenKind::RightParen);
node
}
fn parse_again(&mut self, identity: Identity) -> SyntaxNode {
let mut elements = Vec::new();
while *self.peek() != TokenKind::RightParen && *self.peek() != TokenKind::EOF {
elements.push(Rc::new(self.parse_expression()));
}
let args_node = SyntaxNode {
identity: identity.clone(),
kind: SyntaxKind::Tuple { elements },
ty: (),
};
SyntaxNode {
identity,
kind: SyntaxKind::Again {
args: Rc::new(args_node),
},
ty: (),
}
}
fn parse_if(&mut self, identity: Identity) -> SyntaxNode {
let cond = Rc::new(self.parse_expression());
let then_br = Rc::new(self.parse_expression());
let mut else_br = None;
if *self.peek() != TokenKind::RightParen {
else_br = Some(Rc::new(self.parse_expression()));
}
SyntaxNode {
identity,
kind: SyntaxKind::If {
cond,
then_br,
else_br,
},
ty: (),
}
}
fn parse_def(&mut self, identity: Identity) -> SyntaxNode {
let pattern = Rc::new(self.parse_pattern());
let value = Rc::new(self.parse_expression());
SyntaxNode {
identity,
kind: SyntaxKind::Def {
pattern,
value,
info: (),
},
ty: (),
}
}
fn parse_assign(&mut self, identity: Identity) -> SyntaxNode {
// (assign target value)
let target = Rc::new(self.parse_expression());
let value = Rc::new(self.parse_expression());
SyntaxNode {
identity,
kind: SyntaxKind::Assign {
target,
value,
info: (),
},
ty: (),
}
}
fn parse_do(&mut self, identity: Identity) -> SyntaxNode {
let mut exprs = Vec::new();
while *self.peek() != TokenKind::RightParen && *self.peek() != TokenKind::EOF {
exprs.push(Rc::new(self.parse_expression()));
}
SyntaxNode {
identity,
kind: SyntaxKind::Block { exprs },
ty: (),
}
}
fn parse_pipe(&mut self, identity: Identity) -> SyntaxNode {
let inputs_node = self.parse_expression();
let inputs = match inputs_node.kind {
SyntaxKind::Tuple { elements } => elements,
_ => vec![Rc::new(inputs_node)],
};
let lambda = Rc::new(self.parse_expression());
SyntaxNode {
identity,
kind: SyntaxKind::Pipe { inputs, lambda },
ty: (),
}
}
fn parse_fn(&mut self, identity: Identity) -> SyntaxNode {
let params = Rc::new(self.parse_param_vector());
let body = self.parse_expression();
SyntaxNode {
identity,
kind: SyntaxKind::Lambda {
params,
body: Rc::new(body),
info: (),
},
ty: (),
}
}
fn parse_macro_decl(&mut self, identity: Identity) -> SyntaxNode {
let name_node = self.parse_expression();
let name = match name_node.kind {
SyntaxKind::Identifier { symbol, .. } => symbol,
_ => {
self.diagnostics.push_error(
"Expected identifier for macro name",
Some(name_node.identity.clone()),
);
Symbol::from("error")
}
};
let params = Rc::new(self.parse_param_vector());
let body = self.parse_expression();
SyntaxNode {
identity,
kind: SyntaxKind::MacroDecl {
name,
params,
body: Rc::new(body),
},
ty: (),
}
}
fn parse_param_vector(&mut self) -> SyntaxNode {
if *self.peek() != TokenKind::LeftBracket {
self.diagnostics.push_error(
format!(
"Expected parameter vector [...] for fn, found {:?}",
self.peek()
),
Some(NodeIdentity::new(self.current_token.location)),
);
return SyntaxNode {
identity: NodeIdentity::new(self.current_token.location),
kind: SyntaxKind::Error,
ty: (),
};
}
self.parse_pattern()
}
fn parse_pattern(&mut self) -> SyntaxNode {
let next = self.peek();
match next {
TokenKind::Identifier(_) => {
let token = self.advance();
let sym: Symbol = match token.kind {
TokenKind::Identifier(s) => s.into(),
_ => unreachable!(),
};
SyntaxNode {
identity: NodeIdentity::new(token.location),
kind: SyntaxKind::Identifier {
symbol: sym,
binding: (),
},
ty: (),
}
}
TokenKind::LeftBracket => {
let token = self.advance();
let identity = NodeIdentity::new(token.location);
let mut elements = Vec::new();
while *self.peek() != TokenKind::RightBracket && *self.peek() != TokenKind::EOF {
elements.push(Rc::new(self.parse_pattern()));
}
self.expect(TokenKind::RightBracket);
SyntaxNode {
identity,
kind: SyntaxKind::Tuple { elements },
ty: (),
}
}
TokenKind::Tilde => {
let token = self.advance(); // consume ~
if *self.peek() == TokenKind::At {
self.advance(); // consume @
let expr = self.parse_expression();
SyntaxNode {
identity: NodeIdentity::new(token.location),
kind: SyntaxKind::Splice(Rc::new(expr)),
ty: (),
}
} else {
let expr = self.parse_expression();
SyntaxNode {
identity: NodeIdentity::new(token.location),
kind: SyntaxKind::Placeholder(Rc::new(expr)),
ty: (),
}
}
}
_ => {
self.diagnostics.push_error(
format!(
"Expected identifier or pattern vector [...] for definition, found {:?}",
next
),
Some(NodeIdentity::new(self.current_token.location)),
);
self.advance();
SyntaxNode {
identity: NodeIdentity::new(self.current_token.location),
kind: SyntaxKind::Error,
ty: (),
}
}
}
}
fn parse_call(&mut self, callee: SyntaxNode, identity: Identity) -> SyntaxNode {
let mut elements = Vec::new();
while *self.peek() != TokenKind::RightParen && *self.peek() != TokenKind::EOF {
elements.push(Rc::new(self.parse_expression()));
}
// The arguments are wrapped in a Tuple node, reusing the call's identity/location.
let args_node = SyntaxNode {
identity: identity.clone(),
kind: SyntaxKind::Tuple { elements },
ty: (),
};
SyntaxNode {
identity,
kind: SyntaxKind::Call {
callee: Rc::new(callee),
args: Rc::new(args_node),
},
ty: (),
}
}
fn parse_vector_literal(&mut self) -> SyntaxNode {
let token = self.advance();
let mut elements = Vec::new();
while *self.peek() != TokenKind::RightBracket && *self.peek() != TokenKind::EOF {
let expr = self.parse_expression();
elements.push(Rc::new(expr));
}
self.expect(TokenKind::RightBracket);
SyntaxNode {
identity: NodeIdentity::new(token.location),
kind: SyntaxKind::Tuple { elements },
ty: (),
}
}
fn parse_record_literal(&mut self) -> SyntaxNode {
let token = self.advance();
let mut fields = Vec::new();
while *self.peek() != TokenKind::RightBrace && *self.peek() != TokenKind::EOF {
let key_node = self.parse_expression();
// We check for keyword kind here (syntactically) to avoid ambiguity, but
// strictly we could allow any expression and check at runtime.
// Delphi enforces keywords. We can do minimal check here.
match &key_node.kind {
SyntaxKind::Constant(Value::Keyword(_)) => {}
_ => {
self.diagnostics.push_error(
"Record keys must be keywords (syntactically)",
Some(key_node.identity.clone()),
);
}
}
if *self.peek() == TokenKind::RightBrace || *self.peek() == TokenKind::EOF {
self.diagnostics.push_error(
"Record literal must have even number of forms",
Some(NodeIdentity::new(self.current_token.location)),
);
break;
}
let val_node = self.parse_expression();
fields.push((Rc::new(key_node), Rc::new(val_node)));
}
self.expect(TokenKind::RightBrace);
SyntaxNode {
identity: NodeIdentity::new(token.location),
kind: SyntaxKind::Record {
fields,
layout: (),
},
ty: (),
}
}
fn expect(&mut self, kind: TokenKind) -> Token {
if self.peek() == &kind {
self.advance()
} else {
self.diagnostics.push_error(
format!("Expected {:?}, but found {:?}", kind, self.peek()),
Some(NodeIdentity::new(self.current_token.location)),
);
// Recovery: skip until we find what we expected or a synchronization point
self.synchronize();
Token {
kind,
location: self.current_token.location,
}
}
}
fn make_id_node(&self, name: &str, identity: Identity) -> SyntaxNode {
SyntaxNode {
identity,
kind: SyntaxKind::Identifier {
symbol: Symbol::from(name),
binding: (),
},
ty: (),
}
}
}