nodes.h

来自「Shorthand是一个强大的脚本语言」· C头文件 代码 · 共 683 行

H
683
字号
#ifndef __nodes_h
#define __nodes_h
///////////////////////////////////////////////////////////////////////////////
// $Header: /shorthand/src/nodes.h 4     1/09/03 7:14p Arm $
//-----------------------------------------------------------------------------
// Project: ShortHand interpreter
// Author: Andrei Remenchuk <andrei@remenchuk.com>
//-----------------------------------------------------------------------------
// nodes.h: definitions of ShortHand Syntax Tree nodes  
///////////////////////////////////////////////////////////////////////////////

#include <stdarg.h>
#include <stdio.h>
#include "shorthand.h"

#include "array.h"
#include "cstring.h"
#include "map.h"
#include "mman.h"
#include "utils.h"
#include "yydef.h"
#include "except.h"
#include "http.h"

#include "value.h"
#include "object.h"
#include "function.h"


class ShhModule;
class ShhModule;
    
class ShhVariable;
class ShhNode;
class ShhExecutable;
class ShhLoop;



class ShhVariable
{
protected:
    const char* m_name;
    bool m_initialized;
    ShhValue m_value;
public:
    ShhVariable(const char* name);
    const char* getName() const { return m_name; }
    bool isInitialized() const { return m_initialized; }
    ShhValue& value() { return m_value; }
    const ShhValue& value() const { return m_value; }

    ~ShhVariable();
};


class ShhVariableList: public array<ShhVariable>
{
public:
    ShhVariableList() {}
    ShhVariable* find(const char* name);
};




/**
 * Base object for all nodes in the graph
 */
class ShhNode
{
protected:
    int m_index;
    const char* m_content;
    YYLTYPE m_location;
    ShhModule* m_module;

    ShhException* mkexception(int code, const char* format, ...) const;
    ShhException* wrap(int code, ShhException* ex) const;

public:
    ShhNode(const YYLTYPE& location);
    ShhNode();

    void include(ShhModule* module);

    int index() const { return m_index; }
    void place(const YYLTYPE& aLocation);
    int lineno() const { return m_location.first_line; }

    ShhObject* requireObjectVariable(const char* name);
    ShhObject* requireObjectValue(ShhValue& value);

    virtual ~ShhNode();

friend class ShhModule;
};

class ShhParameter : public ShhNode
{
protected:
    string m_name;
public:
    ShhParameter(const char* name) : m_name(name) {}
    const char* name() const { return m_name; }
};

class ShhParameterList: public ShhNode, public array<ShhParameter,false>
{
public:
    ShhParameterList() {}
};

/** obsolete */
class ShhQualifier : public ShhNode
{
protected:
    array<char,false> m_items;
    string m_fqname;
public:
    ShhQualifier(const char* term);
    ShhQualifier* add(const char* term);
    
    // returns full-qualified name
    const char* fqname() ;
};



///////////////////////////////////////////////////////////////////
// EXPRESSION NODES
///////////////////////////////////////////////////////////////////

class ShhExpression : public ShhNode
{
public:
    ShhExpression() {}
    virtual ShhValue evaluate() = 0;
    virtual ShhValue& lvalue();
};


class ShhConstant : public ShhExpression
{
protected:
    ShhValue m_value;
public:
    ShhConstant(const ShhValue& value) : m_value(value) {}
    ShhValue evaluate() { return m_value; }
};

/**
 * Arithmetic operator (+|-|/|*)
 */
class ShhArithmetic : public ShhExpression
{
protected:
    int m_operator;
    ShhExpression* m_left;
    ShhExpression* m_right;
public:
    ShhArithmetic( int oper, ShhExpression* left, ShhExpression* right);
    ShhValue evaluate();
};

/**
 * Concatenation of two strings
 */
class ShhConcat : public ShhExpression
{
protected:
    ShhExpression* m_left;
    ShhExpression* m_right;
public:
    ShhConcat( ShhExpression* left, ShhExpression* right);
    ShhValue evaluate();
};


/*
//* "LVALUE" object - anything that can be assigned to.
class ShhLeftValue : public ShhNode
{
protected:
    ShhExpression* m_expression;
public:
    ShhLeftValue() {}
    virtual ShhValue& lvalue() = 0;
};

// * Variable dereference as lvalue
class ShhVariableLV : public ShhLeftValue
{
protected:
    const char* m_name;
public:
    ShhVariableLV(const char* name);
    ShhValue& lvalue();

};

// * Object property dereference as lvalue.
class ShhPropertyLV : public ShhLeftValue
{
protected:
    ShhLeftValue* m_object;
    const char* m_property;
public:
    ShhPropertyLV(ShhLeftValue* object, const char* propertyName);
    ShhValue& lvalue();
};
*/

// * Array element reference (lvalue too).
class ShhArrayElement : public ShhExpression
{
protected:
    ShhExpression* m_object;
    ShhExpression* m_index;
public:
    ShhArrayElement(ShhExpression* object, ShhExpression* index);
    ShhValue evaluate();
    ShhValue& lvalue();
};

class ShhHashElement : public ShhExpression
{
protected:
    ShhExpression* m_object;
    ShhExpression* m_index;
public:
    ShhHashElement(ShhExpression* object, ShhExpression* index);
    ShhValue evaluate();
    ShhValue& lvalue();
};



/**
 * Variable reference
 */
class ShhVariableRef : public ShhExpression
{
protected:
    string m_name;
public:
    ShhVariableRef(const char* name);
    ShhValue evaluate();
    ShhValue& lvalue();
};


/**
 * Reference to object's property
 */
class ShhPropertyRef : public ShhExpression
{
protected:
    ShhExpression* m_object;
    const char* m_property_name;
public:
    ShhPropertyRef(ShhExpression* object, const char* property_name);
    ShhValue evaluate();
    ShhValue& lvalue();
};


class ShhExpressionList : public ShhNode, public array<ShhExpression, false>
{
private:
    ShhExpressionList() { }
public:
    ShhExpressionList(ShhModule& module) {}
    ShhExpressionList(ShhExpression* first) { add(first); }
    void evaluate(ShhValueList& results);

    static ShhExpressionList* null;
};



/** 
 * Invocation of object's method as expression having value
 * and possibly some arguments
 */
class ShhValueMethodCall : public ShhExpression
{
protected:
    ShhExpression* m_object;
    const char* m_method_name;
    ShhExpressionList* m_args;
public:
    ShhValueMethodCall(ShhExpression* object, const char* method_name, ShhExpressionList* args);
    ShhValue evaluate();
};




/**
 * Function call
 */
class ShhFunctionCall : public ShhExpression
{
protected:
    const char* m_function;
    ShhExpressionList* m_args;
public:
    ShhFunctionCall(const char* function, ShhExpressionList* args);
    const char* name() const { return m_function; }
    ShhExpressionList* args() const { return m_args; }
    ShhValue evaluate();
};


///////////////////////////////////////////////////////////////////
// PREDICATE NODES (BOOLEAN EXPRESSIONS)
///////////////////////////////////////////////////////////////////
class ShhPredicate : public ShhNode
{
public:
    virtual bool check() = 0;
};

class ShhComparison : public ShhPredicate
{
protected:
    int m_operator;
    ShhExpression* m_left;
    ShhExpression* m_right;

public:
    ShhComparison( int op, ShhExpression* left, ShhExpression* right);
    bool check();
};

class ShhBooleanArithmetic : public ShhPredicate
{
protected:
    int m_operation;
    ShhPredicate* m_left;
    ShhPredicate* m_right;

public:
    ShhBooleanArithmetic( int op, ShhPredicate* left, ShhPredicate* right);
    bool check();
};



///////////////////////////////////////////////////////////////////
// EXECUTABLE OPERATORS
///////////////////////////////////////////////////////////////////

class ShhExecutable : public ShhNode
{
public:
    virtual void execute() = 0;
};


/**
 * Turns expression node into executable node by evaluating it
 * and discarding result.
 */
class ShhVoid : public ShhExecutable
{
protected:
    ShhExpression* m_expression;
public:
    ShhVoid(ShhExpression* expr) : m_expression(expr) {}
    void execute() { m_expression->evaluate(); }
};

class ShhBatch : public ShhExecutable
{
protected:
    array<ShhExecutable,false> m_statements;
public:
    ShhBatch( ShhExecutable* first = NULL);
    void execute();
    ShhBatch* add(ShhExecutable* statement);
};

/**
 * Do-nothing executable operator.
 */
class ShhNOP : public ShhExecutable
{
public:
    ShhNOP() { }
    void execute() { }
};

/**
 * Assignment to the variable.
 */
class ShhAssignment : public ShhExecutable
{
protected:
    ShhExpression* m_lvalue;
    ShhExpression* m_expression;

public:
    ShhAssignment(ShhExpression* lvalue, ShhExpression* ex);
    void execute();
};


/**
 * Declaration of local variable with optional initializer
 */
class ShhLocalDecl : public ShhExecutable
{
protected:
    string m_name;
    ShhExpression* m_expression;

public:
    ShhLocalDecl(const char* name, ShhExpression* ex = NULL);
    void execute();
};


/**
 * Invocation of object constructor. Represents "NEW" operation
 */
class ShhObjectCtor : public ShhExpression
{
protected:
    const char* m_type;
    ShhExpressionList* m_args;
public:
    ShhObjectCtor(const char* type, ShhExpressionList* args = NULL);
    ShhValue evaluate();
};

/**
 * Assignment to object property.
 */
class ShhPropertyAssignment : public ShhExecutable
{
protected:
    const char* m_object_name;
    const char* m_property_name;
    ShhExpression* m_expression;
public:
    ShhPropertyAssignment(const char* object_name, const char* prop_name, ShhExpression* expression);
    void execute();
};


class ShhVoidMethodCall : public ShhExecutable
{
protected:
    ShhExpression* m_object;
    string m_method_name;
    ShhExpressionList* m_args;
public:
    ShhVoidMethodCall(ShhExpression* object, const char* method_name, ShhExpressionList* args);
    void execute();
};

/**
 * PRINT operator.
 */
class ShhPrint : public ShhExecutable
{
protected:
    ShhExpression* m_expression;
    bool m_newline_after;
public:
    ShhPrint(ShhExpression* ex, bool newline_after = false);
    void execute();
};


/**
 * Bare HTML - works as though PRINT operator was there instead of
 * unescaped HTML block.
 */
class ShhHTML : public ShhExecutable
{
protected:
    const char* m_content;
public:
    ShhHTML(const char* content);
    void execute();

};


/**
 * IF-THEN-ELSE block.
 */
class ShhConditionBlock : public ShhExecutable
{
protected:
    ShhPredicate* m_predicate;
    ShhExecutable* m_then;
    ShhExecutable* m_else;
public:
    ShhConditionBlock(ShhPredicate* predicate, ShhExecutable* then_block, ShhExecutable* else_block);
    void execute();
};

/**
 * Pseudo-exception that is used to interrupt loops flow control.
 */
class ShhLoopInterruption 
{
};

/**
 * Abstract LOOP. All ShortHand loops are inherited from this class.
 * This allows to implement BREAK and CONTINUE operations independently
 * of loop semantics.
 */
class ShhLoop : public ShhExecutable
{
public:
    bool m_break_requested;
    bool m_continue_requested;
    ShhLoop() 
    {
        m_break_requested = false;
        m_continue_requested = false;
    }
    void execute();
    virtual void loop() = 0;
};


/**
 * GRID-style loop (works on RecordSet objects 
 */
class ShhGrid : public ShhLoop
{
protected:
    const char* m_object_name;
    ShhExecutable* m_body;
    ShhExpression* m_start;
    ShhExpression* m_end;

public:
    ShhGrid(const char* object_name, ShhExecutable* body, ShhExpression* start = NULL, ShhExpression* end = NULL);
    void loop();
};


/**
 * WHILE loop.
 */
class ShhWhileLoop : public ShhLoop
{
protected:
    ShhPredicate* m_predicate;
    ShhExecutable* m_body;
public:
    ShhWhileLoop(ShhPredicate* predicate, ShhExecutable* body);
    void loop();
};

/**
 * FOR-style loop.
 */
class ShhForLoop : public ShhLoop
{
protected:
    const char* m_counter_name;
    ShhVariable* m_counter;
    ShhExpression* m_from;
    ShhExpression* m_to;
    ShhExecutable* m_body;

public:
    ShhForLoop(const char* counter, ShhExpression* from, ShhExpression* to, ShhExecutable* body);
    void loop();
};

class ShhForeachLoop : public ShhLoop
{
protected:
    ShhExpression* m_subject;
    ShhExpression* m_index;
    ShhExpression* m_value;
    ShhExecutable* m_body;
public:
    ShhForeachLoop(ShhExpression* subject, ShhExpression* index, ShhExpression* value, ShhExecutable* body);
    void loop();
};

/**
 * Operator that breaks the loop.
 */
class ShhBreak : public ShhExecutable
{
public:
    ShhBreak();
    void execute();
};

/**
 * Loop "continue" operator - proceeds to the next iteration skipping the 
 * rest of the code remaining until the end of loop.
 */
class ShhContinue : public ShhExecutable
{
public:
    ShhContinue();
    void execute();
};




/**
 * File inclusion - executes another script in the same contetxt with
 * this script.
 */
class ShhInclude : public ShhExecutable
{
protected:
    ShhExpression* m_name;
public:
    ShhInclude(ShhExpression* name);
    void execute();
};


/**
 * JUMP operator - transfers control to another ShortHand script 
 * that will optionally inherit entire environment from the current script.
 */
class ShhJump : public ShhExecutable
{
protected:
    ShhExpression* m_name;
public:
    ShhJump(ShhExpression* name);
    void execute();
};


/**
 * ShhDefun - UDF (User-Defined Function) definition.
 */
class ShhDefun : public ShhExecutable, public ShhFunction
{
protected:
    ShhParameterList* m_parameters;
    ShhBatch* m_body;
    string m_name;

public:
    ShhDefun(const char* name, ShhParameterList* parameters, ShhBatch* body);
    void execute();
    const char* name() const { return m_name; }
    ShhValue execute(ShhModule* module, const ShhValueList& args) const;
    void paste_location(string& location);
    
friend class ShhDefunList;
};


class ShhDefunList : public array<ShhDefun,false>
{
public:
    ShhDefun* find(const char* name);
};

class ShhReturn : public ShhExecutable
{
protected:
    ShhExpression* m_expression;
public:
    ShhReturn(ShhExpression* expression);
    void execute();
};

#endif // __nodes_h

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?