fix: return-from

This commit is contained in:
Eatswap 2022-12-13 17:53:49 +08:00
parent 6787722945
commit 2d9499c0d1
Signed by: Eatswap
GPG Key ID: BE661106A1F3FA0B
5 changed files with 36 additions and 4 deletions

View File

@ -77,8 +77,12 @@ std::shared_ptr<Value> FuncDefAST::eval(Context* parent, std::vector<std::shared
ptr = dynamic_cast<IfAST*>(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<ReturnAST*>(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;

9
AST.h
View File

@ -265,12 +265,19 @@ public:
class ReturnAST : public ExprAST {
private:
std::shared_ptr<ExprAST> expr;
std::string name;
public:
explicit ReturnAST(std::shared_ptr<ExprAST> expr) : expr(std::move(expr)) {}
explicit ReturnAST(std::shared_ptr<ExprAST> expr) : expr(std::move(expr)), name() {}
ReturnAST(std::shared_ptr<ExprAST> expr, std::string name) : expr(std::move(expr)), name(std::move(name)) {}
std::shared_ptr<Value> eval(Context* parent) override final;
std::string getName() const {
return name;
}
inline ASTType getType() const override final {
return T_ReturnAST;
}

View File

@ -98,6 +98,10 @@ std::shared_ptr<ReturnAST> DLDriver::constructReturnAST(std::shared_ptr<ExprAST>
return std::make_shared<ReturnAST>(std::move(value));
}
std::shared_ptr <ReturnAST> DLDriver::constructReturnAST(std::shared_ptr <ExprAST> value, std::string name) {
return std::make_shared<ReturnAST>(std::move(value), std::move(name));
}
std::shared_ptr<LoopAST> DLDriver::constructLoopAST(std::vector<std::shared_ptr<ExprAST>> body) {
return std::make_shared<LoopForeverAST>(
std::move(body)

View File

@ -68,6 +68,7 @@ public:
// Return AST
static std::shared_ptr<ReturnAST> constructReturnAST(std::shared_ptr<ExprAST> value);
static std::shared_ptr<ReturnAST> constructReturnAST(std::shared_ptr<ExprAST> value, std::string name);
// Loop AST
static std::shared_ptr<LoopAST> constructLoopAST(std::vector<std::shared_ptr<ExprAST>> body);

View File

@ -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