Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New anonymous function syntax #62

Merged
merged 4 commits into from
Jul 25, 2018
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
4 changes: 2 additions & 2 deletions spec/compilers/component_with_provider
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ provider MouseProvider : MouseProvider.Data {

component Test {
use MouseProvider {
moves = \data : Position => void,
ups = \data : Position => void
moves = (data : Position) : Void => { void },
ups = (data : Position) : Void => { void }
} when {
false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ provider MouseProvider : MouseProvider.Data {

component Test {
use MouseProvider {
moves = \data : Position => void,
ups = \data : Position => void
moves = (data : Position) : Void => { void },
ups = (data : Position) : Void => { void }
} when {
false
}
Expand Down
4 changes: 2 additions & 2 deletions spec/compilers/component_with_provider_and_store
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ store Blah {

component Test {
use MouseProvider {
moves = \data : Position => void,
ups = \data : Position => void
moves = (data : Position) : Void => { void },
ups = (data : Position) : Void => { void }
} when {
false
}
Expand Down
2 changes: 1 addition & 1 deletion spec/compilers/html_attribute_ref
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
component HtmlAttribute {
fun render : Html {
<div ref={\element : Dom.Element => void}>
<div ref={(element : Dom.Element) : Void => { void }}>
</div>
}
}
Expand Down
2 changes: 1 addition & 1 deletion spec/compilers/inline_function
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module A {
fun test : String {
a()
} where {
a = \ => "Hello"
a = () : String => { "Hello" }
}
}
--------------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion spec/compilers/inline_function_with_arguments
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module A {
a("Joe")
} where {
a =
\b : String => b
(b : String) : String => { b }
}
}
--------------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions spec/formatters/inline_function
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module A {
fun test : String {
a()
} where {
a = \=>"Hello"
a = ():String=>{"Hello"}
}
}
--------------------------------------------------------------------------------
Expand All @@ -11,6 +11,6 @@ module A {
a()
} where {
a =
\ => "Hello"
() : String => { "Hello" }
}
}
5 changes: 3 additions & 2 deletions spec/formatters/inline_function_multiline
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module A {
fun test : String {
result.name
} where {
a = \name:String,age:Number=> {name = name, age = age}
a = (name:String,age:Number):X=>{{name = name, age = age}}

result =
a("Joe", 25)
Expand All @@ -24,11 +24,12 @@ module A {
result.name
} where {
a =
\name : String, age : Number =>
(name : String, age : Number) : X => {
{
name = name,
age = age
}
}

result =
a("Joe", 25)
Expand Down
5 changes: 3 additions & 2 deletions spec/formatters/inline_function_with_comments
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module A {
fun test : String {
a()
} where {
a = \=>/*A*/"Hello"/*B*/
a = ():String=>{/*A*/"Hello"/*B*/}
}
}
--------------------------------------------------------------------------------
Expand All @@ -11,10 +11,11 @@ module A {
a()
} where {
a =
\ =>
() : String => {
/* A */
"Hello"

/* B */
}
}
}
14 changes: 9 additions & 5 deletions spec/parsers/inline_function_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ describe "Inline Function" do
expect_ignore "::"
expect_ignore "asd"

expect_error "\\", Mint::Parser::InlineFunctionExpectedArrow
expect_error "\\a : Event ", Mint::Parser::InlineFunctionExpectedArrow
expect_error "\\a : Event =>", Mint::Parser::InlineFunctionExpectedExpression
expect_error "\\a : Event => ", Mint::Parser::InlineFunctionExpectedExpression
expect_error "(", Mint::Parser::InlineFunctionExpectedClosingParentheses
expect_error "(a : Event ", Mint::Parser::InlineFunctionExpectedClosingParentheses
expect_error "(a : Event)", Mint::Parser::InlineFunctionExpectedColon
expect_error "(a : Event) :", Mint::Parser::InlineFunctionExpectedType
expect_error "(a : Event) : X", Mint::Parser::InlineFunctionExpectedArrow
expect_error "(a : Event) : X =>", Mint::Parser::InlineFunctionExpectedOpeningBracket
expect_error "(a : Event) : X => {", Mint::Parser::InlineFunctionExpectedExpression
expect_error "(a : Event) : X => { b ", Mint::Parser::InlineFunctionExpectedClosingBracket

expect_ok "\\a : Event => b"
expect_ok "(a : Event) : X => { b }"
end
2 changes: 1 addition & 1 deletion spec/type_checking/html_attribute_event
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
component Test {
fun render : Html {
<div onClick={\event : Html.Event => void}/>
<div onClick={(event : Html.Event) : Void => { void }}/>
}
}
---------------------------------------HtmlAttributeElementAttributeTypeMismatch
Expand Down
2 changes: 1 addition & 1 deletion spec/type_checking/html_attribute_ref
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
component Test {
fun render : Html {
<div ref={\element : Dom.Element => void}/>
<div ref={(element : Dom.Element) : Void => { void }}/>
}
}
---------------------------------------HtmlAttributeElementAttributeTypeMismatch
Expand Down
12 changes: 10 additions & 2 deletions spec/type_checking/inline_function
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,22 @@ module A {
fun test : String {
a()
} where {
a = \ => "Hello"
a = () : String => { "Hello" }
}
}
------------------------------------------------------------FunctionTypeMismatch
module A {
fun test : String {
a()
} where {
a = \ => true
a = () : Bool => { true }
}
}
------------------------------------------------------InlineFunctionTypeMismatch
module A {
fun test : String {
a()
} where {
a = () : String => { true }
}
}
3 changes: 2 additions & 1 deletion src/ast/inline_function.cr
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
module Mint
class Ast
class InlineFunction < Node
getter body, arguments, head_comments, tail_comments
getter body, arguments, head_comments, tail_comments, type

def initialize(@head_comments : Array(Comment),
@tail_comments : Array(Comment),
@arguments : Array(Argument),
@body : Expression,
@input : Data,
@from : Int32,
@type : Type,
@to : Int32)
end
end
Expand Down
7 changes: 5 additions & 2 deletions src/formatters/inline_function.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ module Mint
arguments =
format node.arguments, ", "

type =
format node.type

if body.includes?("\n")
"\\#{arguments} =>\n#{body.indent}"
"(#{arguments}) : #{type} => {\n#{body.indent}\n}"
else
"\\#{arguments} => #{body}"
"(#{arguments}) : #{type} => { #{body} }"
end
end
end
Expand Down
7 changes: 7 additions & 0 deletions src/messages/inline_function_expected_closing_bracket.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
message InlineFunctionExpectedClosingBracket do
title "Syntax Error"

closing_bracket "anonymous function", got

snippet node
end
15 changes: 15 additions & 0 deletions src/messages/inline_function_expected_closing_parentheses.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
message InlineFunctionExpectedClosingParentheses do
title "Syntax Error"

block do
text "The"
bold "arguments"
text "of an"
bold "anonymous function"
text "must be enclosed by parenthesis."
end

was_looking_for "closing parenthesis", got, ")"

snippet node
end
19 changes: 19 additions & 0 deletions src/messages/inline_function_expected_colon.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
message InlineFunctionExpectedColon do
title "Syntax Error"

block do
text "The"
bold "body"
text "of an"
bold "anonymous function"
text "and it's"
bold "return type"
text "must be separated by a"
bold "colon"
code ":"
end

was_looking_for "colon", got, ":"

snippet node
end
7 changes: 7 additions & 0 deletions src/messages/inline_function_expected_opening_bracket.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
message InlineFunctionExpectedOpeningBracket do
title "Syntax Error"

opening_bracket "anonymous function", got

snippet node
end
13 changes: 13 additions & 0 deletions src/messages/inline_function_expected_type.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
message InlineFunctionExpectedType do
title "Syntax Error"

block do
text "The return type of an"
bold "anonymous function"
text "must be defined."
end

was_looking_for "return type", got

snippet node
end
11 changes: 11 additions & 0 deletions src/messages/inline_function_type_mismatch.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
message InlineFunctionTypeMismatch do
title "Type Error"

block do
text "The return type of an anonymous function does not match it's type definition."
end

was_expecting_type expected, got

snippet node
end
3 changes: 3 additions & 0 deletions src/parser.cr
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ module Mint
rescue SkipError
@position = start_position
nil
rescue error : Error
@position = start_position
raise error
end
end

Expand Down
13 changes: 11 additions & 2 deletions src/parsers/basic_expression.cr
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,25 @@ module Mint
do_expression ||
try_expression ||
case_expression ||
inline_function ||
function_call ||
parenthesized_expression ||
inline_function_or_parenthesized_expression ||
negated_expression ||
enum_id ||
js ||
void ||
variable
end

def inline_function_or_parenthesized_expression : Ast::InlineFunction | Ast::ParenthesizedExpression | Nil
parenthesized_expression
rescue error1
begin
inline_function
rescue error2
raise error1
end
end

def basic_expression!(error : SyntaxError.class) : Ast::Expression
raise error unless exp = basic_expression
exp
Expand Down
28 changes: 22 additions & 6 deletions src/parsers/inline_function.cr
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
module Mint
class Parser
syntax_error InlineFunctionExpectedClosingParentheses
syntax_error InlineFunctionExpectedOpeningBracket
syntax_error InlineFunctionExpectedClosingBracket
syntax_error InlineFunctionExpectedExpression
syntax_error InlineFunctionExpectedArrow
syntax_error InlineFunctionExpectedColon
syntax_error InlineFunctionExpectedType

def inline_function : Ast::InlineFunction | Nil
start do |start_position|
skip unless char! '\\'
skip unless char! '('

whitespace

Expand All @@ -14,15 +19,25 @@ module Mint
separator: ','
) { argument }.compact

char ')', InlineFunctionExpectedClosingParentheses

whitespace
keyword! "=>", InlineFunctionExpectedArrow
char ':', InlineFunctionExpectedColon
whitespace

head_comments = many { comment }.compact
type = type! InlineFunctionExpectedType

body = expression! InlineFunctionExpectedExpression
whitespace
keyword! "=>", InlineFunctionExpectedArrow
whitespace

tail_comments = many { comment }.compact
head_comments, body, tail_comments =
block_with_comments(
opening_bracket: InlineFunctionExpectedOpeningBracket,
closing_bracket: InlineFunctionExpectedClosingBracket
) do
expression! InlineFunctionExpectedExpression
end

Ast::InlineFunction.new(
body: body.as(Ast::Expression),
Expand All @@ -31,7 +46,8 @@ module Mint
arguments: arguments,
from: start_position,
to: position,
input: data)
input: data,
type: type)
end
end
end
Expand Down
Loading