From 2d9499c0d11853098bb4156379d8c81ebb0819f0 Mon Sep 17 00:00:00 2001 From: Eatswap Date: Tue, 13 Dec 2022 17:53:49 +0800 Subject: [PATCH] fix: return-from --- AST.cpp | 8 ++++++-- AST.h | 9 ++++++++- DragonLispDriver.cpp | 4 ++++ DragonLispDriver.h | 1 + sample.lisp | 18 +++++++++++++++++- 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/AST.cpp b/AST.cpp index 44362e9..11d4b9a 100644 --- a/AST.cpp +++ b/AST.cpp @@ -77,8 +77,12 @@ std::shared_ptr FuncDefAST::eval(Context* parent, std::vector(ptr)->getResult(ctx.get()).get(); if (!ptr) continue; - if (ptr->getType() == T_ReturnAST) - return ptr->eval(ctx.get()); + if (ptr->getType() == T_ReturnAST) { + auto retAST = dynamic_cast(ptr); + if (this->name == retAST->getName()) + return ptr->eval(ctx.get()); + throw std::runtime_error("Return name mismatch. Closure is not implemented yet!"); + } ret = ptr->eval(ctx.get()); } return ret; diff --git a/AST.h b/AST.h index f632e43..3daa2f4 100644 --- a/AST.h +++ b/AST.h @@ -265,12 +265,19 @@ public: class ReturnAST : public ExprAST { private: std::shared_ptr expr; + std::string name; public: - explicit ReturnAST(std::shared_ptr expr) : expr(std::move(expr)) {} + explicit ReturnAST(std::shared_ptr expr) : expr(std::move(expr)), name() {} + + ReturnAST(std::shared_ptr expr, std::string name) : expr(std::move(expr)), name(std::move(name)) {} std::shared_ptr eval(Context* parent) override final; + std::string getName() const { + return name; + } + inline ASTType getType() const override final { return T_ReturnAST; } diff --git a/DragonLispDriver.cpp b/DragonLispDriver.cpp index db59014..2cffaf2 100644 --- a/DragonLispDriver.cpp +++ b/DragonLispDriver.cpp @@ -98,6 +98,10 @@ std::shared_ptr DLDriver::constructReturnAST(std::shared_ptr return std::make_shared(std::move(value)); } +std::shared_ptr DLDriver::constructReturnAST(std::shared_ptr value, std::string name) { + return std::make_shared(std::move(value), std::move(name)); +} + std::shared_ptr DLDriver::constructLoopAST(std::vector> body) { return std::make_shared( std::move(body) diff --git a/DragonLispDriver.h b/DragonLispDriver.h index 4d7e1f5..2247b81 100644 --- a/DragonLispDriver.h +++ b/DragonLispDriver.h @@ -68,6 +68,7 @@ public: // Return AST static std::shared_ptr constructReturnAST(std::shared_ptr value); + static std::shared_ptr constructReturnAST(std::shared_ptr value, std::string name); // Loop AST static std::shared_ptr constructLoopAST(std::vector> body); diff --git a/sample.lisp b/sample.lisp index acbcd3d..2c227d8 100644 --- a/sample.lisp +++ b/sample.lisp @@ -52,7 +52,7 @@ ) ; prints 1 2 3 4 5 6 7 8 9 10 (defvar i 1) -(loop (if (> i 5) (return i)) (incf i 3)) ; returns 7 +(print (loop (if (> i 5) (return i)) (incf i 3))) ; returns 7 (dotimes (i 10) (print i)) ; prints 0 1 2 3 4 5 6 7 8 9 @@ -62,3 +62,19 @@ (DoTiMeS (i (+ 99999 -99989)) (print i) (setf (aref arr i) (* i i i))) ; prints 0 1 2 3 4 5 6 7 8 9 (dOtImEs (i 10) (print (aref arr i))) ; prints 0 1 8 27 64 125 216 343 512 729 + +(defvar dp (make-array 90)) +(loop for i from 0 to 89 do (setf (aref dp i) -1)) + +(defun fibFast (n) + (if (>= n 90) (return-from fibFast "I can't handle this number!")) + (if (>= (aref dp n) 0) (return-from fibFast (aref dp n))) + (if (<= n 1) (return-from fibFast 1)) + (setf (aref dp n) (+ (fibFast (- n 1)) (fibFast (- n 2)))) +) + +; This is a dynamic programming function, +; still recursive, but with a memoization table. +; O(n) time complexity. +(print (fibFast 8)) ; prints 34 +(print (fibFast 80)) ; prints 37889062373143906