// Copyright (c) 1996 James Clark // See the file copying.txt for copying permission. #ifndef Expression_INCLUDED #define Expression_INCLUDED 1 #include "ELObj.h" #include "Owner.h" #include "Vector.h" #include "NCVector.h" #include "Resource.h" #include "Ptr.h" #include "Insn.h" #include "Named.h" #include "Location.h" #ifdef DSSSL_NAMESPACE namespace DSSSL_NAMESPACE { #endif class Interpreter; class Identifier; struct BoundVar { const Identifier *ident; enum { usedFlag = 01, assignedFlag = 02, sharedFlag = 04, uninitFlag = 010, boxedFlags = assignedFlag|sharedFlag }; static bool flagsBoxed(unsigned f) { return (f & boxedFlags) == boxedFlags; } bool boxed() const { return flagsBoxed(flags); } unsigned flags; unsigned reboundCount; }; class BoundVarList : public Vector { public: BoundVarList() { } BoundVarList(const Vector &); BoundVarList(const Vector &, size_t, unsigned flags = 0); void append(const Identifier *, unsigned flags); void mark(const Identifier *, unsigned flags); void removeUnused(); void remove(const Vector &); void rebind(const Vector &); void unbind(const Vector &); BoundVar *find(const Identifier *); }; class Environment { public: Environment(); Environment(const BoundVarList &frameVars, const BoundVarList &closureVars); void boundVars(BoundVarList &) const; bool lookup(const Identifier *var, bool &isFrame, int &index, unsigned &flags) const; void augmentFrame(const BoundVarList &, int stackPos); private: struct FrameVarList : public Resource { int stackPos; const BoundVarList *vars; ConstPtr next; }; ConstPtr frameVarList_; const BoundVarList *closureVars_; }; class Expression { public: Expression(const Location &); virtual ~Expression() { } virtual InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &) = 0; static InsnPtr optimizeCompile(Owner &, Interpreter &, const Environment &, int, const InsnPtr &); virtual void markBoundVars(BoundVarList &vars, bool); virtual void optimize(Interpreter &, const Environment &, Owner &); virtual ELObj *constantValue() const; virtual bool canEval(bool maybeCall) const = 0; virtual const Identifier *keyword() const; const Location &location() const; protected: static InsnPtr compilePushVars(Interpreter &interp, const Environment &env, int stackPos, const BoundVarList &vars, size_t varIndex, const InsnPtr &next); private: Location loc_; }; class ConstantExpression : public Expression { public: ConstantExpression(ELObj *, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void optimize(Interpreter &, const Environment &, Owner &); bool canEval(bool maybeCall) const; const Identifier *keyword() const; private: ELObj *obj_; // must be permanent }; class ResolvedConstantExpression : public Expression { public: ResolvedConstantExpression(ELObj *, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); bool canEval(bool maybeCall) const; ELObj *constantValue() const; private: ELObj *obj_; }; class CallExpression : public Expression { public: CallExpression(Owner &, NCVector > &, const Location &loc); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void markBoundVars(BoundVarList &vars, bool); int nArgs(); bool canEval(bool maybeCall) const; private: Owner op_; NCVector > args_; }; class VariableExpression : public Expression { public: VariableExpression(const Identifier *, const Location &loc); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void optimize(Interpreter &, const Environment &, Owner &); void markBoundVars(BoundVarList &vars, bool); bool canEval(bool maybeCall) const; private: const Identifier *ident_; bool isTop_; }; class IfExpression : public Expression { public: IfExpression(Owner &, Owner &, Owner &, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void markBoundVars(BoundVarList &vars, bool); bool canEval(bool maybeCall) const; void optimize(Interpreter &, const Environment &, Owner &); private: Owner test_; Owner consequent_; Owner alternate_; }; class OrExpression : public Expression { public: OrExpression(Owner &, Owner &, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void markBoundVars(BoundVarList &vars, bool); bool canEval(bool maybeCall) const; void optimize(Interpreter &, const Environment &, Owner &); private: Owner test1_; Owner test2_; }; class CondFailExpression : public Expression { public: CondFailExpression(const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); bool canEval(bool maybeCall) const; }; class CaseExpression : public Expression { public: struct Case { Vector datums; Owner expr; }; CaseExpression(Owner &, NCVector &, Owner &, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void markBoundVars(BoundVarList &vars, bool); bool canEval(bool maybeCall) const; void optimize(Interpreter &, const Environment &, Owner &); private: Owner key_; NCVector cases_; Vector nResolved_; Owner else_; }; class LambdaExpression : public Expression { public: LambdaExpression(Vector &vars, NCVector > &inits, int nOptional, bool hasRest, int nKey, Owner &body, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void markBoundVars(BoundVarList &vars, bool); bool canEval(bool maybeCall) const; private: Vector formals_; NCVector > inits_; Signature sig_; Owner body_; }; class LetExpression : public Expression { public: LetExpression(Vector &vars, NCVector > &inits, Owner &body, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void markBoundVars(BoundVarList &vars, bool); bool canEval(bool maybeCall) const; protected: InsnPtr compileInits(Interpreter &interp, const Environment &env, const BoundVarList &initVars, size_t initIndex, int stackPos, const InsnPtr &next); Vector vars_; NCVector > inits_; Owner body_; }; class LetStarExpression : public LetExpression { public: LetStarExpression(Vector &vars, NCVector > &inits, Owner &body, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); private: InsnPtr compileInits(Interpreter &interp, const Environment &env, const BoundVarList &initVars, size_t initIndex, int stackPos, const InsnPtr &next); }; class LetrecExpression : public Expression { public: LetrecExpression(Vector &vars, NCVector > &inits, Owner &body, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void markBoundVars(BoundVarList &vars, bool); bool canEval(bool maybeCall) const; private: InsnPtr compileInits(Interpreter &interp, const Environment &env, size_t initIndex, int stackPos, const InsnPtr &next); Vector vars_; NCVector > inits_; Owner body_; }; class QuasiquoteExpression : public Expression { public: enum Type { listType, improperType, vectorType }; QuasiquoteExpression(NCVector > &, Vector &spliced, Type type, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void markBoundVars(BoundVarList &vars, bool); bool canEval(bool maybeCall) const; void optimize(Interpreter &, const Environment &, Owner &); private: NCVector > members_; Vector spliced_; Type type_; }; class SequenceExpression : public Expression { public: SequenceExpression(NCVector > &, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void markBoundVars(BoundVarList &vars, bool); bool canEval(bool maybeCall) const; void optimize(Interpreter &, const Environment &, Owner &); private: NCVector > sequence_; }; class AssignmentExpression : public Expression { public: AssignmentExpression(const Identifier *, Owner &, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void markBoundVars(BoundVarList &vars, bool); bool canEval(bool maybeCall) const; private: const Identifier *var_; Owner value_; }; class ProcessingMode; class WithModeExpression : public Expression { public: WithModeExpression(const ProcessingMode *, Owner &, const Location &); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void markBoundVars(BoundVarList &vars, bool); bool canEval(bool maybeCall) const; private: const ProcessingMode *mode_; Owner expr_; }; class StyleExpression : public Expression { public: StyleExpression(Vector &, NCVector > &, const Location &loc); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); void markBoundVars(BoundVarList &vars, bool); bool canEval(bool maybeCall) const; protected: virtual void unknownStyleKeyword(const Identifier *ident, Interpreter &interp, const Location &loc) const; virtual bool maybeStyleKeyword(const Identifier *ident) const; Vector keys_; NCVector > exprs_; }; class FlowObj; class MakeExpression : public StyleExpression { public: MakeExpression(const Identifier *, Vector &, NCVector > &, const Location &loc); InsnPtr compile(Interpreter &, const Environment &, int, const InsnPtr &); private: InsnPtr compileNonInheritedCs(Interpreter &interp, const Environment &env, int stackPos, const InsnPtr &next); FlowObj *applyConstNonInheritedCs(FlowObj *, Interpreter &, const Environment &); void unknownStyleKeyword(const Identifier *ident, Interpreter &interp, const Location &loc) const; bool maybeStyleKeyword(const Identifier *ident) const; const Identifier *foc_; }; inline const Location &Expression::location() const { return loc_; } inline InsnPtr Expression::optimizeCompile(Owner &expr, Interpreter &interp, const Environment &env, int stackPos, const InsnPtr &next) { expr->optimize(interp, env, expr); return expr->compile(interp, env, stackPos, next); } #ifdef DSSSL_NAMESPACE } #endif #endif /* not Expression_INCLUDED */