diff options
-rw-r--r-- | ast.cc | 4 | ||||
-rw-r--r-- | ast.h | 1 | ||||
-rw-r--r-- | eval.cc | 6 | ||||
-rw-r--r-- | exec.cc | 5 | ||||
-rw-r--r-- | func.cc | 6 | ||||
-rw-r--r-- | main.cc | 3 | ||||
-rw-r--r-- | parser.cc | 2 | ||||
-rw-r--r-- | testcase/value.mk | 6 | ||||
-rw-r--r-- | var.cc | 16 | ||||
-rw-r--r-- | var.h | 11 |
10 files changed, 50 insertions, 10 deletions
@@ -30,9 +30,11 @@ string AssignAST::DebugString() const { case AssignDirective::OVERRIDE: dirstr = "override"; break; case AssignDirective::EXPORT: dirstr = "export"; break; } - return StringPrintf("AssignAST(lhs=%s rhs=%s opstr=%s dir=%s loc=%s:%d)", + return StringPrintf("AssignAST(lhs=%s rhs=%s (%s) " + "opstr=%s dir=%s loc=%s:%d)", lhs->DebugString().c_str(), rhs->DebugString().c_str(), + orig_rhs.as_string().c_str(), opstr, dirstr, LOCF(loc())); } @@ -67,6 +67,7 @@ struct RuleAST : public AST { struct AssignAST : public AST { Value* lhs; Value* rhs; + StringPiece orig_rhs; AssignOp op; AssignDirective directive; @@ -45,12 +45,12 @@ void Evaluator::EvalAssign(const AssignAST* ast) { rhs = new SimpleVar(ast->rhs->Eval(this), origin); break; case AssignOp::EQ: - rhs = new RecursiveVar(ast->rhs, origin); + rhs = new RecursiveVar(ast->rhs, origin, ast->orig_rhs); break; case AssignOp::PLUS_EQ: { Var* prev = LookupVarInCurrentScope(lhs); if (!prev->IsDefined()) { - rhs = new RecursiveVar(ast->rhs, origin); + rhs = new RecursiveVar(ast->rhs, origin, ast->orig_rhs); } else { prev->AppendVar(this, ast->rhs); rhs = prev; @@ -61,7 +61,7 @@ void Evaluator::EvalAssign(const AssignAST* ast) { case AssignOp::QUESTION_EQ: { Var* prev = LookupVarInCurrentScope(lhs); if (!prev->IsDefined()) { - rhs = new RecursiveVar(ast->rhs, origin); + rhs = new RecursiveVar(ast->rhs, origin, ast->orig_rhs); } else { rhs = prev; needs_assign = false; @@ -34,6 +34,11 @@ class AutoVar : public Var { virtual bool IsDefined() const override { CHECK(false); } virtual void AppendVar(Evaluator*, Value*) override { CHECK(false); } + virtual StringPiece String() const override { + ERROR("$(value %s) is not implemented yet", sym_); + return ""; + } + virtual string DebugString() const override { return string("AutoVar(") + sym_ + ")"; } @@ -352,8 +352,10 @@ void OrFunc(const vector<Value*>& args, Evaluator* ev, string* s) { } } -void ValueFunc(const vector<Value*>&, Evaluator*, string*) { - printf("TODO(value)"); +void ValueFunc(const vector<Value*>& args, Evaluator* ev, string* s) { + shared_ptr<string> var_name = args[0]->Eval(ev); + Var* var = ev->LookupVar(*var_name); + AppendString(var->String().as_string(), s); } void EvalFunc(const vector<Value*>& args, Evaluator* ev, string*) { @@ -103,7 +103,8 @@ static void SetVar(StringPiece l, const char* origin, Vars* vars) { CHECK(found != string::npos); StringPiece lhs = Intern(l.substr(0, found)); StringPiece rhs = l.substr(found + 1); - vars->Assign(lhs, new RecursiveVar(NewLiteral(rhs.data()), origin)); + vars->Assign(lhs, + new RecursiveVar(NewLiteral(rhs.data()), origin, rhs.data())); } extern "C" char** environ; @@ -197,6 +197,7 @@ class Parser { ast->set_loc(loc_); ast->lhs = ParseExpr(lhs); ast->rhs = ParseExpr(rhs); + ast->orig_rhs = rhs; ast->op = op; ast->directive = AssignDirective::NONE; out_asts_->push_back(ast); @@ -241,6 +242,7 @@ class Parser { if (define_start_) rhs = TrimRightSpace(buf_.substr(define_start_, l_ - define_start_)); ast->rhs = ParseExpr(rhs, ParseExprOpt::DEFINE); + ast->orig_rhs = rhs; ast->op = AssignOp::EQ; ast->directive = AssignDirective::NONE; out_asts_->push_back(ast); diff --git a/testcase/value.mk b/testcase/value.mk index 3a7a093..fe3c8c1 100644 --- a/testcase/value.mk +++ b/testcase/value.mk @@ -7,6 +7,8 @@ $(FOO_COMMA_BAR):=$PATH FOOREF := FOO +X=$(X) + test: echo $(FOO) echo $(value FOO) @@ -14,3 +16,7 @@ test: echo $(value FOO,BAR) # TODO: Fix # echo $(value $(FOOREF)) +# echo $(value @) + +# TODO(go): Fix +# $(info $(value X)) @@ -31,12 +31,16 @@ void SimpleVar::AppendVar(Evaluator* ev, Value* v) { v_ = s; } +StringPiece SimpleVar::String() const { + return *v_; +} + string SimpleVar::DebugString() const { return *v_; } -RecursiveVar::RecursiveVar(Value* v, const char* origin) - : v_(v), origin_(origin) { +RecursiveVar::RecursiveVar(Value* v, const char* origin, StringPiece orig) + : v_(v), origin_(origin), orig_(orig) { } void RecursiveVar::Eval(Evaluator* ev, string* s) const { @@ -47,6 +51,10 @@ void RecursiveVar::AppendVar(Evaluator*, Value* v) { v_ = NewExpr3(v_, NewLiteral(" "), v); } +StringPiece RecursiveVar::String() const { + return orig_; +} + string RecursiveVar::DebugString() const { return v_->DebugString(); } @@ -57,6 +65,10 @@ void UndefinedVar::Eval(Evaluator*, string*) const { // Nothing to do. } +StringPiece UndefinedVar::String() const { + return STRING_PIECE(""); +} + string UndefinedVar::DebugString() const { return "*undefined*"; } @@ -23,6 +23,8 @@ class Var : public Evaluable { virtual void AppendVar(Evaluator* ev, Value* v); + virtual StringPiece String() const = 0; + virtual string DebugString() const = 0; protected: @@ -47,6 +49,8 @@ class SimpleVar : public Var { virtual void AppendVar(Evaluator* ev, Value* v); + virtual StringPiece String() const override; + virtual string DebugString() const override; private: @@ -56,7 +60,7 @@ class SimpleVar : public Var { class RecursiveVar : public Var { public: - RecursiveVar(Value* v, const char* origin); + RecursiveVar(Value* v, const char* origin, StringPiece orig); virtual const char* Flavor() const { return "recursive"; @@ -69,11 +73,14 @@ class RecursiveVar : public Var { virtual void AppendVar(Evaluator* ev, Value* v); + virtual StringPiece String() const override; + virtual string DebugString() const override; private: Value* v_; const char* origin_; + StringPiece orig_; }; class UndefinedVar : public Var { @@ -90,6 +97,8 @@ class UndefinedVar : public Var { virtual void Eval(Evaluator* ev, string* s) const override; + virtual StringPiece String() const override; + virtual string DebugString() const override; }; |