Browse Source

Change function declaration syntax

github-actions
Garrit Franke 2 years ago
parent
commit
b21c781a64
  1. 7
      examples/hello_world.sb
  2. 3
      examples_out/out.js
  3. 13
      src/lexer/mod.rs
  4. 62
      src/lexer/tests.rs
  5. 5
      src/parser/mod.rs
  6. 44
      src/parser/tests.rs

7
examples/hello_world.sb

@ -1,3 +1,4 @@
fn main(n) {
n * 2;
}
main :: (n) {
return 2 * n;
}

3
examples_out/out.js

@ -1,3 +1,4 @@
function main(n) {
n * 2}
return 2 * n
}
console.log(main())

13
src/lexer/mod.rs

@ -53,6 +53,8 @@ pub enum TokenKind {
Slash,
/// ":"
Colon,
/// "::"
DoubleColon,
/// ";"
SemiColon,
/// ","
@ -97,7 +99,7 @@ pub enum Keyword {
If,
Else,
Return,
Function,
FunctionDecl,
Boolean,
Unknown,
}
@ -170,7 +172,13 @@ impl Cursor<'_> {
'=' => Equals,
_ => Assign,
},
':' => Colon,
':' => match self.first() {
':' => {
self.bump();
DoubleColon
}
_ => Colon,
},
';' => SemiColon,
',' => Comma,
'<' => LessThan,
@ -250,7 +258,6 @@ impl Cursor<'_> {
match original {
c if c == "if" => Keyword::If,
c if c == "else" => Keyword::Else,
c if c == "fn" => Keyword::Function,
c if c == "true" || c == "false" => Keyword::Boolean,
c if c == "let" => Keyword::Let,
c if c == "return" => Keyword::Return,

62
src/lexer/tests.rs

@ -160,18 +160,46 @@ mod tests {
#[test]
fn test_functions() {
let mut tokens = tokenize("fn fib() {}").into_iter();
let mut tokens = tokenize("fib :: () {}").into_iter();
assert_eq!(
tokens.nth(0).unwrap(),
Token {
len: 3,
kind: TokenKind::Identifier("fib".into()),
raw: "fib".to_owned(),
pos: Position {
raw: 2,
line: 1,
offset: 2
}
}
);
assert_eq!(
tokens.nth(0).unwrap(),
Token {
len: 1,
kind: TokenKind::Whitespace,
raw: " ".to_owned(),
pos: Position {
raw: 3,
line: 1,
offset: 3
}
}
);
assert_eq!(
tokens.nth(0).unwrap(),
Token {
len: 2,
kind: TokenKind::Keyword(Keyword::Function),
raw: "fn".to_owned(),
kind: TokenKind::DoubleColon,
raw: "::".to_owned(),
pos: Position {
raw: 1,
raw: 5,
line: 1,
offset: 1
offset: 5
}
}
);
@ -181,7 +209,7 @@ mod tests {
fn test_comments() {
let mut tokens = tokenize(
"// foo
fn fib() {}
fib :: () {}
",
)
.into_iter()
@ -205,16 +233,30 @@ fn fib() {}
}
);
assert_eq!(
tokens.nth(0).unwrap(),
Token {
len: 3,
kind: TokenKind::Identifier("fib".into()),
raw: "fib".to_owned(),
pos: Position {
raw: 9,
line: 2,
offset: 3
}
}
);
assert_eq!(
tokens.nth(0).unwrap(),
Token {
len: 2,
kind: TokenKind::Keyword(Keyword::Function),
raw: "fn".to_owned(),
kind: TokenKind::DoubleColon,
raw: "::".to_owned(),
pos: Position {
raw: 8,
raw: 12,
line: 2,
offset: 2
offset: 6
}
}
);

5
src/parser/mod.rs

@ -48,6 +48,8 @@ impl Parser {
self.peeked.pop()
};
dbg!(&item);
self.current = item.to_owned();
item
}
@ -149,9 +151,8 @@ impl Parser {
}
fn parse_function(&mut self) -> Result<Function, String> {
self.match_keyword(Keyword::Function)?;
let name = self.match_identifier()?;
self.match_token(TokenKind::DoubleColon)?;
self.match_token(TokenKind::BraceOpen)?;
let arguments: Vec<Variable> = match self.peek() {

44
src/parser/tests.rs

@ -3,7 +3,7 @@ use crate::parser::*;
#[test]
fn test_parse_empty_function() {
let raw = "fn main() {}";
let raw = "main :: () {}";
let tokens = tokenize(raw);
let tree = parse(tokens, Some(raw.to_string()));
assert!(tree.is_ok())
@ -12,7 +12,7 @@ fn test_parse_empty_function() {
#[test]
fn test_parse_function_with_return() {
let raw = "
fn main() {
main :: () {
return 1;
}
";
@ -24,7 +24,7 @@ fn test_parse_function_with_return() {
#[test]
fn test_parse_missing_semicolon() {
let raw = "
fn main() {
main :: () {
return 1
}
";
@ -46,12 +46,12 @@ fn test_parse_no_function_context() {
#[test]
fn test_parse_multiple_functions() {
let raw = "
fn foo() {
foo :: () {
let x = 2;
return x;
}
fn bar() {
bar :: () {
let y = 5;
return y;
}
@ -64,7 +64,7 @@ fn test_parse_multiple_functions() {
#[test]
fn test_parse_variable_declaration() {
let raw = "
fn main() {
main :: () {
let x = 1;
return x;
}
@ -77,7 +77,7 @@ fn test_parse_variable_declaration() {
#[test]
fn test_parse_function_with_args() {
let raw = "
fn main(foo) {
main :: (foo) {
return foo;
}
";
@ -89,11 +89,11 @@ fn test_parse_function_with_args() {
#[test]
fn test_parse_function_call() {
let raw = "
fn main(foo) {
main :: (foo) {
foo();
}
fn foo() {
foo :: () {
foo(2);
}
";
@ -105,11 +105,11 @@ fn test_parse_function_call() {
#[test]
fn test_parse_return_function_call() {
let raw = "
fn main() {
main :: () {
return fib(2);
}
fn fib() {
fib :: () {
return fib(2);
}
";
@ -121,11 +121,11 @@ fn test_parse_return_function_call() {
#[test]
fn test_parse_function_call_multiple_arguments() {
let raw = "
fn main() {
main :: () {
fib(1, 2, 3);
}
fn fib() {
fib :: () {
return 2;
}
";
@ -137,11 +137,11 @@ fn test_parse_function_call_multiple_arguments() {
#[test]
fn test_parse_nexted_function_call() {
let raw = "
fn main() {
main :: () {
fib(fib(2), 2);
}
fn fib(n) {
fib :: (n) {
return 2;
}
";
@ -153,7 +153,7 @@ fn test_parse_nexted_function_call() {
#[test]
fn test_parse_basic_ops() {
let raw = "
fn main() {
main :: () {
return 2 * 5;
}
";
@ -165,7 +165,7 @@ fn test_parse_basic_ops() {
#[test]
fn test_parse_compound_ops() {
let raw = "
fn main() {
main :: () {
2 * 5 / 3;
}
";
@ -177,7 +177,7 @@ fn test_parse_compound_ops() {
#[test]
fn test_parse_compound_ops_with_function_call() {
let raw = "
fn main() {
main :: () {
return 2 * fib(1) / 3;
}
";
@ -189,7 +189,7 @@ fn test_parse_compound_ops_with_function_call() {
#[test]
fn test_parse_compound_ops_with_strings() {
let raw = "
fn main() {
main :: () {
return 2 * \"Hello\";
}
";
@ -201,7 +201,7 @@ fn test_parse_compound_ops_with_strings() {
#[test]
fn test_parse_compound_ops_with_identifier() {
let raw = "
fn main(n) {
main :: (n) {
return 2 * n;
}
";
@ -214,7 +214,7 @@ fn test_parse_compound_ops_with_identifier() {
#[ignore]
fn test_parse_compound_ops_with_identifier_first() {
let raw = "
fn main(n) {
main :: (n) {
return n * 2;
}
";
@ -226,7 +226,7 @@ fn test_parse_compound_ops_with_identifier_first() {
#[test]
fn test_parse_compound_ops_return() {
let raw = "
fn main(n) {
main :: (n) {
return 2 * n;
}
";

Loading…
Cancel
Save