Skip to content

Commit a6a7fd9

Browse files
author
Joel Abrahams
committed
feat: remove vararg from grammar
1 parent 056b3e9 commit a6a7fd9

12 files changed

Lines changed: 53 additions & 74 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,14 @@ class MyServer(def ip_address: IPv4Address)
107107
def is_connected: Bool := False
108108
def _last_message: Str := "temp"
109109
110-
def last_sent(fin self) -> Str ! ServerError =>
110+
def last_sent(fin self) -> Str ! ServerError :=
111111
self._last_message
112112
113113
def connect(self) :=
114114
self.is_connected := True
115115
print(always_the_same_message)
116116
117-
def send(self, message: Str) ! ServerError =>
117+
def send(self, message: Str) ! ServerError :=
118118
if self.is_connected then
119119
self._last_message := message
120120
else

docs/spec/grammar.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,8 @@ The grammar of the language in Extended Backus-Naur Form (EBNF).
5757
5858
reassignment ::= expression ( ":=" | "+=" | "-=" | "*=" | "/=" | "^=" | ">>=" | "<<=" ) expression
5959
anon-fun ::= "\" [ id-maybe-type { "," id-maybe-type } ] ":=" expression
60-
call ::= expression [ ( "." | "?." ) ] id tuple [ handle ]
61-
60+
call ::= expression [ ( "." | "?." ) ] id tuple [ "!" ] [ newline match-cases ]
6261
raise ::= "!" id { "," id }
63-
handle ::= "!" | newline match-cases
6462
6563
collection ::= tuple | set | list | map
6664
tuple ::= "(" { expression } ")"
@@ -81,7 +79,7 @@ The grammar of the language in Extended Backus-Naur Form (EBNF).
8179
fun-def ::= [ "pure" ] id fun-args [ "->" type ] [ raise ]
8280
[ ":=" ( expr-or-stmt | newline block ) ]
8381
fun-args ::= "(" [ fun-arg ] { "," fun-arg } ")"
84-
fun-arg ::= [ "vararg" ] ( id-maybe-type | literal ) [ ":=" expression ]
82+
fun-arg ::= ( id-maybe-type | literal ) [ ":=" expression ]
8583
forward ::= "forward" id { "," id }
8684
8785
operation ::= relation [ ( equality | instance-eq | binary-logic ) relation ]

docs/spec/keywords.md

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ Keyword | Use
3838
`def` | Denote definition
3939
`fin` | Denote defined variable is immutable
4040
`pure` | Denote function is pure
41-
`vararg` | Denote variable argument
4241

4342
## Boolean operators
4443

@@ -93,11 +92,3 @@ Keyword | Use
9392
---|---
9493
`return` | Return from a function or method
9594
`pass` | Empty placeholder statement
96-
97-
## Errors
98-
99-
Keyword | Use
100-
---|---
101-
`handle` | Denote handle cases
102-
`raise` | Denote that an expression, statement, or function may raise an error
103-
`retry` | Retry an expression from within handle case

src/parse/call.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::parse::ast::Node;
22
use crate::parse::ast::AST;
3+
use crate::parse::control_flow_expr::parse_match_cases;
34
use crate::parse::definition::parse_lambda_arg;
45
use crate::parse::expression::parse_inner_expression;
56
use crate::parse::iterator::LexIterator;
@@ -19,7 +20,6 @@ pub fn parse_anon_fun(it: &mut LexIterator) -> ParseResult {
1920
})?;
2021

2122
it.eat(&Token::Assign, "anonymous function")?;
22-
2323
let body = it.parse(&parse_expression, "anonymous function", start)?;
2424
let node = Node::AnonFun {
2525
args,
@@ -28,8 +28,9 @@ pub fn parse_anon_fun(it: &mut LexIterator) -> ParseResult {
2828
Ok(Box::from(AST::new(start.union(body.pos), node)))
2929
}
3030

31+
/// TODO parse match cases
3132
pub fn parse_call(pre: &AST, it: &mut LexIterator) -> ParseResult {
32-
it.peek_or_err(
33+
let res = it.peek_or_err(
3334
&|it, ast| match ast.token {
3435
Token::Point => {
3536
it.eat(&Token::Point, "call")?;
@@ -58,7 +59,23 @@ pub fn parse_call(pre: &AST, it: &mut LexIterator) -> ParseResult {
5859
},
5960
&[Token::Point, Token::LRBrack],
6061
"function call",
61-
)
62+
)?;
63+
64+
if it.peek_if_followed_by(&Token::NL, &Token::Indent) {
65+
it.eat(&Token::NL, "internal error in parsing call")?; // peek covers this
66+
67+
// parse handle cases if indentation block after
68+
let cases = it.parse_vec(&parse_match_cases, "handle cases", res.pos)?;
69+
let end = cases.last().map_or(res.pos, |stmt| stmt.pos);
70+
71+
let node = Node::Handle {
72+
expr_or_stmt: res.clone(),
73+
cases,
74+
};
75+
Ok(Box::from(AST::new(res.pos.union(end), node)))
76+
} else {
77+
Ok(res)
78+
}
6279
}
6380

6481
fn parse_arguments(it: &mut LexIterator) -> ParseResult<Vec<AST>> {

src/parse/definition.rs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use crate::parse::expr_or_stmt::parse_expr_or_stmt;
55
use crate::parse::iterator::LexIterator;
66
use crate::parse::lex::token::Token;
77
use crate::parse::operation::parse_expression;
8+
use crate::parse::result::custom;
89
use crate::parse::result::ParseResult;
9-
use crate::parse::result::{custom, ParseErr};
1010
use crate::parse::ty::parse_expression_type;
1111
use crate::parse::ty::parse_id;
1212
use crate::parse::ty::parse_type;
@@ -177,7 +177,12 @@ pub fn parse_fun_args(it: &mut LexIterator) -> ParseResult<Vec<AST>> {
177177
let mut args = vec![];
178178
it.peek_while_not_token(&Token::RRBrack, &mut |it, _| {
179179
args.push(*it.parse(&parse_fun_arg, "function arguments", start)?);
180-
it.eat_if(&Token::Comma);
180+
181+
if let Some(next) = it.peek_next() {
182+
if next.token != Token::RRBrack {
183+
it.eat(&Token::Comma, "function arguments must be comma separated")?;
184+
}
185+
}
181186
Ok(())
182187
})?;
183188

@@ -187,7 +192,6 @@ pub fn parse_fun_args(it: &mut LexIterator) -> ParseResult<Vec<AST>> {
187192

188193
pub fn parse_fun_arg(it: &mut LexIterator) -> ParseResult {
189194
let start = it.start_pos("function argument")?;
190-
let vararg = it.eat_if(&Token::Vararg).is_some();
191195

192196
let expression_type = it.parse(&parse_expression_type, "function argument", start)?;
193197
let (mutable, var, ty) = match &expression_type.node {
@@ -208,7 +212,7 @@ pub fn parse_fun_arg(it: &mut LexIterator) -> ParseResult {
208212

209213
let end = default.clone().map_or(expression_type.pos, |def| def.pos);
210214
let node = Node::FunArg {
211-
vararg,
215+
vararg: false,
212216
mutable,
213217
var,
214218
ty,
@@ -217,10 +221,9 @@ pub fn parse_fun_arg(it: &mut LexIterator) -> ParseResult {
217221
Ok(Box::from(AST::new(start.union(end), node)))
218222
}
219223

220-
/// Lambda args cannot be assigned a default
224+
/// Lambda args cannot be assigned a default, though whether we should even allow default arguments is debatable.
221225
pub fn parse_lambda_arg(it: &mut LexIterator) -> ParseResult {
222226
let start = it.start_pos("function argument")?;
223-
let vararg = it.eat_if(&Token::Vararg).is_some();
224227

225228
let expression_type = it.parse(&parse_expression_type, "function argument", start)?;
226229
let (mutable, var, ty) = match &expression_type.node {
@@ -233,17 +236,8 @@ pub fn parse_lambda_arg(it: &mut LexIterator) -> ParseResult {
233236
}
234237
};
235238

236-
if let Some(lex) = it.peek_next() {
237-
if lex.token == Token::Assign {
238-
return Err(Box::new(custom(
239-
"lambda function arguments cannot have defaults",
240-
lex.pos,
241-
)));
242-
}
243-
}
244-
245239
let node = Node::FunArg {
246-
vararg,
240+
vararg: false,
247241
mutable,
248242
var,
249243
ty,
@@ -545,7 +539,7 @@ mod test {
545539

546540
#[test]
547541
fn function_definition_verify() {
548-
let source = String::from("def f(fin b: Something, vararg c) := d");
542+
let source = String::from("def f(fin b: Something, c) := d");
549543
let ast = parse_direct(&source).unwrap();
550544
let (pure, id, fun_args, ret, raises, body) = unwrap_func_definition!(ast);
551545

@@ -587,8 +581,8 @@ mod test {
587581
default: d2,
588582
},
589583
) => {
590-
assert_eq!(v1.clone(), false);
591-
assert_eq!(v2.clone(), true);
584+
assert!(!v1.clone());
585+
assert!(!v2.clone());
592586

593587
assert_eq!(
594588
id1.node,
@@ -681,9 +675,15 @@ mod test {
681675
}
682676
}
683677

678+
#[test]
679+
fn function_no_separator_args() {
680+
let source = String::from("def f(x b: Something) := d");
681+
parse_direct(&source).unwrap_err();
682+
}
683+
684684
#[test]
685685
fn function_definition_with_literal_verify() {
686-
let source = String::from("def f(x, vararg b: Something) := d");
686+
let source = String::from("def f(x, b: Something) := d");
687687
let ast = parse_direct(&source).unwrap();
688688
let (pure, id, fun_args, ret, _, body) = unwrap_func_definition!(ast);
689689

@@ -725,7 +725,7 @@ mod test {
725725
},
726726
) => {
727727
assert!(!v1.clone());
728-
assert!(v2.clone());
728+
assert!(!v2.clone());
729729

730730
assert!(mut1.clone());
731731
assert!(mut2.clone());

src/parse/expr_or_stmt.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use crate::parse::ast::Node;
2-
use crate::parse::ast::AST;
31
use crate::parse::block::parse_block;
4-
use crate::parse::control_flow_expr::parse_match_cases;
52
use crate::parse::iterator::LexIterator;
63
use crate::parse::lex::token::Token;
74
use crate::parse::operation::parse_expression;
@@ -25,7 +22,6 @@ pub fn parse_expr_or_stmt(it: &mut LexIterator) -> ParseResult {
2522

2623
it.peek(
2724
&|it, lex| match lex.token {
28-
Token::Handle => parse_handle(*result.clone(), it),
2925
Token::Assign
3026
| Token::AddAssign
3127
| Token::SubAssign
@@ -40,21 +36,6 @@ pub fn parse_expr_or_stmt(it: &mut LexIterator) -> ParseResult {
4036
)
4137
}
4238

43-
pub fn parse_handle(expr_or_stmt: AST, it: &mut LexIterator) -> ParseResult {
44-
let start = it.start_pos("handle")?;
45-
it.eat(&Token::Handle, "handle")?;
46-
it.eat(&Token::NL, "handle")?;
47-
48-
let cases = it.parse_vec(&parse_match_cases, "handle", start)?;
49-
let end = cases.last().map_or(start, |stmt| stmt.pos);
50-
51-
let node = Node::Handle {
52-
expr_or_stmt: Box::from(expr_or_stmt),
53-
cases,
54-
};
55-
Ok(Box::from(AST::new(start.union(end), node)))
56-
}
57-
5839
#[cfg(test)]
5940
mod test {
6041
use crate::parse::ast::node_op::NodeOp;

src/parse/lex/token.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ pub enum Token {
4040
Point,
4141
Comma,
4242
DoublePoint,
43-
Vararg,
4443
BSlash,
4544

4645
Id(String),
@@ -126,7 +125,6 @@ pub enum Token {
126125
With,
127126

128127
Question,
129-
Handle,
130128

131129
Pass,
132130
Comment(String),
@@ -168,7 +166,6 @@ impl fmt::Display for Token {
168166
Token::Point => write!(f, "."),
169167
Token::Comma => write!(f, ","),
170168
Token::DoublePoint => write!(f, ":"),
171-
Token::Vararg => write!(f, "vararg"),
172169
Token::BSlash => write!(f, "\\"),
173170

174171
Token::Fin => write!(f, "fin"),
@@ -252,7 +249,6 @@ impl fmt::Display for Token {
252249

253250
Token::Question => write!(f, "?"),
254251

255-
Token::Handle => write!(f, "handle"),
256252
Token::Raise => write!(f, "!"),
257253
Token::When => write!(f, "when"),
258254

src/parse/lex/tokenize.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ fn as_op_or_id(string: String) -> Token {
258258

259259
"import" => Token::Import,
260260
"forward" => Token::Forward,
261-
"vararg" => Token::Vararg,
262261

263262
"def" => Token::Def,
264263
"fin" => Token::Fin,
@@ -288,10 +287,7 @@ fn as_op_or_id(string: String) -> Token {
288287
"with" => Token::With,
289288

290289
"in" => Token::In,
291-
292-
"handle" => Token::Handle,
293290
"when" => Token::When,
294-
295291
"pass" => Token::Pass,
296292

297293
_ => Token::Id(string),

src/parse/result.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pub fn expected_one_of(tokens: &[Token], actual: &Lex, parsing: &str) -> ParseEr
8282

8383
pub fn expected(expected: &Token, actual: &Lex, parsing: &str) -> ParseErr {
8484
let msg = format!(
85-
"Expected {}{expected} token while parsing {}{parsing}, but found {}",
85+
"Expected {}{expected:?} token while parsing {}{parsing}, but found {}",
8686
an_or_a(expected),
8787
an_or_a(parsing),
8888
actual.token
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
class MyErr: Exception
22
class MyErr2: Exception
33

4-
def f(fun: Int -> Int) raise [MyErr, MyErr2] := g()
5-
def g() raise [MyErr2] := pass
4+
def f(fun: Int -> Int) ! { MyErr, MyErr2 } := g()
5+
def g() ! MyErr2 := pass

0 commit comments

Comments
 (0)