Added a Location object to ASTNode, to track source code locations

This commit is contained in:
Marius Kintel 2016-06-13 20:20:04 -04:00
parent 0eadffea33
commit b509afd4ed
12 changed files with 157 additions and 133 deletions

View file

@ -239,7 +239,8 @@ HEADERS += src/AST.h \
src/module.h \ src/module.h \
src/UserModule.h src/UserModule.h
SOURCES += src/ModuleInstantiation.cc \ SOURCES += src/AST.cc \
src/ModuleInstantiation.cc \
src/expr.cc \ src/expr.cc \
src/function.cc \ src/function.cc \
src/module.cc \ src/module.cc \

3
src/AST.cc Normal file
View file

@ -0,0 +1,3 @@
#include "AST.h"
Location Location::NONE(0, 0, 0, 0);

View file

@ -1,8 +1,33 @@
#pragma once #pragma once
class Location {
public:
Location(int firstLine, int firstCol, int lastLine, int lastCol)
: first_line(firstLine), first_col(firstCol), last_line(lastLine), last_col(lastCol) {
}
int firstLine() const { return first_line; }
int firstColumn() const { return first_col; }
int lastLine() const { return last_line; }
int lastColumn() const { return last_col; }
static Location NONE;
private:
int first_line;
int first_col;
int last_line;
int last_col;
};
class ASTNode class ASTNode
{ {
public: public:
ASTNode(/* srcref */) {} ASTNode(const Location &loc) : loc(loc) {}
virtual ~ASTNode() {} virtual ~ASTNode() {}
Location location() const { return loc; }
protected:
Location loc;
}; };

View file

@ -10,10 +10,11 @@
class Assignment : public ASTNode class Assignment : public ASTNode
{ {
public: public:
Assignment(std::string name, const Location &loc) : Assignment(name, shared_ptr<class Expression>(), loc) { }
Assignment(std::string name, Assignment(std::string name,
shared_ptr<class Expression> expr = shared_ptr<class Expression>()) shared_ptr<class Expression> expr = shared_ptr<class Expression>(),
: name(name), expr(expr) { const Location &loc = Location::NONE)
} : ASTNode(loc), name(name), expr(expr) { }
std::string name; std::string name;
shared_ptr<class Expression> expr; shared_ptr<class Expression> expr;

View file

@ -9,8 +9,8 @@ typedef std::vector<class ModuleInstantiation*> ModuleInstantiationList;
class ModuleInstantiation : public ASTNode class ModuleInstantiation : public ASTNode
{ {
public: public:
ModuleInstantiation(const std::string &name = "") ModuleInstantiation(const std::string &name = "", const Location &loc = Location::NONE)
: tag_root(false), tag_highlight(false), tag_background(false), modname(name) { } : ASTNode(loc), tag_root(false), tag_highlight(false), tag_background(false), modname(name) { }
virtual ~ModuleInstantiation(); virtual ~ModuleInstantiation();
virtual std::string dump(const std::string &indent) const; virtual std::string dump(const std::string &indent) const;
@ -39,7 +39,7 @@ protected:
class IfElseModuleInstantiation : public ModuleInstantiation { class IfElseModuleInstantiation : public ModuleInstantiation {
public: public:
IfElseModuleInstantiation() : ModuleInstantiation("if") { } IfElseModuleInstantiation(const Location &loc) : ModuleInstantiation("if", loc) { }
virtual ~IfElseModuleInstantiation(); virtual ~IfElseModuleInstantiation();
std::vector<AbstractNode*> instantiateElseChildren(const Context *evalctx) const; std::vector<AbstractNode*> instantiateElseChildren(const Context *evalctx) const;
virtual std::string dump(const std::string &indent) const; virtual std::string dump(const std::string &indent) const;

View file

@ -9,8 +9,8 @@
class UserModule : public AbstractModule, public ASTNode class UserModule : public AbstractModule, public ASTNode
{ {
public: public:
UserModule() { } UserModule(const Location &loc) : ASTNode(loc) { }
UserModule(const class Feature& feature) : AbstractModule(feature) { } UserModule(const class Feature& feature, const Location &loc) : AbstractModule(feature), ASTNode(loc) { }
virtual ~UserModule() {} virtual ~UserModule() {}
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx = NULL) const; virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, EvalContext *evalctx = NULL) const;

View file

@ -30,7 +30,6 @@
#include <assert.h> #include <assert.h>
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include "stl-utils.h"
#include "printutils.h" #include "printutils.h"
#include "stackcheck.h" #include "stackcheck.h"
#include "exceptions.h" #include "exceptions.h"
@ -58,14 +57,6 @@ namespace {
} }
} }
Expression::Expression()
{
}
Expression::~Expression()
{
}
namespace /* anonymous*/ { namespace /* anonymous*/ {
std::ostream &operator << (std::ostream &o, AssignmentList const& l) { std::ostream &operator << (std::ostream &o, AssignmentList const& l) {
@ -85,7 +76,7 @@ bool Expression::isListComprehension() const
return false; return false;
} }
UnaryOp::UnaryOp(UnaryOp::Op op, Expression *expr) : op(op), expr(expr) UnaryOp::UnaryOp(UnaryOp::Op op, Expression *expr, const Location &loc) : Expression(loc), op(op), expr(expr)
{ {
} }
@ -122,8 +113,8 @@ void UnaryOp::print(std::ostream &stream) const
stream << opString() << *this->expr; stream << opString() << *this->expr;
} }
BinaryOp::BinaryOp(Expression *left, BinaryOp::Op op, Expression *right) : BinaryOp::BinaryOp(Expression *left, BinaryOp::Op op, Expression *right, const Location &loc) :
op(op), left(left), right(right) Expression(loc), op(op), left(left), right(right)
{ {
} }
@ -228,8 +219,8 @@ void BinaryOp::print(std::ostream &stream) const
stream << "(" << *this->left << " " << opString() << " " << *this->right << ")"; stream << "(" << *this->left << " " << opString() << " " << *this->right << ")";
} }
TernaryOp::TernaryOp(Expression *cond, Expression *ifexpr, Expression *elseexpr) TernaryOp::TernaryOp(Expression *cond, Expression *ifexpr, Expression *elseexpr, const Location &loc)
: cond(cond), ifexpr(ifexpr), elseexpr(elseexpr) : Expression(loc), cond(cond), ifexpr(ifexpr), elseexpr(elseexpr)
{ {
} }
@ -243,8 +234,8 @@ void TernaryOp::print(std::ostream &stream) const
stream << "(" << *this->cond << " ? " << *this->ifexpr << " : " << *this->elseexpr << ")"; stream << "(" << *this->cond << " ? " << *this->ifexpr << " : " << *this->elseexpr << ")";
} }
ArrayLookup::ArrayLookup(Expression *array, Expression *index) ArrayLookup::ArrayLookup(Expression *array, Expression *index, const Location &loc)
: array(array), index(index) : Expression(loc), array(array), index(index)
{ {
} }
@ -257,7 +248,7 @@ void ArrayLookup::print(std::ostream &stream) const
stream << *array << "[" << *index << "]"; stream << *array << "[" << *index << "]";
} }
Literal::Literal(const ValuePtr &val) : value(val) Literal::Literal(const ValuePtr &val, const Location &loc) : Expression(loc), value(val)
{ {
} }
@ -271,13 +262,13 @@ void Literal::print(std::ostream &stream) const
stream << *this->value; stream << *this->value;
} }
Range::Range(Expression *begin, Expression *end) Range::Range(Expression *begin, Expression *end, const Location &loc)
: begin(begin), end(end) : Expression(loc), begin(begin), end(end)
{ {
} }
Range::Range(Expression *begin, Expression *step, Expression *end) Range::Range(Expression *begin, Expression *step, Expression *end, const Location &loc)
: begin(begin), step(step), end(end) : Expression(loc), begin(begin), step(step), end(end)
{ {
} }
@ -310,7 +301,7 @@ void Range::print(std::ostream &stream) const
stream << "]"; stream << "]";
} }
Vector::Vector() Vector::Vector(const Location &loc) : Expression(loc)
{ {
} }
@ -346,7 +337,7 @@ void Vector::print(std::ostream &stream) const
stream << "]"; stream << "]";
} }
Lookup::Lookup(const std::string &name) : name(name) Lookup::Lookup(const std::string &name, const Location &loc) : Expression(loc), name(name)
{ {
} }
@ -360,8 +351,8 @@ void Lookup::print(std::ostream &stream) const
stream << this->name; stream << this->name;
} }
MemberLookup::MemberLookup(Expression *expr, const std::string &member) MemberLookup::MemberLookup(Expression *expr, const std::string &member, const Location &loc)
: expr(expr), member(member) : Expression(loc), expr(expr), member(member)
{ {
} }
@ -387,8 +378,8 @@ void MemberLookup::print(std::ostream &stream) const
} }
FunctionCall::FunctionCall(const std::string &name, FunctionCall::FunctionCall(const std::string &name,
const AssignmentList &args) const AssignmentList &args, const Location &loc)
: name(name), arguments(args) : Expression(loc), name(name), arguments(args)
{ {
} }
@ -409,8 +400,8 @@ void FunctionCall::print(std::ostream &stream) const
stream << this->name << "(" << this->arguments << ")"; stream << this->name << "(" << this->arguments << ")";
} }
Let::Let(const AssignmentList &args, Expression *expr) Let::Let(const AssignmentList &args, Expression *expr, const Location &loc)
: arguments(args), expr(expr) : Expression(loc), arguments(args), expr(expr)
{ {
} }
@ -427,7 +418,7 @@ void Let::print(std::ostream &stream) const
stream << "let(" << this->arguments << ") " << *expr; stream << "let(" << this->arguments << ") " << *expr;
} }
ListComprehension::ListComprehension() ListComprehension::ListComprehension(const Location &loc) : Expression(loc)
{ {
} }
@ -436,8 +427,8 @@ bool ListComprehension::isListComprehension() const
return true; return true;
} }
LcIf::LcIf(Expression *cond, Expression *ifexpr, Expression *elseexpr) LcIf::LcIf(Expression *cond, Expression *ifexpr, Expression *elseexpr, const Location &loc)
: cond(cond), ifexpr(ifexpr), elseexpr(elseexpr) : ListComprehension(loc), cond(cond), ifexpr(ifexpr), elseexpr(elseexpr)
{ {
} }
@ -469,7 +460,7 @@ void LcIf::print(std::ostream &stream) const
} }
} }
LcEach::LcEach(Expression *expr) : expr(expr) LcEach::LcEach(Expression *expr, const Location &loc) : ListComprehension(loc), expr(expr)
{ {
} }
@ -512,8 +503,8 @@ void LcEach::print(std::ostream &stream) const
stream << "each (" << *this->expr << ")"; stream << "each (" << *this->expr << ")";
} }
LcFor::LcFor(const AssignmentList &args, Expression *expr) LcFor::LcFor(const AssignmentList &args, Expression *expr, const Location &loc)
: arguments(args), expr(expr) : ListComprehension(loc), arguments(args), expr(expr)
{ {
} }
@ -564,8 +555,8 @@ void LcFor::print(std::ostream &stream) const
stream << "for(" << this->arguments << ") (" << *this->expr << ")"; stream << "for(" << this->arguments << ") (" << *this->expr << ")";
} }
LcForC::LcForC(const AssignmentList &args, const AssignmentList &incrargs, Expression *cond, Expression *expr) LcForC::LcForC(const AssignmentList &args, const AssignmentList &incrargs, Expression *cond, Expression *expr, const Location &loc)
: arguments(args), incr_arguments(incrargs), cond(cond), expr(expr) : ListComprehension(loc), arguments(args), incr_arguments(incrargs), cond(cond), expr(expr)
{ {
} }
@ -605,8 +596,8 @@ void LcForC::print(std::ostream &stream) const
<< ") " << *this->expr; << ") " << *this->expr;
} }
LcLet::LcLet(const AssignmentList &args, Expression *expr) LcLet::LcLet(const AssignmentList &args, Expression *expr, const Location &loc)
: arguments(args), expr(expr) : ListComprehension(loc), arguments(args), expr(expr)
{ {
} }

View file

@ -11,8 +11,8 @@
class Expression : public ASTNode class Expression : public ASTNode
{ {
public: public:
Expression(); Expression(const Location &loc) : ASTNode(loc) {}
virtual ~Expression(); virtual ~Expression() {}
virtual bool isListComprehension() const; virtual bool isListComprehension() const;
virtual ValuePtr evaluate(const class Context *context) const = 0; virtual ValuePtr evaluate(const class Context *context) const = 0;
@ -29,7 +29,7 @@ public:
Negate Negate
}; };
UnaryOp(Op op, Expression *expr); UnaryOp(Op op, Expression *expr, const Location &loc);
virtual ValuePtr evaluate(const class Context *context) const; virtual ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
@ -59,7 +59,7 @@ public:
NotEqual NotEqual
}; };
BinaryOp(Expression *left, Op op, Expression *right); BinaryOp(Expression *left, Op op, Expression *right, const Location &loc);
virtual ValuePtr evaluate(const class Context *context) const; virtual ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
@ -74,7 +74,7 @@ private:
class TernaryOp : public Expression class TernaryOp : public Expression
{ {
public: public:
TernaryOp(Expression *cond, Expression *ifexpr, Expression *elseexpr); TernaryOp(Expression *cond, Expression *ifexpr, Expression *elseexpr, const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
@ -86,7 +86,7 @@ public:
class ArrayLookup : public Expression class ArrayLookup : public Expression
{ {
public: public:
ArrayLookup(Expression *array, Expression *index); ArrayLookup(Expression *array, Expression *index, const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private: private:
@ -97,7 +97,7 @@ private:
class Literal : public Expression class Literal : public Expression
{ {
public: public:
Literal(const ValuePtr &val); Literal(const ValuePtr &val, const Location &loc = Location::NONE);
ValuePtr evaluate(const class Context *) const; ValuePtr evaluate(const class Context *) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private: private:
@ -107,8 +107,8 @@ private:
class Range : public Expression class Range : public Expression
{ {
public: public:
Range(Expression *begin, Expression *end); Range(Expression *begin, Expression *end, const Location &loc);
Range(Expression *begin, Expression *step, Expression *end); Range(Expression *begin, Expression *step, Expression *end, const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private: private:
@ -120,7 +120,7 @@ private:
class Vector : public Expression class Vector : public Expression
{ {
public: public:
Vector(); Vector(const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
void push_back(Expression *expr); void push_back(Expression *expr);
@ -131,7 +131,7 @@ private:
class Lookup : public Expression class Lookup : public Expression
{ {
public: public:
Lookup(const std::string &name); Lookup(const std::string &name, const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private: private:
@ -141,7 +141,7 @@ private:
class MemberLookup : public Expression class MemberLookup : public Expression
{ {
public: public:
MemberLookup(Expression *expr, const std::string &member); MemberLookup(Expression *expr, const std::string &member, const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private: private:
@ -152,7 +152,7 @@ private:
class FunctionCall : public Expression class FunctionCall : public Expression
{ {
public: public:
FunctionCall(const std::string &funcname, const AssignmentList &arglist); FunctionCall(const std::string &funcname, const AssignmentList &arglist, const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
public: public:
@ -163,7 +163,7 @@ public:
class Let : public Expression class Let : public Expression
{ {
public: public:
Let(const AssignmentList &args, Expression *expr); Let(const AssignmentList &args, Expression *expr, const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private: private:
@ -175,13 +175,14 @@ class ListComprehension : public Expression
{ {
virtual bool isListComprehension() const; virtual bool isListComprehension() const;
public: public:
ListComprehension(); ListComprehension(const Location &loc);
~ListComprehension() = default;
}; };
class LcIf : public ListComprehension class LcIf : public ListComprehension
{ {
public: public:
LcIf(Expression *cond, Expression *ifexpr, Expression *elseexpr); LcIf(Expression *cond, Expression *ifexpr, Expression *elseexpr, const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private: private:
@ -193,7 +194,7 @@ private:
class LcFor : public ListComprehension class LcFor : public ListComprehension
{ {
public: public:
LcFor(const AssignmentList &args, Expression *expr); LcFor(const AssignmentList &args, Expression *expr, const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private: private:
@ -204,7 +205,7 @@ private:
class LcForC : public ListComprehension class LcForC : public ListComprehension
{ {
public: public:
LcForC(const AssignmentList &args, const AssignmentList &incrargs, Expression *cond, Expression *expr); LcForC(const AssignmentList &args, const AssignmentList &incrargs, Expression *cond, Expression *expr, const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private: private:
@ -217,7 +218,7 @@ private:
class LcEach : public ListComprehension class LcEach : public ListComprehension
{ {
public: public:
LcEach(Expression *expr); LcEach(Expression *expr, const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private: private:
@ -227,7 +228,7 @@ private:
class LcLet : public ListComprehension class LcLet : public ListComprehension
{ {
public: public:
LcLet(const AssignmentList &args, Expression *expr); LcLet(const AssignmentList &args, Expression *expr, const Location &loc);
ValuePtr evaluate(const class Context *context) const; ValuePtr evaluate(const class Context *context) const;
virtual void print(std::ostream &stream) const; virtual void print(std::ostream &stream) const;
private: private:

View file

@ -32,8 +32,8 @@ AbstractFunction::~AbstractFunction()
{ {
} }
UserFunction::UserFunction(const char *name, AssignmentList &definition_arguments, shared_ptr<Expression> expr) UserFunction::UserFunction(const char *name, AssignmentList &definition_arguments, shared_ptr<Expression> expr, const Location &loc)
: name(name), definition_arguments(definition_arguments), expr(expr) : ASTNode(loc), name(name), definition_arguments(definition_arguments), expr(expr)
{ {
} }
@ -76,8 +76,9 @@ private:
public: public:
FunctionTailRecursion(const char *name, AssignmentList &definition_arguments, FunctionTailRecursion(const char *name, AssignmentList &definition_arguments,
shared_ptr<TernaryOp> expr, shared_ptr<FunctionCall> call, shared_ptr<TernaryOp> expr, shared_ptr<FunctionCall> call,
shared_ptr<Expression> endexpr, bool invert) shared_ptr<Expression> endexpr, bool invert,
: UserFunction(name, definition_arguments, expr), const Location &loc)
: UserFunction(name, definition_arguments, expr, loc),
invert(invert), op(expr), call(call), endexpr(endexpr) { invert(invert), op(expr), call(call), endexpr(endexpr) {
} }
@ -105,22 +106,22 @@ public:
} }
}; };
UserFunction *UserFunction::create(const char *name, AssignmentList &definition_arguments, shared_ptr<Expression> expr) UserFunction *UserFunction::create(const char *name, AssignmentList &definition_arguments, shared_ptr<Expression> expr, const Location &loc)
{ {
if (shared_ptr<TernaryOp> ternary = dynamic_pointer_cast<TernaryOp>(expr)) { if (shared_ptr<TernaryOp> ternary = dynamic_pointer_cast<TernaryOp>(expr)) {
shared_ptr<FunctionCall> ifcall = dynamic_pointer_cast<FunctionCall>(ternary->ifexpr); shared_ptr<FunctionCall> ifcall = dynamic_pointer_cast<FunctionCall>(ternary->ifexpr);
shared_ptr<FunctionCall> elsecall = dynamic_pointer_cast<FunctionCall>(ternary->elseexpr); shared_ptr<FunctionCall> elsecall = dynamic_pointer_cast<FunctionCall>(ternary->elseexpr);
if (ifcall && !elsecall) { if (ifcall && !elsecall) {
if (name == ifcall->name) { if (name == ifcall->name) {
return new FunctionTailRecursion(name, definition_arguments, ternary, ifcall, ternary->elseexpr, false); return new FunctionTailRecursion(name, definition_arguments, ternary, ifcall, ternary->elseexpr, false, loc);
} }
} else if (elsecall && !ifcall) { } else if (elsecall && !ifcall) {
if (name == elsecall->name) { if (name == elsecall->name) {
return new FunctionTailRecursion(name, definition_arguments, ternary, elsecall, ternary->ifexpr, true); return new FunctionTailRecursion(name, definition_arguments, ternary, elsecall, ternary->ifexpr, true, loc);
} }
} }
} }
return new UserFunction(name, definition_arguments, expr); return new UserFunction(name, definition_arguments, expr, loc);
} }
BuiltinFunction::~BuiltinFunction() BuiltinFunction::~BuiltinFunction()

View file

@ -8,13 +8,13 @@
#include <string> #include <string>
#include <vector> #include <vector>
class AbstractFunction : public ASTNode class AbstractFunction
{ {
private: private:
const Feature *feature; const Feature *feature;
public: public:
AbstractFunction() : feature(NULL) {} AbstractFunction(const Feature& feature) : AbstractFunction(&feature) {}
AbstractFunction(const Feature& feature) : feature(&feature) {} AbstractFunction(const Feature *feature = NULL) : feature(feature) {}
virtual ~AbstractFunction(); virtual ~AbstractFunction();
virtual bool is_experimental() const { return feature != NULL; } virtual bool is_experimental() const { return feature != NULL; }
virtual bool is_enabled() const { return (feature == NULL) || feature->is_enabled(); } virtual bool is_enabled() const { return (feature == NULL) || feature->is_enabled(); }
@ -36,7 +36,7 @@ public:
virtual std::string dump(const std::string &indent, const std::string &name) const; virtual std::string dump(const std::string &indent, const std::string &name) const;
}; };
class UserFunction : public AbstractFunction class UserFunction : public AbstractFunction, public ASTNode
{ {
public: public:
std::string name; std::string name;
@ -44,11 +44,11 @@ public:
shared_ptr<Expression> expr; shared_ptr<Expression> expr;
UserFunction(const char *name, AssignmentList &definition_arguments, shared_ptr<Expression> expr); UserFunction(const char *name, AssignmentList &definition_arguments, shared_ptr<Expression> expr, const Location &loc);
virtual ~UserFunction(); virtual ~UserFunction();
virtual ValuePtr evaluate(const Context *ctx, const EvalContext *evalctx) const; virtual ValuePtr evaluate(const Context *ctx, const EvalContext *evalctx) const;
virtual std::string dump(const std::string &indent, const std::string &name) const; virtual std::string dump(const std::string &indent, const std::string &name) const;
static UserFunction *create(const char *name, AssignmentList &definition_arguments, shared_ptr<Expression> expr); static UserFunction *create(const char *name, AssignmentList &definition_arguments, shared_ptr<Expression> expr, const Location &loc);
}; };

View file

@ -51,7 +51,8 @@ namespace fs = boost::filesystem;
#include "boosty.h" #include "boosty.h"
#define YYMAXDEPTH 20000 #define YYMAXDEPTH 20000
#define LOC(loc) Location(loc.first_line, loc.first_column, loc.last_line, loc.last_column)
int parser_error_pos = -1; int parser_error_pos = -1;
int parserlex(void); int parserlex(void);
@ -163,8 +164,7 @@ statement:
| assignment | assignment
| TOK_MODULE TOK_ID '(' arguments_decl optional_commas ')' | TOK_MODULE TOK_ID '(' arguments_decl optional_commas ')'
{ {
UserModule *newmodule = new UserModule(); UserModule *newmodule = new UserModule(LOC(@$));
printf("Loc: %d\n", @$.first_line);
newmodule->definition_arguments = *$4; newmodule->definition_arguments = *$4;
scope_stack.top()->modules[$2] = newmodule; scope_stack.top()->modules[$2] = newmodule;
scope_stack.push(&newmodule->scope); scope_stack.push(&newmodule->scope);
@ -177,7 +177,7 @@ statement:
} }
| TOK_FUNCTION TOK_ID '(' arguments_decl optional_commas ')' '=' expr | TOK_FUNCTION TOK_ID '(' arguments_decl optional_commas ')' '=' expr
{ {
UserFunction *func = UserFunction::create($2, *$4, shared_ptr<Expression>($8)); UserFunction *func = UserFunction::create($2, *$4, shared_ptr<Expression>($8), LOC(@$));
scope_stack.top()->functions[$2] = func; scope_stack.top()->functions[$2] = func;
free($2); free($2);
delete $4; delete $4;
@ -264,7 +264,7 @@ ifelse_statement:
if_statement: if_statement:
TOK_IF '(' expr ')' TOK_IF '(' expr ')'
{ {
$<ifelse>$ = new IfElseModuleInstantiation(); $<ifelse>$ = new IfElseModuleInstantiation(LOC(@$));
$<ifelse>$->arguments.push_back(Assignment("", shared_ptr<Expression>($3))); $<ifelse>$->arguments.push_back(Assignment("", shared_ptr<Expression>($3)));
$<ifelse>$->setPath(boosty::stringy(parser_sourcefile.parent_path())); $<ifelse>$->setPath(boosty::stringy(parser_sourcefile.parent_path()));
scope_stack.push(&$<ifelse>$->scope); scope_stack.push(&$<ifelse>$->scope);
@ -302,7 +302,7 @@ module_id:
single_module_instantiation: single_module_instantiation:
module_id '(' arguments_call ')' module_id '(' arguments_call ')'
{ {
$$ = new ModuleInstantiation($1); $$ = new ModuleInstantiation($1, LOC(@$));
$$->arguments = *$3; $$->arguments = *$3;
$$->setPath(boosty::stringy(parser_sourcefile.parent_path())); $$->setPath(boosty::stringy(parser_sourcefile.parent_path()));
free($1); free($1);
@ -313,51 +313,51 @@ single_module_instantiation:
expr: expr:
TOK_TRUE TOK_TRUE
{ {
$$ = new Literal(ValuePtr(true)); $$ = new Literal(ValuePtr(true), LOC(@$));
} }
| TOK_FALSE | TOK_FALSE
{ {
$$ = new Literal(ValuePtr(false)); $$ = new Literal(ValuePtr(false), LOC(@$));
} }
| TOK_UNDEF | TOK_UNDEF
{ {
$$ = new Literal(ValuePtr::undefined); $$ = new Literal(ValuePtr::undefined, LOC(@$));
} }
| TOK_ID | TOK_ID
{ {
$$ = new Lookup($1); $$ = new Lookup($1, LOC(@$));
free($1); free($1);
} }
| expr '.' TOK_ID | expr '.' TOK_ID
{ {
$$ = new MemberLookup($1, $3); $$ = new MemberLookup($1, $3, LOC(@$));
free($3); free($3);
} }
| TOK_STRING | TOK_STRING
{ {
$$ = new Literal(ValuePtr(std::string($1))); $$ = new Literal(ValuePtr(std::string($1)), LOC(@$));
free($1); free($1);
} }
| TOK_NUMBER | TOK_NUMBER
{ {
$$ = new Literal(ValuePtr($1)); $$ = new Literal(ValuePtr($1), LOC(@$));
} }
| TOK_LET '(' arguments_call ')' expr %prec LET | TOK_LET '(' arguments_call ')' expr %prec LET
{ {
$$ = new Let(*$3, $5); $$ = new Let(*$3, $5, LOC(@$));
delete $3; delete $3;
} }
| '[' expr ':' expr ']' | '[' expr ':' expr ']'
{ {
$$ = new Range($2, $4); $$ = new Range($2, $4, LOC(@$));
} }
| '[' expr ':' expr ':' expr ']' | '[' expr ':' expr ':' expr ']'
{ {
$$ = new Range($2, $4, $6); $$ = new Range($2, $4, $6, LOC(@$));
} }
| '[' optional_commas ']' | '[' optional_commas ']'
{ {
$$ = new Literal(ValuePtr(Value::VectorType())); $$ = new Literal(ValuePtr(Value::VectorType()), LOC(@$));
} }
| '[' vector_expr optional_commas ']' | '[' vector_expr optional_commas ']'
{ {
@ -365,55 +365,55 @@ expr:
} }
| expr '*' expr | expr '*' expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::Multiply, $3); $$ = new BinaryOp($1, BinaryOp::Op::Multiply, $3, LOC(@$));
} }
| expr '/' expr | expr '/' expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::Divide, $3); $$ = new BinaryOp($1, BinaryOp::Op::Divide, $3, LOC(@$));
} }
| expr '%' expr | expr '%' expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::Modulo, $3); $$ = new BinaryOp($1, BinaryOp::Op::Modulo, $3, LOC(@$));
} }
| expr '+' expr | expr '+' expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::Plus, $3); $$ = new BinaryOp($1, BinaryOp::Op::Plus, $3, LOC(@$));
} }
| expr '-' expr | expr '-' expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::Minus, $3); $$ = new BinaryOp($1, BinaryOp::Op::Minus, $3, LOC(@$));
} }
| expr '<' expr | expr '<' expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::Less, $3); $$ = new BinaryOp($1, BinaryOp::Op::Less, $3, LOC(@$));
} }
| expr LE expr | expr LE expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::LessEqual, $3); $$ = new BinaryOp($1, BinaryOp::Op::LessEqual, $3, LOC(@$));
} }
| expr EQ expr | expr EQ expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::Equal, $3); $$ = new BinaryOp($1, BinaryOp::Op::Equal, $3, LOC(@$));
} }
| expr NE expr | expr NE expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::NotEqual, $3); $$ = new BinaryOp($1, BinaryOp::Op::NotEqual, $3, LOC(@$));
} }
| expr GE expr | expr GE expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::GreaterEqual, $3); $$ = new BinaryOp($1, BinaryOp::Op::GreaterEqual, $3, LOC(@$));
} }
| expr '>' expr | expr '>' expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::Greater, $3); $$ = new BinaryOp($1, BinaryOp::Op::Greater, $3, LOC(@$));
} }
| expr AND expr | expr AND expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::LogicalAnd, $3); $$ = new BinaryOp($1, BinaryOp::Op::LogicalAnd, $3, LOC(@$));
} }
| expr OR expr | expr OR expr
{ {
$$ = new BinaryOp($1, BinaryOp::Op::LogicalOr, $3); $$ = new BinaryOp($1, BinaryOp::Op::LogicalOr, $3, LOC(@$));
} }
| '+' expr | '+' expr
{ {
@ -421,11 +421,11 @@ expr:
} }
| '-' expr | '-' expr
{ {
$$ = new UnaryOp(UnaryOp::Op::Negate, $2); $$ = new UnaryOp(UnaryOp::Op::Negate, $2, LOC(@$));
} }
| '!' expr | '!' expr
{ {
$$ = new UnaryOp(UnaryOp::Op::Not, $2); $$ = new UnaryOp(UnaryOp::Op::Not, $2, LOC(@$));
} }
| '(' expr ')' | '(' expr ')'
{ {
@ -433,15 +433,15 @@ expr:
} }
| expr '?' expr ':' expr | expr '?' expr ':' expr
{ {
$$ = new TernaryOp($1, $3, $5); $$ = new TernaryOp($1, $3, $5, LOC(@$));
} }
| expr '[' expr ']' | expr '[' expr ']'
{ {
$$ = new ArrayLookup($1, $3); $$ = new ArrayLookup($1, $3, LOC(@$));
} }
| TOK_ID '(' arguments_call ')' | TOK_ID '(' arguments_call ')'
{ {
$$ = new FunctionCall($1, *$3); $$ = new FunctionCall($1, *$3, LOC(@$));
free($1); free($1);
delete $3; delete $3;
} }
@ -452,12 +452,12 @@ list_comprehension_elements:
be parsed as an expression) */ be parsed as an expression) */
TOK_LET '(' arguments_call ')' list_comprehension_elements_p TOK_LET '(' arguments_call ')' list_comprehension_elements_p
{ {
$$ = new LcLet(*$3, $5); $$ = new LcLet(*$3, $5, LOC(@$));
delete $3; delete $3;
} }
| TOK_EACH list_comprehension_elements_or_expr | TOK_EACH list_comprehension_elements_or_expr
{ {
$$ = new LcEach($2); $$ = new LcEach($2, LOC(@$));
} }
| TOK_FOR '(' arguments_call ')' list_comprehension_elements_or_expr | TOK_FOR '(' arguments_call ')' list_comprehension_elements_or_expr
{ {
@ -467,24 +467,24 @@ list_comprehension_elements:
for (int i = $3->size()-1; i >= 0; i--) { for (int i = $3->size()-1; i >= 0; i--) {
AssignmentList arglist; AssignmentList arglist;
arglist.push_back((*$3)[i]); arglist.push_back((*$3)[i]);
Expression *e = new LcFor(arglist, $$); Expression *e = new LcFor(arglist, $$, LOC(@$));
$$ = e; $$ = e;
} }
delete $3; delete $3;
} }
| TOK_FOR '(' arguments_call ';' expr ';' arguments_call ')' list_comprehension_elements_or_expr | TOK_FOR '(' arguments_call ';' expr ';' arguments_call ')' list_comprehension_elements_or_expr
{ {
$$ = new LcForC(*$3, *$7, $5, $9); $$ = new LcForC(*$3, *$7, $5, $9, LOC(@$));
delete $3; delete $3;
delete $7; delete $7;
} }
| TOK_IF '(' expr ')' list_comprehension_elements_or_expr | TOK_IF '(' expr ')' list_comprehension_elements_or_expr
{ {
$$ = new LcIf($3, $5, 0); $$ = new LcIf($3, $5, 0, LOC(@$));
} }
| TOK_IF '(' expr ')' list_comprehension_elements_or_expr TOK_ELSE list_comprehension_elements_or_expr | TOK_IF '(' expr ')' list_comprehension_elements_or_expr TOK_ELSE list_comprehension_elements_or_expr
{ {
$$ = new LcIf($3, $5, $7); $$ = new LcIf($3, $5, $7, LOC(@$));
} }
; ;
@ -510,12 +510,12 @@ optional_commas:
vector_expr: vector_expr:
expr expr
{ {
$$ = new Vector(); $$ = new Vector(LOC(@$));
$$->push_back($1); $$->push_back($1);
} }
| list_comprehension_elements | list_comprehension_elements
{ {
$$ = new Vector(); $$ = new Vector(LOC(@$));
$$->push_back($1); $$->push_back($1);
} }
| vector_expr ',' optional_commas list_comprehension_elements_or_expr | vector_expr ',' optional_commas list_comprehension_elements_or_expr
@ -547,12 +547,12 @@ arguments_decl:
argument_decl: argument_decl:
TOK_ID TOK_ID
{ {
$$ = new Assignment($1); $$ = new Assignment($1, LOC(@$));
free($1); free($1);
} }
| TOK_ID '=' expr | TOK_ID '=' expr
{ {
$$ = new Assignment($1, shared_ptr<Expression>($3)); $$ = new Assignment($1, shared_ptr<Expression>($3), LOC(@$));
free($1); free($1);
} }
; ;
@ -579,11 +579,11 @@ arguments_call:
argument_call: argument_call:
expr expr
{ {
$$ = new Assignment("", shared_ptr<Expression>($1)); $$ = new Assignment("", shared_ptr<Expression>($1), LOC(@$));
} }
| TOK_ID '=' expr | TOK_ID '=' expr
{ {
$$ = new Assignment($1, shared_ptr<Expression>($3)); $$ = new Assignment($1, shared_ptr<Expression>($3), LOC(@$));
free($1); free($1);
} }
; ;
@ -597,9 +597,9 @@ int parserlex(void)
void yyerror (char const *s) void yyerror (char const *s)
{ {
// FIXME: We leak memory on parser errors... // FIXME: We leak memory on parser errors...
PRINTB("ERROR: Parser error in file %s, line %d: %s\n", PRINTB("ERROR: Parser error in file %s, line %d: %s\n",
sourcefile() % lexerget_lineno() % s); sourcefile() % lexerget_lineno() % s);
} }
FileModule *parse(const char *text, const fs::path &filename, int debug) FileModule *parse(const char *text, const fs::path &filename, int debug)

View file

@ -682,6 +682,7 @@ set(CORE_SOURCES
../src/FileModule.cc ../src/FileModule.cc
../src/UserModule.cc ../src/UserModule.cc
../src/GroupModule.cc ../src/GroupModule.cc
../src/AST.cc
../src/ModuleInstantiation.cc ../src/ModuleInstantiation.cc
../src/ModuleCache.cc ../src/ModuleCache.cc
../src/node.cc ../src/node.cc