Podlog language v1 (#225)

* Initial commit for Podlog language

* Spell-checker thinks that 'lits' is a bad abbreviation for 'literals'

* Enable SetContains/SetNotContains

* Update language based on review feedback

* Typo/comment fix

* Make native predicates case-sensitive

* Enforce max batch size in CustomPredicateBatchBuilder

* Remove some unnecessary checks for things handled by the grammar

* Clean up more unnecessary error-checking

* Typo

* Simplify hex processing

* Replace various errors with unreachable!()

* Translate from big-endian hex string to little-endian RawValue

* Update hex en/decoding functions
This commit is contained in:
Rob Knight 2025-06-07 07:17:23 +02:00 committed by GitHub
parent e8edbbc1c5
commit 541c264586
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 2259 additions and 29 deletions

94
src/lang/error.rs Normal file
View file

@ -0,0 +1,94 @@
use thiserror::Error;
use crate::{frontend, lang::parser::ParseError, middleware};
#[derive(Error, Debug)]
pub enum LangError {
#[error("Parsing failed: {0}")]
Parse(Box<ParseError>),
#[error("AST processing error: {0}")]
Processor(Box<ProcessorError>),
#[error("Middleware error during processing: {0}")]
Middleware(Box<middleware::Error>),
#[error("Frontend error: {0}")]
Frontend(Box<frontend::Error>),
}
/// Errors that can occur during the processing of Podlog Pest tree into middleware structures.
#[derive(thiserror::Error, Debug)]
pub enum ProcessorError {
#[error("Undefined identifier: '{name}' at {span:?}")]
UndefinedIdentifier {
name: String,
span: Option<(usize, usize)>,
},
#[error("Duplicate definition: '{name}' at {span:?}")]
DuplicateDefinition {
name: String,
span: Option<(usize, usize)>,
},
#[error("Duplicate wildcard: ?{name} in scope at {span:?}")]
DuplicateWildcard {
name: String,
span: Option<(usize, usize)>,
},
#[error("Type error: expected {expected}, found {found} for '{item}' at {span:?}")]
TypeError {
expected: String,
found: String,
item: String,
span: Option<(usize, usize)>,
},
#[error(
"Invalid argument count for '{predicate}': expected {expected}, found {found} at {span:?}"
)]
ArgumentCountMismatch {
predicate: String,
expected: usize,
found: usize,
span: Option<(usize, usize)>,
},
#[error("Multiple REQUEST definitions found. Only one is allowed. First at {first_span:?}, second at {second_span:?}")]
MultipleRequestDefinitions {
first_span: Option<(usize, usize)>,
second_span: Option<(usize, usize)>,
},
#[error("Internal processing error: {0}")]
Internal(String),
#[error("Middleware error: {0}")]
Middleware(middleware::Error),
#[error("Undefined wildcard: '?{name}' at {span:?}")]
UndefinedWildcard {
name: String,
span: Option<(usize, usize)>,
},
#[error("Invalid literal format for {kind}: '{value}' at {span:?}")]
InvalidLiteralFormat {
kind: String,
value: String,
span: Option<(usize, usize)>,
},
#[error("Frontend error: {0}")]
Frontend(#[from] frontend::Error),
}
impl From<ParseError> for LangError {
fn from(err: ParseError) -> Self {
LangError::Parse(Box::new(err))
}
}
impl From<ProcessorError> for LangError {
fn from(err: ProcessorError) -> Self {
LangError::Processor(Box::new(err))
}
}
impl From<middleware::Error> for LangError {
fn from(err: middleware::Error) -> Self {
LangError::Middleware(Box::new(err))
}
}