From 36f04713bde2d34185fb3cc581ee7f037f4c9fb3 Mon Sep 17 00:00:00 2001 From: Chuck Smith Date: Thu, 14 Mar 2024 20:11:29 -0400 Subject: [PATCH] fibonacci --- main.go | 76 ++++++++++++++++++++++++++++++++++++++++++++------- vm/vm_test.go | 24 ++++++++++++++++ 2 files changed, 90 insertions(+), 10 deletions(-) diff --git a/main.go b/main.go index 830498c..86255a6 100644 --- a/main.go +++ b/main.go @@ -1,19 +1,75 @@ package main import ( + "flag" "fmt" - "monkey/repl" - "os" - user2 "os/user" + "time" + + "monkey/compiler" + "monkey/evaluator" + "monkey/lexer" + "monkey/object" + "monkey/parser" + "monkey/vm" ) -func main() { - user, err := user2.Current() +var engine = flag.String("engine", "vm", "use 'vm' or 'eval'") - if err != nil { - panic(err) +var input = ` +let fibonacci = fn(x) { + if (x == 0) { + 0 + } else { + if (x == 1) { + return 1; + } else { + fibonacci(x - 1) + fibonacci(x - 2); + } + } +}; +fibonacci(35); +` + +func main() { + flag.Parse() + + var duration time.Duration + var result object.Object + + l := lexer.New(input) + p := parser.New(l) + program := p.ParseProgram() + + if *engine == "vm" { + comp := compiler.New() + err := comp.Compile(program) + if err != nil { + fmt.Printf("compiler error: %s", err) + return + } + + machine := vm.New(comp.Bytecode()) + + start := time.Now() + + err = machine.Run() + if err != nil { + fmt.Printf("vm error: %s", err) + return + } + + duration = time.Since(start) + result = machine.LastPoppedStackElem() + } else { + env := object.NewEnvironment() + start := time.Now() + result = evaluator.Eval(program, env) + duration = time.Since(start) } - fmt.Printf("Hello %s! This is the Monkey programmig language!\n", user.Username) - fmt.Printf("Feel free to type in commands\n") - repl.Start(os.Stdin, os.Stdout) + + fmt.Printf( + "engine=%s, result=%s, duration=%s\n", + *engine, + result.Inspect(), + duration) } diff --git a/vm/vm_test.go b/vm/vm_test.go index 395eca4..ce05909 100644 --- a/vm/vm_test.go +++ b/vm/vm_test.go @@ -755,3 +755,27 @@ func TestRecursiveFunctions(t *testing.T) { runVmTests(t, tests) } + +func TestRecursiveFibonacci(t *testing.T) { + tests := []vmTestCase{ + { + input: ` + let fibonacci = fn(x) { + if (x == 0) { + return 0; + } else { + if (x == 1) { + return 1; + } else { + fibonacci(x - 1) + fibonacci(x - 2); + } + } + }; + fibonacci(15); + `, + expected: 610, + }, + } + + runVmTests(t, tests) +}