initial structure impl
This commit is contained in:
+15
-12
@@ -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 }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
Reference in New Issue
Block a user