Structs and comptime reflection stuff
This commit is contained in:
@@ -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
@@ -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
@@ -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'] __ }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user