diff --git a/corpus/edigits_like.langexp b/corpus/edigits_like.langexp index e0919bd..fcd7174 100644 --- a/corpus/edigits_like.langexp +++ b/corpus/edigits_like.langexp @@ -7,26 +7,26 @@ EdigitsDraft :: math; exec.main = { - %n := (?? os.args.size > 1 -> (<> os.args[1]).scan !!-> 27); + %n := (?? os.args.size > 1 => (<> os.args[1]).scan !!=> 27); %k := binary_search 0; %p & %q := sum_terms 0 (k - 1); p += q; $a := (std.BigInt.of 10).pow (n - 1); %answer := p * a /. q; %s := answer.to_string; - @ %i : (@ %j : 0..(n / 10 +. 1) -> j * 10) -> { - ?? i + 10 <=. n -> + @ %i : (@ %j : 0..(n / 10 +. 1) => j * 10) => { + ?? i + 10 <=. n => print (s.subseg i (i + 10) ++ "\t:" ++. (i + 10).to_string) - !!-> + !!=> print (s.subseg i n - ++ (@ _ : 0..(10 - math.mod n 10) -> ''\s'') + ++ (@ _ : 0..(10 - math.mod n 10) => ''\s'') ++ "\t:" ++ n.to_string); }; } sum_terms 'a 'b : Int Int -> std.BigInt -> std.BigInt = { - ?? 'b ==. 'a + 1 -> return std.BigInt.of 1 & std.BigInt.of 'b; + ?? 'b ==. 'a + 1 => return std.BigInt.of 1 & std.BigInt.of 'b; %mid := 'a + 'b /. 2; %p_left & %q_left := sum_terms 'a mid; @@ -38,20 +38,20 @@ sum_terms 'a 'b : Int Int -> std.BigInt -> std.BigInt = { binary_search 'n : Int -> Int = { %a := 0; %b := 1; - @ not (test_k 'n b) -> { + @ not (test_k 'n b) => { a = b; b *= 2; }; - @ b - a >. 1 -> { + @ b - a >. 1 => { %m := a + b /. 2; - ?? test_k 'n m -> b = m !!-> a = m; + ?? test_k 'n m => b = m !!=> a = m; }; return b; } test_k 'n 'k : Int Int -> Bool = { - ?? k < 0 -> return false; + ?? k < 0 => return false; %ln_k_factorial := k * (math.log k - 1) +. 0.5 * math.log math.tau; %log_10_k_factorial := ln_k_factorial / math.ln10; @@ -83,7 +83,7 @@ test_k 'n 'k : Int Int -> Bool = { (operator) (number_literal)) (name_expression - (reference + (reference_expression (array_access (simple_name_identifier) (number_literal))) diff --git a/corpus/test.langexp b/corpus/test.langexp index f4e0d7e..d878682 100644 --- a/corpus/test.langexp +++ b/corpus/test.langexp @@ -10,32 +10,33 @@ Test :: module_namespace = module; func = { - @-> { + + @=> { %x := scan; - ?? x == ''x'' -> break; + ?? x == ''x'' => break; }; - @ i < 10 -> { + @ i < 10 => { inc i; }; - @ %x : 1..10 -> { + @ %x : 1..10 => { print "Hello World!\n"; }; ?? abracadabbra < abracadabra_abracadabra || some_long_name == another_long_name - &&. abracadabra-abracadabra < long_long_long_long_name -> io.print x - !! x < 0 -> { + &&. abracadabra-abracadabra < long_long_long_long_name => io.print x + !! x < 0 => { x += 1; io.print y; - } !!-> return (); + } !!=> return (); } : example of function with optional arguments (without type annotation) : real type is 'A? 'A? -> 'A? sum 'a? 'b? = - 'a & 'b =: %a? & %b? -> a + b - =: _ -> null; + 'a & 'b =: %a? & %b? => a + b + =: _ => null; : example that shows that default annotations are argument names (without ') @@ -49,34 +50,34 @@ sum 'a 'b = 'a + 'b; @n is position in Fibonacci sequence ? 'n >= 0; fib @n 'n : Int -> Int = - 'n =: 0 | 1 -> 1 - =: _ -> fib ('n - 1) + fib 'n; + 'n =: 0 | 1 => 1 + =: _ => fib ('n - 1) + fib 'n; func_2 = { %variant := x; %val | %err := f x; - %lambda1 := \'x 'y -> 'x + 'y; + %lambda1 := \'x 'y => 'x + 'y; - %lambda2 := \ -> 3; + %lambda2 := \ => 3; - variant =: 1 | 2 -> "a" - =: 3..10 -> "b" - =: 45 | 55 | x ?? x > 100 -> "c" - =: _ -> "another variants"; + variant =: 1 | 2 => "a" + =: 3..10 => "b" + =: 45 | 55 | x ?? x > 100 => "c" + =: _ => "another variants"; // all var arrays are dynamic $array := [[x y z]]; array.push a; - %x := maybe_something -> do_something - !!-> do_something_another; + %x := maybe_something => do_something + := _ => do_something_another; %x := Task @name "do something" @duration 123.1; // open optional: execute expression only if not null - %x? := maybe_something -> do_something; + %x? := maybe_something => do_something; // open optional: return null to all outputs (all outputs should be optional values) %x? := maybe_something; @@ -95,9 +96,9 @@ func_2 = { %y := Fruit @apple (); - y =: Fruit @apple () -> "apple" - =: Fruit @orange () -> "orange" - =: Fruit @banana () -> "banana"; + y =: Fruit @apple () => "apple" + =: Fruit @orange () => "orange" + =: Fruit @banana () => "banana"; %z := ( + ) 1 2; @@ -131,9 +132,9 @@ Fruit = @apple Unit : function that takes array reference argument bubble_sort 'arr : <> Array['A] = { swap_occured := true; - @ swap_occured -> { + @ swap_occured => { swap_occured = false; - @ %i : 0 .. 'arr.size -> (?? 'arr[i] > 'arr[i + 1] -> swap 'arr[i] 'arr[i + 1], swap_occured = true); + @ %i : 0 .. 'arr.size => (?? 'arr[i] > 'arr[i + 1] => swap 'arr[i] 'arr[i + 1], swap_occured = true); }; } @@ -484,12 +485,12 @@ arg_deduction_example 'name 'duration : <- String <- Float -> Task = Task 'name (case (name_expression (simple_name_identifier)) - (operator_expression - (name_expression - (simple_name_identifier)) - (operator) - (name_expression - (simple_name_identifier))))) + (name_expression + (simple_name_identifier))) + (case + (placeholder) + (name_expression + (simple_name_identifier)))) (match (name_definition (simple_name_identifier)) @@ -910,7 +911,7 @@ arg_deduction_example 'name 'duration : <- String <- Float -> Task = Task 'name (name_definition (simple_name_identifier)) (case - (reference + (reference_expression (array_access (simple_name_identifier) (number_literal))))))) @@ -941,19 +942,19 @@ arg_deduction_example 'name 'duration : <- String <- Float -> Task = Task 'name (name_definition (simple_name_identifier)) (case - (reference + (reference_expression (argument_name_identifier)))) (match (name_expression (argument_name_identifier)) (case - (reference + (reference_expression (argument_name_identifier))))) (match (name_expression (argument_name_identifier)) (case - (reference + (reference_expression (simple_name_identifier)))))) (function_definition (definition_info) @@ -966,19 +967,19 @@ arg_deduction_example 'name 'duration : <- String <- Float -> Task = Task 'name (name_definition (simple_name_identifier)) (case - (reference + (reference_expression (argument_name_identifier)))) (match (name_expression (argument_name_identifier)) (case - (reference + (reference_expression (argument_name_identifier))))) (match (name_expression (argument_name_identifier)) (case - (reference + (reference_expression (simple_name_identifier)))))) (function_definition (definition_info) diff --git a/grammar.g4 b/grammar.g4 index 588f6b0..9d3263d 100644 --- a/grammar.g4 +++ b/grammar.g4 @@ -24,8 +24,8 @@ type_definition: (DEFINITION_INFO)? (ANNOTATION_INFO)* ('^')? function_definition: (definietion_info)? (ANNOTATION_INFO)* (constraint ';')* (('%' | 'let') | ('$' | 'var'))? (SIMPLE_NAME_IDENTIFIER | ('(' OPERATOR ')')) - ((ANNOTATION_IDENTIFIER)? ARGUMENT_NAME_IDENTIFIER ('?')?)* - (':' ((ANNOTATION_IDENTIFIER)? ('->' | 'in') | ('<-' | 'out') | ('<>' | 'ref'))? type)+)? + ((ANNOTATION_IDENTIFIER)? (('->' | 'in') | ('<-' | 'out') | ('<>' | 'ref')) ARGUMENT_NAME_IDENTIFIER ('?')?)* + (':' ((ANNOTATION_IDENTIFIER)? (('->' | 'in') | ('<-' | 'out') | ('<>' | 'ref')))? type)+)? (('=' ( /*prec 2*/ block | (super_expression ';'))) | ';') ; @@ -34,17 +34,17 @@ typeclass_definition: (DEFINITION_INFO)? (ANNOTATION_INFO)* (('{' (function_definition)* '}') | ';') ; -case: (':=' | '=:') expression (('??' | 'if') expression)? (('->' | 'do') expression)? ; +case: (':=' | '=:') expression (('??' | 'if') expression)? (('=>' | 'do') expression)? ; match: expression (case)+ ; -condition: choice('??' | 'if') expression choice('->' |'do') expression - (('!!' | 'elif') expression ('->' | 'do') expression)* - (('!!->' | 'else') _expression)? +condition: choice('??' | 'if') expression choice('=>' |'do') expression + (('!!' | 'elif') expression ('=>' | 'do') expression)* + (('!!=>' | 'else') _expression)? ; loop: ('@' | 'for') (expression | (expression ':' expression))?, - ('->' | 'do') expression + ('=>' | 'do') expression ; comma_expression: /* prec left ?? */ super_expression ',' super_expression ; @@ -66,7 +66,7 @@ array_access: scoped_expression '[' super_expression ']' ; tuple_access: scoped_expression, '.' NUMBER_LITERAL -reference: /* prec -1 ?? */ (('<>' | 'ref') | ('<-' | 'in')) scoped_expression ; +reference_expression: /* prec -1 ?? */ (('->' | 'in') | ('<-' | 'out') | ('<>' | 'ref')) scoped_expression ; suffix_expression: scoped_expression ('?' | '!') @@ -87,7 +87,7 @@ name_expression: constructor: type (ANNOTATION_IDENTIFIER)? scoped_expression)+ ; -lambda: '\\' (ARGUMENT_NAME_IDENTIFIER)* '->' expression ; +lambda: '\\' (ARGUMENT_NAME_IDENTIFIER)* '=>' expression ; super_expression: match | condition @@ -116,7 +116,7 @@ not_name_scoped_expression: block | array_access | tuple_access | loop_control - | reference + | reference_expression | suffix_expression | literal | '(' super_expression ')' diff --git a/grammar.js b/grammar.js index fbe38db..fd9e903 100644 --- a/grammar.js +++ b/grammar.js @@ -52,17 +52,17 @@ module.exports = grammar({ optional($.definition_info), repeat($.annotation_info), repeat(seq($.constraint, ';')), - /*optional(seq(*/optional(choice(choice('%', 'let'), choice('$', 'var')))/*, '.'))*/, + /*optional(seq(*/optional($._var_let)/*, '.'))*/, choice(field('name', $.simple_name_identifier), seq('(', field('name', $.operator), ')')), repeat(seq( optional($.annotation_identifier), - optional(choice(choice('->', 'out'), choice('<-', 'in'), choice('<>', 'ref'))), + optional($._reference), $.argument_name_identifier, optional('?'), )), optional(seq(':', repeat1(seq( optional($.annotation_identifier), - optional(choice(choice('->', 'out'), choice('<-', 'in'), choice('<>', 'ref'))), + optional($._reference), $.type, )))), choice(seq('=', choice(prec(2, $.block), seq($._super_expression, ';'))), ';'), @@ -82,7 +82,7 @@ module.exports = grammar({ choice(':=', '=:'), $._expression, optional(seq(choice('??', 'if'), $._expression)), - optional(seq(choice('->', 'do'), $._expression)), + optional(seq($._do, $._expression)), ), match: $ => seq( @@ -93,15 +93,15 @@ module.exports = grammar({ condition: $ => seq( choice('??', 'if'), $._expression, - choice('->', 'do'), + $._do, $._expression, repeat(seq( choice('!!', 'elif'), $._expression, - choice('->', 'do'), + $._do, $._expression, )), - optional(seq(choice('!!->', 'else'), $._expression)), + optional(seq(choice('!!=>', 'else'), $._expression)), ), loop: $ => seq( @@ -110,7 +110,7 @@ module.exports = grammar({ field('condition', $._expression), seq(field('variable', $._expression), ':', field('interval', $._expression)), )), - choice('->', 'do'), + $._do, field('expression', $._expression), ), @@ -136,7 +136,7 @@ module.exports = grammar({ return: $ => seq(choice('return', 'bring'), field('value', $._expression)), name_definition: $ => seq( - choice(choice('%', 'let'), choice('$', 'var')), + $._var_let, choice($.simple_name_identifier, $.placeholder), ), @@ -146,7 +146,7 @@ module.exports = grammar({ loop_control: $ => choice('break', 'continue'), - reference: $ => prec(-1, seq(choice(choice('<>', 'ref'), choice('<-', 'in')), $._scoped_expression)), + reference_expression: $ => prec(-1, seq($._reference, $._scoped_expression)), suffix_expression: $ => seq($._scoped_expression, choice('?', '!')), @@ -168,9 +168,9 @@ module.exports = grammar({ ), lambda: $ => seq( - '\\', + choice('\\', 'lambda'), repeat($.argument_name_identifier), - '->', + $._do, $._expression, ), @@ -206,7 +206,7 @@ module.exports = grammar({ $.array_access, $.tuple_access, $.loop_control, - $.reference, + $.reference_expression, $.suffix_expression, $._literal, seq('(', $._super_expression, ')'), @@ -245,6 +245,10 @@ module.exports = grammar({ // --- tokens + _do: $ => choice('=>', 'do'), + _var_let: $ => choice(choice('%', 'let'), choice('$', 'var')), + _reference: $ => choice(choice('->', 'out'), choice('<-', 'in'), choice('<>', 'ref')), + _name_identifier: $ => choice($.argument_name_identifier, $.simple_name_identifier), _type_identifier: $ => choice($.argument_type_identifier, $.simple_type_identifier),