Bläddra i källkod

Adding Function compiler

simon 3 år sedan
förälder
incheckning
e950063c58
2 ändrade filer med 44 tillägg och 0 borttagningar
  1. 6 0
      compiler/compiler.go
  2. 38 0
      compiler/compiler_test.go

+ 6 - 0
compiler/compiler.go

@@ -258,6 +258,12 @@ func (c *Compiler) Compile(node ast.Node) error {
 
 		compiledFn := &object.CompileFunction{Instructions: instructions}
 		c.emit(code.OpConstant, c.addConstant(compiledFn))
+	case *ast.CallExpression:
+		err := c.Compile(node.Function)
+		if err != nil {
+			return err
+		}
+		c.emit(code.OpCall)
 	}
 	return nil
 }

+ 38 - 0
compiler/compiler_test.go

@@ -528,6 +528,44 @@ func TestFunctionWithoutReturnValue(t *testing.T) {
 	runCompilerTests(t, tests)
 }
 
+func TestFunctionCalls(t *testing.T) {
+	tests := []compilerTestCase{
+		{
+			input: `fn () { 24 } ()`,
+			expectedConstants: []interface{}{
+				24,
+				[]code.Instructions{
+					code.Make(code.OpConstant, 0), // The literal "24"
+					code.Make(code.OpReturnValue),
+				},
+			},
+			expectedInstructions: []code.Instructions{
+				code.Make(code.OpConstant, 1), // The compiled function
+				code.Make(code.OpCall),
+				code.Make(code.OpPop),
+			},
+		},
+		{
+			input: `let noArg = fn(){24};noArg();`,
+			expectedConstants: []interface{}{
+				24,
+				[]code.Instructions{
+					code.Make(code.OpConstant, 0),
+					code.Make(code.OpReturnValue)},
+			},
+			expectedInstructions: []code.Instructions{
+				code.Make(code.OpConstant, 1), // The compiled function
+				code.Make(code.OpSetGlobal, 0),
+				code.Make(code.OpGetGlobal, 0),
+				code.Make(code.OpCall),
+				code.Make(code.OpPop),
+			},
+		},
+	}
+
+	runCompilerTests(t, tests)
+}
+
 func runCompilerTests(t *testing.T, tests []compilerTestCase) {
 	t.Helper()