initial structure impl

This commit is contained in:
2025-03-26 21:39:24 -04:00
parent 0614d48fcc
commit 021434d2f1
23 changed files with 390 additions and 84 deletions
+15 -12
View File
@@ -1,8 +1,8 @@
use std::fmt::Debug;
use super::{
MaybeParsable, Node, PExpr, PIdent, PType, Parsable, ParseResult, ParserCtx, Symbol,
Token, CompilerMsg
CompilerMsg, MaybeParsable, Node, PExpr, PIdent, PType, Parsable, ParseResult, ParserCtx,
Symbol, Token,
};
pub struct PVarDef {
@@ -18,27 +18,30 @@ pub struct PFieldDef {
impl Parsable for PVarDef {
fn parse(ctx: &mut ParserCtx) -> ParseResult<Self> {
let name = ctx.parse()?;
if ctx.peek().is_some_and(|n| n.is_symbol(Symbol::Colon)) {
ParseResult::Ok(if ctx.peek().is_some_and(|n| n.is_symbol(Symbol::Colon)) {
ctx.next();
ctx.parse().map(|ty| Self { name, ty: Some(ty) })
Self {
name,
ty: Some(ctx.parse()?),
}
} else {
ParseResult::Ok(Self { name, ty: None })
}
Self { name, ty: None }
})
}
}
impl Parsable for PFieldDef {
fn parse(ctx: &mut ParserCtx) -> ParseResult<Self> {
let name = ctx.parse()?;
if ctx.peek().is_some_and(|n| n.is_symbol(Symbol::Colon)) {
ParseResult::Ok(if ctx.peek().is_some_and(|n| n.is_symbol(Symbol::Colon)) {
ctx.next();
ctx.parse().map(|ty| Self {
Self {
name,
val: Some(ty),
})
val: Some(ctx.parse()?),
}
} else {
ParseResult::Ok(Self { name, val: None })
}
Self { name, val: None }
})
}
}
+15 -3
View File
@@ -1,7 +1,10 @@
use std::fmt::{Debug, Write};
use super::{
op::{PInfixOp, UnaryOp}, util::parse_list, Keyword, Node, NodeParsable, PAsmBlock, PBlock, PConstruct, PIdent, PLiteral, Parsable, ParseResult, ParserCtx, Symbol, CompilerMsg
op::{PInfixOp, UnaryOp},
util::parse_list,
CompilerMsg, Keyword, Node, NodeParsable, PAsmBlock, PBlock, PConstruct, PIdent, PLiteral,
Parsable, ParseResult, ParserCtx, Symbol,
};
type BoxNode = Node<Box<PExpr>>;
@@ -53,12 +56,21 @@ impl Parsable for PExpr {
Self::UnaryOp(op, n)
}
});
} else if let Some(val) = Node::maybe_parse(ctx) {
} else if let Some(val) = ctx.maybe_parse() {
Self::Lit(val)
} else {
let res = ctx.parse();
if res.node.is_some() {
Self::Ident(res.node)
// TODO: this is extremely limiting
// maybe parse generically and then during lowering figure out what's a function vs
// struct vs etc like mentioned in main.rs
if let Some(next) = ctx.peek()
&& next.is_symbol(Symbol::OpenCurly)
{
Self::Construct(ctx.parse_with(res.node)?)
} else {
Self::Ident(res.node)
}
} else {
let next = ctx.expect_peek()?;
return ParseResult::Err(CompilerMsg::unexpected_token(next, "an expression"));
+1 -1
View File
@@ -5,7 +5,7 @@ use std::{
};
#[derive(Clone)]
pub struct PIdent(String);
pub struct PIdent(pub String);
impl Parsable for PIdent {
fn parse(ctx: &mut ParserCtx) -> ParseResult<Self> {
+18 -7
View File
@@ -1,8 +1,10 @@
use std::fmt::Debug;
use crate::parser::ParsableWith;
use super::{
util::parse_list, Keyword, Node, PExpr, PFieldDef, PIdent, PType, PVarDef, Parsable,
ParseResult, ParserCtx, CompilerMsg, Symbol,
util::parse_list, CompilerMsg, Keyword, Node, PExpr, PFieldDef, PIdent, PType, PVarDef,
Parsable, ParseResult, ParserCtx, Symbol,
};
#[derive(Debug)]
@@ -13,7 +15,7 @@ pub struct PStruct {
#[derive(Debug)]
pub struct PConstruct {
pub name: Node<PIdent>,
pub name: Node<PType>,
pub fields: PConstructFields,
}
@@ -57,11 +59,20 @@ impl Parsable for PStruct {
}
}
impl Parsable for PConstruct {
fn parse(ctx: &mut ParserCtx) -> ParseResult<Self> {
ctx.expect_kw(Keyword::Struct)?;
let name = ctx.parse()?;
impl ParsableWith for PConstruct {
type Data = Node<PIdent>;
fn parse(ctx: &mut ParserCtx, name_node: Self::Data) -> ParseResult<Self> {
let next = ctx.expect_peek()?;
// TODO: this is not correct span; type should also span generics, which aren't even in
// here yet
let span = name_node.span;
let name = Node::new(
PType {
name: name_node,
args: Vec::new(),
},
span,
);
let fields = if next.is_symbol(Symbol::Semicolon) {
ctx.next();
PConstructFields::None
+9 -10
View File
@@ -1,9 +1,11 @@
use std::fmt::Debug;
use super::{util::parse_list, Node, Parsable, ParseResult, ParserCtx, CompilerMsg, Symbol, Token};
use super::{
util::parse_list, CompilerMsg, Node, PIdent, Parsable, ParseResult, ParserCtx, Symbol, Token,
};
pub struct PType {
pub name: String,
pub name: Node<PIdent>,
pub args: Vec<Node<PType>>,
}
@@ -11,18 +13,15 @@ impl Parsable for PType {
fn parse(ctx: &mut ParserCtx) -> ParseResult<Self> {
let next = ctx.expect_peek()?;
let res = if next.is_symbol(Symbol::Ampersand) {
let name = Node::new(PIdent("&".to_string()), next.span);
ctx.next();
let arg = ctx.parse()?;
Self {
name: "&".to_string(),
name,
args: vec![arg],
}
} else {
let Token::Word(name) = &next.token else {
return ParseResult::Err(CompilerMsg::unexpected_token(next, "a type identifier"));
};
let n = name.to_string();
ctx.next();
let n = ctx.parse()?;
let mut args = Vec::new();
if let Some(next) = ctx.peek() {
if next.is_symbol(Symbol::OpenAngle) {
@@ -38,8 +37,8 @@ impl Parsable for PType {
impl Debug for PType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.name)?;
if self.name == "&" {
write!(f, "{:?}", self.name)?;
if self.name.as_ref().is_some_and(|n| n.0 == "&") {
write!(f, "{:?}", self.args[0])?;
} else if !self.args.is_empty() {
write!(f, "<{:?}>", self.args)?;