Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 91 additions & 89 deletions compiler/pipec-ast/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ impl<'this> ASTGenerator<'this> {
Token::PublicKeyword => self.consume_public_keyword(),
Token::TypeKeyword => self.consume_type_keyword(),
Token::TraitKeyword => self.consume_trait_keyword(),
Token::ImplementKeyword => self.consume_implement_keyword(),
Token::AtSign => self.consume_attributes(),
_v => {
println!("{_v:#?}");
Expand All @@ -89,6 +90,56 @@ impl<'this> ASTGenerator<'this> {
}
}

#[inline]
pub(crate) fn consume_implement_keyword(&mut self) -> ASTNode {
self.advance_stream();
let generics = self.consume_generics();
self.consume_whitespace();
let first = self.consume_a_path();
let second = {
self.consume_whitespace();
match self.peek_stream() {
Some(Token::ForKeyword) => {
self.advance_stream();
self.consume_whitespace();
Some(self.consume_a_path())
}
Some(Token::LeftCurly) => None,
v => todo!("unexpected {v:#?}"),
}
};
self.consume_whitespace();
let block = {
self.must(Token::LeftCurly);
let mut nodes = Vec::new();
loop {
self.consume_whitespace();
if self.peek_stream() == &Some(Token::RightCurly) {
self.advance_stream();
break;
}
nodes.push(self.parse_value());
}
ASTTree::new(nodes, self.src)
};

if let Some(implementor) = second {
ASTNode::ImplementBlock {
generics,
traitpath: Some(first),
implementor,
block,
}
} else {
ASTNode::ImplementBlock {
generics,
traitpath: second,
implementor: first,
block,
}
}
}

#[inline]
pub(crate) fn consume_trait_keyword(&mut self) -> ASTNode {
self.advance_stream();
Expand Down Expand Up @@ -132,6 +183,7 @@ impl<'this> ASTGenerator<'this> {
.parse_arena(self.loader.load(self.src), self.arena);
match name {
"language" => attributes.push(self.consume_language_attribute()),
"inline" => attributes.push(self.consume_inline_attribute()),
_ => todo!(),
}
} else {
Expand All @@ -141,6 +193,11 @@ impl<'this> ASTGenerator<'this> {
ASTNode::Attributed(attributes, Box::new(self.parse_value()))
}

#[inline]
pub(crate) fn consume_inline_attribute(&mut self) -> Attribute {
Attribute::Inline
}

#[inline]
pub(crate) fn consume_language_attribute(&mut self) -> Attribute {
self.must(Token::LeftParenthesis);
Expand Down Expand Up @@ -366,13 +423,13 @@ impl<'this> ASTGenerator<'this> {
self.consume_whitespace();
match self.peek_stream() {
Some(Token::Ident(_)) => {
let name = self.must_ident();
let generics = self.consume_generics();
out.push(Trait { name, generics });
out.push(self.consume_a_path());
self.consume_whitespace();
if self.next_is(Token::Plus) {
self.advance_stream();
continue;
} else {
break;
}
}
Some(Token::Comma) | Some(Token::RightSquare) | Some(Token::LeftCurly) => {
Expand Down Expand Up @@ -1173,33 +1230,31 @@ impl<'this> ASTGenerator<'this> {
Some(Token::Ident(v)) => {
let name = *v;
self.advance_stream();
let param = self.consume_path_param();
out.push(PathNode::Named { name, param });
continue;
}
Some(Token::Slash) => {
self.advance_stream();
continue;
let generics = self.consume_generics();
out.push(PathNode::Singly { name, generics });
if self.next_is(Token::Backslash) {
self.advance_stream();
continue;
} else {
break;
}
}
Some(Token::LeftParenthesis) => {
self.advance_stream();
let mut vals = Vec::new();
loop {
self.consume_whitespace();
match self.advance_stream() {
Some(Token::Ident(v)) => {
vals.push(v);
continue;
}
Some(Token::RightParenthesis) => {
break;
}
Some(Token::Comma) => {
continue;
}
_v => {}
vals.push(self.consume_a_path());
self.consume_whitespace();
if self.next_is(Token::Comma) {
self.advance_stream();
continue;
} else {
break;
}
}
out.push(PathNode::Multi(vals));
self.must(Token::RightParenthesis);
}
_ => {
break;
Expand All @@ -1209,62 +1264,12 @@ impl<'this> ASTGenerator<'this> {
Path(out)
}

#[inline]
pub(crate) fn consume_path_param(&mut self) -> Option<FunctionNodeParams> {
match self.peek_stream() {
Some(Token::LeftParenthesis) => {
if let Expression::TupleExpression { values } = self.consume_tuple_expression() {
return Some(FunctionNodeParams::Tuple(values));
}
// TODO : compiler error
unreachable!();
}
Some(Token::LeftAngle) => Some(FunctionNodeParams::Angles(self.consume_angle_params())),
_v => None,
}
}
#[inline]
pub(crate) fn consume_whitespace(&mut self) {
while self.tokens.peek() == &Some(Token::Whitespace) {
self.tokens.next_token();
}
}

#[inline]
pub(crate) fn consume_angle_params(&mut self) -> Vec<Path> {
self.must(Token::LeftAngle);
let mut out = Vec::new();
loop {
self.consume_whitespace();
match self.peek_stream() {
Some(Token::Ident(_)) => {
out.push(self.consume_a_path());
self.consume_whitespace();
match self.peek_stream() {
Some(Token::Comma) => {
self.advance_stream();
continue;
}
Some(Token::Ident(_)) => {
continue;
}
Some(Token::RightAngle) => {
break;
}
_ => {
//TODO : compiler error
unreachable!()
}
}
}
_ => {
//TODO : compiler error
unreachable!()
}
}
}
out
}
}

#[derive(Clone, Debug, Hash)]
Expand All @@ -1273,11 +1278,8 @@ pub struct Path(pub Vec<PathNode>);

#[derive(Debug, Clone, Hash)]
pub enum PathNode {
Named {
name: Span,
param: Option<FunctionNodeParams>,
},
Tuple(Vec<Span>),
Singly { name: Span, generics: Generics },
Multi(Vec<Path>),
}

#[derive(Debug, Clone, Hash)]
Expand Down Expand Up @@ -1327,6 +1329,12 @@ pub enum ASTNode {
supertraits: Traits,
tree: ASTTree,
},
ImplementBlock {
generics: Generics,
traitpath: Option<Path>,
implementor: Path,
block: ASTTree,
},
Public(Box<Self>),
Attributed(Vec<Attribute>, Box<Self>),
EOF,
Expand All @@ -1335,6 +1343,7 @@ pub enum ASTNode {
#[derive(Debug, Clone)]
pub enum Attribute {
LanguageAttribute(Span),
Inline,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -1501,29 +1510,22 @@ pub struct FunctionDeclarationParameter {
pub arg_type: Path,
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Hash)]
pub struct Generics(pub Vec<Generic>);

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Hash)]
#[allow(unused)]
pub struct Generic {
name: Span,
generictype: GenericType,
traits: Traits,
}

#[derive(Debug, Clone, Default)]
#[allow(unused)]
pub struct Traits(Vec<Trait>);

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Hash, Default)]
#[allow(unused)]
pub struct Trait {
name: Span,
generics: Generics,
}
pub struct Traits(Vec<Path>);

#[derive(Debug, Clone)]
#[derive(Debug, Clone, Hash)]
pub enum GenericType {
Lifetime,
Generic,
Expand Down
16 changes: 16 additions & 0 deletions compiler/pipec-ast/src/tokenizer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,12 @@ impl<'chars> Tokenizer<'chars> {
'=' => self.consume_equal_sign(),
'"' => self.consume_string(),
'#' => self.consume_hash(),
'\\' => self.consume_backslash(),
v if v.is_ascii_whitespace() => self.consume_whitespace(),
v if v.is_ascii_alphabetic() => self.consume_ident_token(),
v if v.is_ascii_digit() => self.consume_digit_token(),
_v => {
println!("unexpected token {_v}");
//TODO : compiler error
unreachable!()
}
Expand All @@ -106,6 +108,12 @@ impl<'chars> Tokenizer<'chars> {
}
}

#[inline]
pub(crate) fn consume_backslash(&mut self) -> Token {
self.advance_stream();
Token::Backslash
}

#[inline]
pub(crate) fn consume_left_paranthesis(&mut self) -> Token {
self.advance_stream();
Expand Down Expand Up @@ -436,6 +444,8 @@ impl<'chars> Tokenizer<'chars> {
"switch" => SwitchKeyword,
"type" => TypeKeyword,
"trait" => TraitKeyword,
"implement" => ImplementKeyword,
"for" => ForKeyword,
_ => Token::Ident(input),
}
}
Expand Down Expand Up @@ -529,6 +539,8 @@ pub enum Token {
RightAngle,
/// #
Hash,
/// \
Backslash,
/// (whitespace)
Whitespace,
/// using
Expand Down Expand Up @@ -565,6 +577,10 @@ pub enum Token {
TypeKeyword,
/// trait
TraitKeyword,
/// implement
ImplementKeyword,
/// for
ForKeyword,
/// 21213
Digit { val: Span, digittype: DigitType },
/// things_like_this or this_2
Expand Down
4 changes: 2 additions & 2 deletions compiler/pipec-gst/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl<'this> GlobalSymbolTree<'this> {
let first = vec.first();
match first {
None => {}
Some(PathNode::Named { name, param: _ }) => {
Some(PathNode::Singly { name, generics: _ }) => {
let name = name.parse_arena(self.src, self.arena);
match name {
"integer8" => return Integer8,
Expand Down Expand Up @@ -167,7 +167,7 @@ impl<'this> GlobalSymbolTree<'this> {
if next.is_none() {
break;
}
if let Some(PathNode::Named { name, param: _ }) = next {
if let Some(PathNode::Singly { name, generics: _ }) = next {
let parsed = name.parse_arena(self.src, self.arena).to_string();
out.path.push(parsed);
}
Expand Down