type checking !?!?
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use super::{PIdent, Node, Parsable, ParseResult, ParserCtx, ParserMsg, Symbol};
|
||||
use super::{Node, PIdent, Parsable, ParseResult, ParserCtx, Symbol, CompilerMsg};
|
||||
|
||||
pub struct PInstruction {
|
||||
pub op: Node<PIdent>,
|
||||
@@ -38,7 +38,7 @@ impl Parsable for PAsmArg {
|
||||
|
||||
let next = ctx.expect_peek()?;
|
||||
if !next.is_symbol(Symbol::OpenCurly) {
|
||||
return ParseResult::Err(ParserMsg::unexpected_token(
|
||||
return ParseResult::Err(CompilerMsg::unexpected_token(
|
||||
next,
|
||||
"An identifier or {identifier}",
|
||||
));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fmt::{Debug, Write};
|
||||
|
||||
use super::{
|
||||
token::Symbol, Node, NodeParsable, Parsable, ParseResult, ParserCtx, ParserMsg, PStatement,
|
||||
token::Symbol, Node, NodeParsable, PStatement, Parsable, ParseResult, ParserCtx, CompilerMsg,
|
||||
};
|
||||
use crate::util::Padder;
|
||||
|
||||
@@ -24,7 +24,7 @@ impl Parsable for PBlock {
|
||||
loop {
|
||||
let Some(next) = ctx.peek() else {
|
||||
recover = true;
|
||||
ctx.err(ParserMsg::unexpected_end());
|
||||
ctx.err(CompilerMsg::unexpected_end());
|
||||
break;
|
||||
};
|
||||
if next.is_symbol(Symbol::CloseCurly) {
|
||||
@@ -36,7 +36,7 @@ impl Parsable for PBlock {
|
||||
expect_semi = false;
|
||||
continue;
|
||||
} else if expect_semi {
|
||||
ctx.err(ParserMsg {
|
||||
ctx.err(CompilerMsg {
|
||||
msg: "expected ';'".to_string(),
|
||||
spans: vec![ctx.next_start().char_span()],
|
||||
});
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use super::{
|
||||
PIdent, MaybeParsable, Node, Parsable, ParseResult, ParserCtx, ParserMsg, Symbol, Token, PType,
|
||||
MaybeParsable, Node, PExpr, PIdent, PType, Parsable, ParseResult, ParserCtx, Symbol,
|
||||
Token, CompilerMsg
|
||||
};
|
||||
|
||||
pub struct PVarDef {
|
||||
@@ -9,6 +10,11 @@ pub struct PVarDef {
|
||||
pub ty: Option<Node<PType>>,
|
||||
}
|
||||
|
||||
pub struct PFieldDef {
|
||||
pub name: Node<PIdent>,
|
||||
pub val: Option<Node<PExpr>>,
|
||||
}
|
||||
|
||||
impl Parsable for PVarDef {
|
||||
fn parse(ctx: &mut ParserCtx) -> ParseResult<Self> {
|
||||
let name = ctx.parse()?;
|
||||
@@ -21,6 +27,21 @@ impl Parsable for PVarDef {
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
ctx.next();
|
||||
ctx.parse().map(|ty| Self {
|
||||
name,
|
||||
val: Some(ty),
|
||||
})
|
||||
} else {
|
||||
ParseResult::Ok(Self { name, val: None })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SelfVar {
|
||||
pub ty: SelfType,
|
||||
}
|
||||
@@ -32,7 +53,7 @@ pub enum SelfType {
|
||||
}
|
||||
|
||||
impl MaybeParsable for SelfVar {
|
||||
fn maybe_parse(ctx: &mut ParserCtx) -> Result<Option<Self>, super::ParserMsg> {
|
||||
fn maybe_parse(ctx: &mut ParserCtx) -> Result<Option<Self>, CompilerMsg> {
|
||||
if let Some(mut next) = ctx.peek() {
|
||||
let mut ty = SelfType::Take;
|
||||
if next.is_symbol(Symbol::Ampersand) {
|
||||
@@ -47,7 +68,7 @@ impl MaybeParsable for SelfVar {
|
||||
}
|
||||
}
|
||||
if ty != SelfType::Take {
|
||||
return Err(ParserMsg::unexpected_token(next, "self"));
|
||||
return Err(CompilerMsg::unexpected_token(next, "self"));
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
@@ -64,6 +85,16 @@ impl Debug for PVarDef {
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for PFieldDef {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.name.fmt(f)?;
|
||||
if let Some(val) = &self.val {
|
||||
write!(f, ": {:?}", val)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for SelfVar {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
use std::fmt::{Debug, Write};
|
||||
|
||||
use super::{
|
||||
op::{PInfixOp, UnaryOp},
|
||||
util::parse_list,
|
||||
PAsmBlock, PBlock, PIdent, Keyword, PLiteral, Node, NodeParsable, Parsable, ParseResult, ParserCtx,
|
||||
ParserMsg, Symbol,
|
||||
op::{PInfixOp, UnaryOp}, util::parse_list, Keyword, Node, NodeParsable, PAsmBlock, PBlock, PConstruct, PIdent, PLiteral, Parsable, ParseResult, ParserCtx, Symbol, CompilerMsg
|
||||
};
|
||||
|
||||
type BoxNode = Node<Box<PExpr>>;
|
||||
@@ -18,6 +15,7 @@ pub enum PExpr {
|
||||
Call(BoxNode, Vec<Node<PExpr>>),
|
||||
Group(BoxNode),
|
||||
AsmBlock(Node<PAsmBlock>),
|
||||
Construct(Node<PConstruct>),
|
||||
}
|
||||
|
||||
impl Parsable for PExpr {
|
||||
@@ -63,7 +61,7 @@ impl Parsable for PExpr {
|
||||
Self::Ident(res.node)
|
||||
} else {
|
||||
let next = ctx.expect_peek()?;
|
||||
return ParseResult::Err(ParserMsg::unexpected_token(next, "an expression"));
|
||||
return ParseResult::Err(CompilerMsg::unexpected_token(next, "an expression"));
|
||||
}
|
||||
};
|
||||
let Some(mut next) = ctx.peek() else {
|
||||
@@ -140,6 +138,7 @@ impl Debug for PExpr {
|
||||
}
|
||||
PExpr::Group(inner) => inner.fmt(f)?,
|
||||
PExpr::AsmBlock(inner) => inner.fmt(f)?,
|
||||
PExpr::Construct(inner) => inner.fmt(f)?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::{MaybeParsable, Parsable, ParseResult, ParserCtx, ParserMsg, Token};
|
||||
use super::{MaybeParsable, Parsable, ParseResult, ParserCtx, Token, CompilerMsg};
|
||||
use std::{
|
||||
fmt::{Debug, Display},
|
||||
ops::Deref,
|
||||
@@ -11,7 +11,7 @@ impl Parsable for PIdent {
|
||||
fn parse(ctx: &mut ParserCtx) -> ParseResult<Self> {
|
||||
let next = ctx.expect_peek()?;
|
||||
let Token::Word(name) = &next.token else {
|
||||
return ParseResult::Err(ParserMsg::unexpected_token(next, "an identifier"));
|
||||
return ParseResult::Err(CompilerMsg::unexpected_token(next, "an identifier"));
|
||||
};
|
||||
let name = name.to_string();
|
||||
ctx.next();
|
||||
@@ -20,7 +20,7 @@ impl Parsable for PIdent {
|
||||
}
|
||||
|
||||
impl MaybeParsable for PIdent {
|
||||
fn maybe_parse(ctx: &mut ParserCtx) -> Result<Option<Self>, ParserMsg> {
|
||||
fn maybe_parse(ctx: &mut ParserCtx) -> Result<Option<Self>, CompilerMsg> {
|
||||
let Some(next) = ctx.peek() else { return Ok(None) };
|
||||
let Token::Word(name) = &next.token else {
|
||||
return Ok(None);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::{CharCursor, MaybeParsable, ParserCtx, ParserMsg, Symbol, Token};
|
||||
use super::{CharCursor, MaybeParsable, ParserCtx, CompilerMsg, Symbol, Token};
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
@@ -17,7 +17,7 @@ pub struct PNumber {
|
||||
}
|
||||
|
||||
impl MaybeParsable for PLiteral {
|
||||
fn maybe_parse(ctx: &mut ParserCtx) -> Result<Option<Self>, ParserMsg> {
|
||||
fn maybe_parse(ctx: &mut ParserCtx) -> Result<Option<Self>, CompilerMsg> {
|
||||
let inst = ctx.expect_peek()?;
|
||||
Ok(Some(match &inst.token {
|
||||
Token::Symbol(Symbol::SingleQuote) => {
|
||||
@@ -37,7 +37,7 @@ impl MaybeParsable for PLiteral {
|
||||
if !first.is_ascii_digit() {
|
||||
return Ok(None);
|
||||
}
|
||||
let (whole, ty) = parse_whole_num(text);
|
||||
let (whole, ty) = parse_whole_num(&text);
|
||||
let mut num = PNumber {
|
||||
whole,
|
||||
decimal: None,
|
||||
@@ -81,7 +81,7 @@ pub fn parse_whole_num(text: &str) -> (String, Option<String>) {
|
||||
(whole, if ty.is_empty() { None } else { Some(ty) })
|
||||
}
|
||||
|
||||
pub fn string_from(cursor: &mut CharCursor) -> Result<String, ParserMsg> {
|
||||
pub fn string_from(cursor: &mut CharCursor) -> Result<String, CompilerMsg> {
|
||||
let mut str = String::new();
|
||||
loop {
|
||||
let c = cursor.expect_next()?;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::{
|
||||
PFunction, PImpl, Keyword, Node, Parsable, ParseResult, ParserCtx, ParserMsg,
|
||||
PFunction, PImpl, Keyword, Node, Parsable, ParseResult, ParserCtx, CompilerMsg,
|
||||
PStruct, Symbol, Token, PTrait,
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
@@ -52,18 +52,18 @@ impl Parsable for PModule {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
ctx.err(ParserMsg::unexpected_token(next, "a definition"));
|
||||
ctx.err(CompilerMsg::unexpected_token(next, "a definition"));
|
||||
ctx.next();
|
||||
}
|
||||
}
|
||||
} else if next.is_symbol(Symbol::Semicolon) {
|
||||
ctx.hint(ParserMsg::from_instances(
|
||||
ctx.hint(CompilerMsg::from_instances(
|
||||
&[next],
|
||||
"unneeded semicolon".to_string(),
|
||||
));
|
||||
ctx.next();
|
||||
} else {
|
||||
ctx.err(ParserMsg::unexpected_token(next, "a definition"));
|
||||
ctx.err(CompilerMsg::unexpected_token(next, "a definition"));
|
||||
ctx.next();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use super::{
|
||||
util::parse_list, PIdent, Keyword, Node, Parsable, ParseResult, ParserCtx, ParserMsg, Symbol,
|
||||
PType, PVarDef,
|
||||
util::parse_list, Keyword, Node, PExpr, PFieldDef, PIdent, PType, PVarDef, Parsable,
|
||||
ParseResult, ParserCtx, CompilerMsg, Symbol,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -11,6 +11,12 @@ pub struct PStruct {
|
||||
pub fields: PStructFields,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PConstruct {
|
||||
pub name: Node<PIdent>,
|
||||
pub fields: PConstructFields,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PStructFields {
|
||||
Named(Vec<Node<PVarDef>>),
|
||||
@@ -18,6 +24,13 @@ pub enum PStructFields {
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PConstructFields {
|
||||
Named(Vec<Node<PFieldDef>>),
|
||||
Tuple(Vec<Node<PExpr>>),
|
||||
None,
|
||||
}
|
||||
|
||||
impl Parsable for PStruct {
|
||||
fn parse(ctx: &mut ParserCtx) -> ParseResult<Self> {
|
||||
ctx.expect_kw(Keyword::Struct)?;
|
||||
@@ -33,7 +46,7 @@ impl Parsable for PStruct {
|
||||
ctx.next();
|
||||
PStructFields::Tuple(parse_list(ctx, Symbol::CloseParen)?)
|
||||
} else {
|
||||
let msg = ParserMsg::unexpected_token(next, "`;`, `(`, or `{`");
|
||||
let msg = CompilerMsg::unexpected_token(next, "`;`, `(`, or `{`");
|
||||
ctx.err(msg);
|
||||
return ParseResult::Recover(PStruct {
|
||||
name,
|
||||
@@ -43,3 +56,29 @@ impl Parsable for PStruct {
|
||||
ParseResult::Ok(PStruct { name, fields })
|
||||
}
|
||||
}
|
||||
|
||||
impl Parsable for PConstruct {
|
||||
fn parse(ctx: &mut ParserCtx) -> ParseResult<Self> {
|
||||
ctx.expect_kw(Keyword::Struct)?;
|
||||
let name = ctx.parse()?;
|
||||
let next = ctx.expect_peek()?;
|
||||
let fields = if next.is_symbol(Symbol::Semicolon) {
|
||||
ctx.next();
|
||||
PConstructFields::None
|
||||
} else if next.is_symbol(Symbol::OpenCurly) {
|
||||
ctx.next();
|
||||
PConstructFields::Named(parse_list(ctx, Symbol::CloseCurly)?)
|
||||
} else if next.is_symbol(Symbol::OpenParen) {
|
||||
ctx.next();
|
||||
PConstructFields::Tuple(parse_list(ctx, Symbol::CloseParen)?)
|
||||
} else {
|
||||
let msg = CompilerMsg::unexpected_token(next, "`;`, `(`, or `{`");
|
||||
ctx.err(msg);
|
||||
return ParseResult::Recover(PConstruct {
|
||||
name,
|
||||
fields: PConstructFields::None,
|
||||
});
|
||||
};
|
||||
ParseResult::Ok(PConstruct { name, fields })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use super::{util::parse_list, Node, Parsable, ParseResult, ParserCtx, ParserMsg, Symbol, Token};
|
||||
use super::{util::parse_list, Node, Parsable, ParseResult, ParserCtx, CompilerMsg, Symbol, Token};
|
||||
|
||||
pub struct PType {
|
||||
pub name: String,
|
||||
@@ -19,7 +19,7 @@ impl Parsable for PType {
|
||||
}
|
||||
} else {
|
||||
let Token::Word(name) = &next.token else {
|
||||
return ParseResult::Err(ParserMsg::unexpected_token(next, "a type identifier"));
|
||||
return ParseResult::Err(CompilerMsg::unexpected_token(next, "a type identifier"));
|
||||
};
|
||||
let n = name.to_string();
|
||||
ctx.next();
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use super::{Node, Parsable, ParserCtx, ParserMsg, Symbol};
|
||||
use super::{Node, Parsable, ParserCtx, CompilerMsg, Symbol};
|
||||
|
||||
pub fn parse_list_sep<T: Parsable>(
|
||||
ctx: &mut ParserCtx,
|
||||
sep: Symbol,
|
||||
end: Symbol,
|
||||
) -> Result<Vec<Node<T>>, ParserMsg> {
|
||||
) -> Result<Vec<Node<T>>, CompilerMsg> {
|
||||
let mut vals = Vec::new();
|
||||
loop {
|
||||
let next = ctx.expect_peek()?;
|
||||
@@ -29,14 +29,14 @@ pub fn parse_list_sep<T: Parsable>(
|
||||
pub fn parse_list<T: Parsable>(
|
||||
ctx: &mut ParserCtx,
|
||||
end: Symbol,
|
||||
) -> Result<Vec<Node<T>>, ParserMsg> {
|
||||
) -> Result<Vec<Node<T>>, CompilerMsg> {
|
||||
parse_list_sep(ctx, Symbol::Comma, end)
|
||||
}
|
||||
|
||||
pub fn parse_list_nosep<T: Parsable>(
|
||||
ctx: &mut ParserCtx,
|
||||
end: Symbol,
|
||||
) -> Result<Vec<Node<T>>, ParserMsg> {
|
||||
) -> Result<Vec<Node<T>>, CompilerMsg> {
|
||||
let mut vals = Vec::new();
|
||||
loop {
|
||||
let next = ctx.expect_peek()?;
|
||||
|
||||
Reference in New Issue
Block a user