Structs and comptime reflection stuff

This commit is contained in:
Mia
2026-03-07 01:42:06 +01:00
parent 81d1dfe3d3
commit fb84e09391
18 changed files with 1399 additions and 321 deletions
+1
View File
@@ -6,4 +6,5 @@ edition = "2024"
[dependencies]
arcstr = "1.2.0"
derive_more = { version = "2.1.0", features = ["deref", "debug", "display"] }
indexmap = "2.13.0"
peg = "0.8.5"
+33 -4
View File
@@ -1,5 +1,6 @@
use arcstr::Substr;
use derive_more::Deref;
use indexmap::IndexMap;
use std::ops::Range;
use std::sync::Arc;
@@ -27,6 +28,7 @@ pub enum Expr {
#[debug("{_0:?}")]
Binary(Arc<BinaryExpr>),
Index(Arc<IndexingExpr>),
Access(Arc<AccessExpr>),
Tuple(Vec<Expr>),
List(Vec<Expr>),
Struct(Arc<StructCtor>),
@@ -56,6 +58,8 @@ impl Expr {
pub fn range(&self) -> Range<usize> {
match self {
Self::Ident(e) => e.range(),
Self::Access(e) => e.range(),
Self::Number(e) => e.text.range(),
_ => todo!("{self:?}"),
}
}
@@ -74,6 +78,18 @@ pub struct IndexingExpr {
pub index: Expr,
}
#[derive(Debug)]
pub struct AccessExpr {
pub value: Expr,
pub field: Ident,
}
impl AccessExpr {
pub fn range(&self) -> Range<usize> {
self.value.range().start..self.field.0.range().end
}
}
#[rustfmt::skip]
#[derive(derive_more::Debug)]
pub enum BinaryOp {
@@ -82,7 +98,6 @@ pub enum BinaryOp {
#[debug("{_0}")] Mul(Substr),
#[debug("{_0}")] Div(Substr),
#[debug("{_0}")] Mod(Substr),
#[debug("{_0}")] Dot(Substr),
#[debug("{_0}")] Eq(Substr),
#[debug("{_0}")] Ne(Substr),
#[debug("{_0}")] Lt(Substr),
@@ -96,7 +111,8 @@ pub enum BinaryOp {
#[derive(Debug)]
pub enum Type {
Ptr { base: Expr, mutable: bool },
Ptr { base: Expr, mutable: Option<Substr> },
Struct(Struct),
}
#[derive(Debug)]
@@ -141,13 +157,26 @@ pub struct Function {
#[derive(Debug)]
pub struct NameValuePair {
pub name: Ident,
pub r#type: Expr,
pub value: Expr,
}
#[derive(Debug)]
pub struct Struct {
pub fields: Vec<Field>,
}
#[derive(Debug)]
pub struct Field {
pub name: Ident,
pub ty: Expr,
pub public: Option<Substr>,
pub mutable: Option<Substr>,
}
#[derive(Debug)]
pub struct StructCtor {
pub r#type: Expr,
pub r#values: Vec<NameValuePair>,
pub r#values: IndexMap<Substr, NameValuePair>,
}
#[derive(Debug)]
+47 -21
View File
@@ -60,6 +60,9 @@ peg::parser! {
rule ident() -> Ident
= text:$(['_'|'a'..='z'|'A'..='Z']['_'|'a'..='z'|'A'..='Z'|'0'..='9']*) { Ident(text) }
rule ident2() -> Ident
= text:$("#"? ['_'|'a'..='z'|'A'..='Z']['_'|'a'..='z'|'A'..='Z'|'0'..='9']*) { Ident(text) }
rule string() -> Substr
= str:$("\"" char()* "\"") { str }
@@ -70,29 +73,32 @@ peg::parser! {
// ### EXPRESSIONS ####
rule expr() -> Expr = precedence! {
lhs:(@) __ op:$("as") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Cast(op), rhs })) }
lhs:(@) __ op:$("as") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Cast(op), rhs })) }
--
lhs:@ __ op:$("=") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Assign(op), rhs })) }
lhs:(@) __ op:$(".") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Dot(op), rhs })) }
lhs:(@) "(" __ args:(expr() ** ("," __)) __ ")" { Expr::Call { func: Arc::new(lhs), args } }
value:(@) "[" __ index:expr() __ "]" { Expr::Index(Arc::new(IndexingExpr { value, index })) }
r#type:(@) _ "{" __ values:name_value_pairs() __ "}" { Expr::Struct(Arc::new(StructCtor { r#type, values })) }
value:@ __ op:$(".") __ field:ident2() { Expr::Access(AccessExpr { value, field }.into()) }
lhs:@ "(" __ args:(expr() ** list_separator()) __ ")" { Expr::Call { func: Arc::new(lhs), args } }
value:@ "[" __ index:expr() __ "]" { Expr::Index(Arc::new(IndexingExpr { value, index })) }
r#type:@ __ "{" __ values:name_value_pairs() __ "}" { Expr::Struct(Arc::new(StructCtor {
r#type, values: values.into_iter().map(|v| (v.name.0.clone(), v)).collect()
})) }
--
lhs:(@) __ op:$("+") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Add(op), rhs })) }
lhs:(@) __ op:$("-") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Sub(op), rhs })) }
lhs:@ __ op:$("+") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Add(op), rhs })) }
lhs:@ __ op:$("-") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Sub(op), rhs })) }
--
lhs:(@) __ op:$("*") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Mul(op), rhs })) }
lhs:(@) __ op:$("/") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Div(op), rhs })) }
lhs:(@) __ op:$("%") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Mod(op), rhs })) }
lhs:@ __ op:$("*") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Mul(op), rhs })) }
lhs:@ __ op:$("/") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Div(op), rhs })) }
lhs:@ __ op:$("%") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Mod(op), rhs })) }
--
lhs:(@) __ op:$("..") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Range(op), rhs })) }
lhs:@ __ op:$("..") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Range(op), rhs })) }
--
lhs:(@) __ op:$("==") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Eq(op), rhs })) }
lhs:(@) __ op:$("!=") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Ne(op), rhs })) }
lhs:(@) __ op:$("<") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Lt(op), rhs })) }
lhs:(@) __ op:$(">") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Gt(op), rhs })) }
lhs:(@) __ op:$("<=") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Le(op), rhs })) }
lhs:(@) __ op:$(">=") __ rhs:@ { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Ge(op), rhs })) }
lhs:@ __ op:$("==") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Eq(op), rhs })) }
lhs:@ __ op:$("!=") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Ne(op), rhs })) }
lhs:@ __ op:$("<") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Lt(op), rhs })) }
lhs:@ __ op:$(">") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Gt(op), rhs })) }
lhs:@ __ op:$("<=") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Le(op), rhs })) }
lhs:@ __ op:$(">=") __ rhs:expr() { Expr::Binary(Arc::new(BinaryExpr { lhs, op: BinaryOp::Ge(op), rhs })) }
--
block:block() { Expr::Block(block)}
for_loop:for_loop() { Expr::For(Arc::new(for_loop))}
@@ -103,7 +109,8 @@ peg::parser! {
"(" __ tuple:(expr() **<2,> ("," __)) __ ")" { Expr::Tuple(tuple) }
"[" __ list:(expr() ** ("," __)) __ "]" { Expr::List(list) }
"(" __ v:expr() __ ")" { v }
"*" __ m:"mut"? __ v:expr() { Expr::Type(Arc::new(Type::Ptr { base:v, mutable: m.is_some() })) }
"*" __ m:$"mut"? __ v:expr() { Expr::Type(Arc::new(Type::Ptr { base:v, mutable: m })) }
v:struct_t() { Expr::Type(Arc::new(Type::Struct(v))) }
v:string() { Expr::String(v) }
v:number() { Expr::Number(v) }
v:ident() { Expr::Ident(v) }
@@ -113,14 +120,32 @@ peg::parser! {
= "{" __ exprs:(i:expr() statement_separator() {i})* __ "}" { Block(exprs) }
rule func() -> Function
= s:position!() t:$"fn" __ "(" __ args:name_value_pairs() __ ")" __ ret:("->" __ e:expr() {e})? __ block:block()? e:position!()
= s:position!() t:$"fn" __ "(" __ args:name_type_pairs() __ ")" __ ret:("->" __ e:expr() {e})? __ block:block()? e:position!()
{ Function { args, ret, block: block.map(Arc::new), text: t.parent().substr(s..e), } }
rule name_type_pair() -> NameValuePair
= name:ident() __ ":" __ value:expr() { NameValuePair { name, value } }
rule name_type_pairs() -> Vec<NameValuePair>
= v:(name_type_pair() **<1,> list_separator()) list_separator()? { v }
/ { vec![] }
rule name_value_pair() -> NameValuePair
= name:ident() __ ":" __ r#type:expr() { NameValuePair { name, r#type } }
= name:ident() __ "=" __ value:expr() { NameValuePair { name, value } }
rule name_value_pairs() -> Vec<NameValuePair>
= v:(name_value_pair() ** ("," __)) { v }
= v:(name_value_pair() **<1,> list_separator()) list_separator()? { v }
/ { vec![] }
rule struct_t() -> Struct
= "struct" __ "{" __ fields:fields() __ "}" { Struct { fields } }
rule field() -> Field
= public:$"pub"? __ mutable:$"mut"? __ name:ident() __ ":" __ ty:expr() { Field { name, ty, public, mutable } }
rule fields() -> Vec<Field>
= v:(field() **<1,> list_separator()) list_separator()? { v }
/ { vec![] }
rule import() -> Import
= "import" _ expr:expr() { Import(expr) }
@@ -156,6 +181,7 @@ peg::parser! {
rule _ = quiet! { [' '|'\t']+ }
rule __ = quiet! { [' '|'\t'|'\n']* }
rule statement_separator() = quiet! { [';'|'\n'] __ }
rule list_separator() = quiet! { [','|'\n'] __ }
}
}