Parcourir la source

Allow top-level function expressions

master
Dylan Baker il y a 5 ans
Parent
révision
25152d67de
3 fichiers modifiés avec 70 ajouts et 4 suppressions
  1. 7
    0
      lib/ahem/lexer.rb
  2. 13
    4
      lib/ahem/parser.rb
  3. 50
    0
      spec/parser_spec.rb

+ 7
- 0
lib/ahem/lexer.rb Voir le fichier

@@ -174,6 +174,13 @@ class Lexer
174 174
     end
175 175
   end
176 176
 
177
+  def peek
178
+    position = @position
179
+    token = get_token
180
+    @position = position
181
+    token
182
+  end
183
+
177 184
   def scan_all
178 185
     tokens = Array.new
179 186
     until at_end

+ 13
- 4
lib/ahem/parser.rb Voir le fichier

@@ -18,18 +18,27 @@ class Parser
18 18
     elsif @current_token.type == TokenKinds::LET
19 19
       variable_declaration
20 20
     elsif @current_token.type == TokenKinds::FUNCTION
21
-      function_definition
21
+      next_token = @lexer.peek
22
+      if next_token && next_token.type == TokenKinds::IDENTIFIER
23
+				function_definition
24
+      else
25
+				expression_statement
26
+      end
22 27
     elsif @current_token.type == TokenKinds::CLASS
23 28
       class_definition
24 29
     elsif @current_token.type == TokenKinds::FOR
25 30
       for_loop
26 31
     else
27
-      expr = expression
28
-      eat(TokenKinds::SEMICOLON)
29
-      expr
32
+			expression_statement
30 33
     end
31 34
   end
32 35
 
36
+	def expression_statement
37
+    expr = expression
38
+    eat(TokenKinds::SEMICOLON)
39
+    return expr
40
+	end
41
+
33 42
   def variable_declaration
34 43
     eat(TokenKinds::LET)
35 44
     name = identifier

+ 50
- 0
spec/parser_spec.rb Voir le fichier

@@ -402,4 +402,54 @@ RSpec.describe Parser do
402 402
       ]
403 403
     )
404 404
   end
405
+
406
+  it 'allows returning an anonymous function from another function' do
407
+    expect(parse('function outer() { function() { print("Hello world"); }; }')).to eq(
408
+      [
409
+        AST::FunctionDefinition.new(
410
+          AST::Identifier.new('outer'),
411
+          [],
412
+          AST::Block.new(
413
+            [
414
+              AST::FunctionDefinition.new(
415
+                nil,
416
+                [],
417
+                AST::Block.new(
418
+                  [
419
+                    AST::FunctionCall.new(
420
+                      AST::Identifier.new('print'),
421
+                      [
422
+                        AST::String.new('Hello world')
423
+                      ]
424
+                    )
425
+                  ]
426
+                )
427
+              )
428
+            ]
429
+          )
430
+        )
431
+      ]
432
+    )
433
+  end
434
+
435
+	it 'allows toplevel function expressions' do
436
+    expect(parse('function() { print("Hello world"); };')).to eq(
437
+      [
438
+        AST::FunctionDefinition.new(
439
+          nil,
440
+          [],
441
+          AST::Block.new(
442
+            [
443
+              AST::FunctionCall.new(
444
+                AST::Identifier.new('print'),
445
+                [
446
+                  AST::String.new('Hello world')
447
+                ]
448
+              )
449
+            ]
450
+          )
451
+        )
452
+      ]
453
+    )
454
+	end
405 455
 end

Chargement…
Annuler
Enregistrer