Skip to content

Commit e7febd0

Browse files
committed
Finished initial support for parsing for generics / compile-time arguments
1 parent 2e0959a commit e7febd0

File tree

9 files changed

+66
-43
lines changed

9 files changed

+66
-43
lines changed

Diff for: src/ast/expr/call.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use super::Expr;
2-
use crate::ast::Type;
2+
use crate::ast::{CompileTimeArgument, Type};
33

44
#[derive(Clone, Debug)]
55
pub struct Call {
66
pub function_name: String,
77
pub arguments: Vec<Expr>,
88
pub expected_to_return: Option<Type>,
9+
pub generics: Vec<CompileTimeArgument>,
910
}

Diff for: src/interpreter_env/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ pub fn setup_build_system_interpreter_symbols(file: &mut AstFile) {
5959
function_name: "main".into(),
6060
arguments: vec![],
6161
expected_to_return: Some(void.clone()),
62+
generics: vec![],
6263
}))
6364
.at(Source::internal());
6465

Diff for: src/parser/error.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ pub enum ParseErrorKind {
6969
DefineHasMultipleDefinitions {
7070
name: String,
7171
},
72-
ExpectedEnumName,
7372
ExpectedEnumMemberName,
7473
Lexical {
7574
message: String,
@@ -84,6 +83,7 @@ pub enum ParseErrorKind {
8483
name: String,
8584
word_for_nth: String,
8685
},
86+
GenericsNotSupportedHere,
8787
Other {
8888
message: String,
8989
},
@@ -180,9 +180,6 @@ impl Display for ParseErrorKind {
180180
ParseErrorKind::DefineHasMultipleDefinitions { name } => {
181181
write!(f, "Define '{}' has multiple definitions", name)?;
182182
}
183-
ParseErrorKind::ExpectedEnumName => {
184-
write!(f, "Expected enum name")?;
185-
}
186183
ParseErrorKind::ExpectedEnumMemberName => {
187184
write!(f, "Expected enum member name")?;
188185
}
@@ -207,6 +204,9 @@ impl Display for ParseErrorKind {
207204
word_for_nth, name
208205
)?;
209206
}
207+
ParseErrorKind::GenericsNotSupportedHere => {
208+
write!(f, "Generics not supported here")?;
209+
}
210210
ParseErrorKind::Other { message } | ParseErrorKind::Lexical { message } => {
211211
write!(f, "{}", message)?;
212212
}

Diff for: src/parser/parse_expr/post/member.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
1414
let source = self.parse_token(TokenKind::Member, Some("for member expression"))?;
1515
let member_name = self.parse_identifier(Some("for member name"))?;
1616

17-
if self.input.peek_is(TokenKind::OpenParen) {
18-
self.parse_call_with(member_name, vec![subject], source)
17+
if self.input.peek_is(TokenKind::OpenParen) || self.input.peek_is(TokenKind::OpenAngle) {
18+
let generics = self.parse_generics()?;
19+
self.parse_call_with(member_name, generics, vec![subject], source)
1920
} else {
2021
Ok(ExprKind::Member(Box::new(subject), member_name).at(source))
2122
}

Diff for: src/parser/parse_expr/primary/call.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
use super::Parser;
22
use crate::{
3-
ast::{Call, Expr, ExprKind},
3+
ast::{Call, CompileTimeArgument, Expr, ExprKind},
44
inflow::Inflow,
55
parser::error::ParseError,
66
source_files::Source,
77
token::{Token, TokenKind},
88
};
99

1010
impl<'a, I: Inflow<Token>> Parser<'a, I> {
11-
pub fn parse_call(&mut self) -> Result<Expr, ParseError> {
11+
pub fn parse_call(
12+
&mut self,
13+
function_name: String,
14+
generics: Vec<CompileTimeArgument>,
15+
source: Source,
16+
) -> Result<Expr, ParseError> {
1217
// function_name(arg1, arg2, arg3)
1318
// ^
1419

15-
let (function_name, source) =
16-
self.parse_identifier_keep_location(Some("for function call"))?;
17-
18-
self.parse_call_with(function_name, vec![], source)
20+
self.parse_call_with(function_name, generics, vec![], source)
1921
}
2022

2123
pub fn parse_call_with(
2224
&mut self,
2325
function_name: String,
26+
generics: Vec<CompileTimeArgument>,
2427
prefix_args: Vec<Expr>,
2528
source: Source,
2629
) -> Result<Expr, ParseError> {
@@ -45,6 +48,7 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
4548
function_name,
4649
arguments: args,
4750
expected_to_return: None,
51+
generics,
4852
}))
4953
.at(source))
5054
}

Diff for: src/parser/parse_expr/primary/declare_assign.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@ use crate::{
33
ast::{DeclareAssign, Expr, ExprKind},
44
inflow::Inflow,
55
parser::error::ParseError,
6+
source_files::Source,
67
token::{Token, TokenKind},
78
};
89

910
impl<'a, I: Inflow<Token>> Parser<'a, I> {
10-
pub fn parse_declare_assign(&mut self) -> Result<Expr, ParseError> {
11+
pub fn parse_declare_assign(
12+
&mut self,
13+
variable_name: String,
14+
source: Source,
15+
) -> Result<Expr, ParseError> {
1116
// variable_name := value
12-
// ^
13-
14-
let (variable_name, source) =
15-
self.parse_identifier_keep_location(Some("for function call"))?;
17+
// ^
1618

1719
self.parse_token(
1820
TokenKind::DeclareAssign,

Diff for: src/parser/parse_expr/primary/enum_member_literal.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,26 @@ use crate::{
33
ast::{EnumMemberLiteral, Expr, ExprKind},
44
inflow::Inflow,
55
parser::error::{ParseError, ParseErrorKind},
6+
source_files::Source,
67
token::{Token, TokenKind},
78
};
89

910
impl<'a, I: Inflow<Token>> Parser<'a, I> {
10-
pub fn parse_enum_member_literal(&mut self) -> Result<Expr, ParseError> {
11+
pub fn parse_enum_member_literal(
12+
&mut self,
13+
enum_name: String,
14+
source: Source,
15+
) -> Result<Expr, ParseError> {
1116
// EnumName::EnumVariant
1217
// ^
1318

14-
let source = self.source_here();
15-
let enum_name = self
16-
.input
17-
.eat_identifier()
18-
.ok_or_else(|| ParseErrorKind::ExpectedEnumName.at(source))?;
19-
2019
self.parse_token(TokenKind::Namespace, Some("for enum member literal"))?;
2120

2221
let variant_source = self.source_here();
2322
let variant_name = self
2423
.input
2524
.eat_identifier()
26-
.ok_or_else(|| ParseErrorKind::ExpectedEnumName.at(variant_source))?;
25+
.ok_or_else(|| ParseErrorKind::ExpectedEnumMemberName.at(variant_source))?;
2726

2827
Ok(ExprKind::EnumMemberLiteral(Box::new(EnumMemberLiteral {
2928
enum_name,

Diff for: src/parser/parse_expr/primary/mod.rs

+25-17
Original file line numberDiff line numberDiff line change
@@ -70,32 +70,31 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
7070
// TODO: CLEANUP: This should be cleaned up once we have proper
7171
// namespaces and generic parsing that applies to all cases
7272

73-
match self.input.peek_nth(1).kind {
74-
TokenKind::Namespace => self.parse_enum_member_literal(),
75-
TokenKind::OpenAngle => {
76-
let name = self.input.eat_identifier().unwrap();
77-
let generics = self.parse_generics()?;
73+
let name = self.input.eat_identifier().unwrap();
74+
let generics = self.parse_generics()?;
7875

76+
match self.input.peek().kind {
77+
TokenKind::Namespace => {
7978
if !generics.is_empty() {
80-
todo!("generics in expressions not implemented yet");
79+
return Err(ParseErrorKind::GenericsNotSupportedHere.at(source));
8180
}
8281

83-
let ast_type = self.parse_type_from_parts(name, vec![], source)?;
84-
self.parse_structure_literal_with(ast_type)
82+
self.parse_enum_member_literal(name, source)
8583
}
8684
TokenKind::OpenCurly => {
87-
let peek = &self.input.peek_nth(2).kind;
85+
let ast_type = self.parse_type_from_parts(name, generics, source)?;
86+
let peek = &self.input.peek_nth(1).kind;
8887

8988
if peek.is_extend() || peek.is_colon() {
90-
self.parse_structure_literal()
89+
self.parse_structure_literal_with(ast_type)
9190
} else {
9291
let next_three =
9392
array_last::<3, 5, _>(self.input.peek_n()).map(|token| &token.kind);
9493

9594
match &next_three[..] {
9695
[TokenKind::Identifier(_), TokenKind::Colon, ..]
9796
| [TokenKind::Newline, TokenKind::Identifier(_), TokenKind::Colon, ..] => {
98-
self.parse_structure_literal()
97+
self.parse_structure_literal_with(ast_type)
9998
}
10099
_ => Ok(Expr::new(
101100
ExprKind::Variable(
@@ -106,12 +105,21 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
106105
}
107106
}
108107
}
109-
TokenKind::OpenParen => self.parse_call(),
110-
TokenKind::DeclareAssign => self.parse_declare_assign(),
111-
_ => Ok(Expr::new(
112-
ExprKind::Variable(self.input.advance().kind.unwrap_identifier()),
113-
source,
114-
)),
108+
TokenKind::OpenParen => self.parse_call(name, generics, source),
109+
TokenKind::DeclareAssign => {
110+
if !generics.is_empty() {
111+
return Err(ParseErrorKind::GenericsNotSupportedHere.at(source));
112+
}
113+
114+
self.parse_declare_assign(name, source)
115+
}
116+
_ => {
117+
if !generics.is_empty() {
118+
return Err(ParseErrorKind::GenericsNotSupportedHere.at(source));
119+
}
120+
121+
Ok(Expr::new(ExprKind::Variable(name), source))
122+
}
115123
}
116124
}
117125
TokenKind::Not | TokenKind::BitComplement | TokenKind::Subtract => {

Diff for: src/resolve/expr/call.rs

+7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ pub fn resolve_call_expr(
1515
call: &ast::Call,
1616
source: Source,
1717
) -> Result<TypedExpr, ResolveError> {
18+
if !call.generics.is_empty() {
19+
return Err(ResolveErrorKind::Other {
20+
message: "Resolution of calls with generics is not implemented yet".into(),
21+
}
22+
.at(source));
23+
}
24+
1825
let function_ref = ctx
1926
.function_search_ctx
2027
.find_function_or_error(&call.function_name, source)?;

0 commit comments

Comments
 (0)