⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nodes.cpp

📁 Shorthand是一个强大的脚本语言
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
// $Header: /shorthand/src/nodes.cpp 5     2/14/03 4:20a Arm $
//-----------------------------------------------------------------------------
// Project: ShortHand interpreter
// Author: Andrei Remenchuk <andrei@remenchuk.com>
//-----------------------------------------------------------------------------
// nodes.cpp: implementations of ShortHand Syntax Tree nodes  
///////////////////////////////////////////////////////////////////////////////
#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#ifdef WIN32
#include <windows.h>
#endif

#include "nodes.h"
#include "parser.h"

#include "shsql.h"

#include "utils.h"
#include "shorthand.h"
#include "yydef.h"
#include "value.h"
#include "module.h"
#include "sharray.h"
#include "hash.h"
#include "function.h"
#include "builtins.h"


ShhExpressionList* ShhExpressionList::null = new ShhExpressionList();



ShhVariable::ShhVariable(const char* name)
{
    m_name = name;
    m_initialized = false;
}

ShhVariable::~ShhVariable()
{
}


ShhVariable* ShhVariableList::find(const char* name)
{
    for(int i=0,n=m_size; i<n; i++)
    {
        ShhVariable* var = get(i);
        if (stricmp(var->getName(), name) == 0) return var;
    }
    return NULL;
}


/**
 * Base object for all nodes in the graph
 */

ShhNode::ShhNode()
{
    TRACE((22, "ShhNode(0x%08x  )::ShhNode()\n", this)); 
    //if (module == NULL) throw new ShhException("global module is not defined");
    //m_location = yylloc;
    m_index = -1;
    m_content = NULL;
    m_module = NULL;
}

ShhNode::ShhNode(const YYLTYPE& location) : m_location(location)
{
    //if (module == NULL) throw new ShhException("global module is not defined");
    m_index = -1;
    //m_module = module;
    m_content = NULL;
    m_module = NULL;
}

void ShhNode::place(const YYLTYPE& location)
{
    m_location = location;
}
    
ShhNode::~ShhNode()
{
    TRACE((22, "ShhNode(0x%08x[%d])::~ShhNode()\n", this, m_index)); 
}

ShhException* ShhNode::mkexception(int code, const char* format, ...) const
{
    va_list args; va_start(args, format);
    string usertext; usertext.vprintf(format, args);
    ShhException* ex = new ShhException
    (
        "\n<br>\n<b>%s</b>(%d:%d): %s\n<br>\n",
        m_module->getName(), m_location.first_line, m_location.first_column,
        usertext.cstr()
    );
    ex->setCode(code);
    return ex;
}

ShhException* ShhNode::wrap(int code, ShhException* ex) const
{
    if (ex->code() != 0) code = ex->code();
    ShhException* newx = mkexception(code, "%s", ex->message());
    delete ex;
    return newx;
}

ShhObject* ShhNode::requireObjectValue(ShhValue& value)
{
    if (!value.isObject())
        throw mkexception(1052, "Expression doesn't evaluate as object");
    return value.toObject();
}

ShhObject* ShhNode::requireObjectVariable(const char* name)
{
    ShhVariable* v = m_module->findVariable(name);
    if (v == NULL || !v->value().isObject())
        throw mkexception(1009, "Variable '%s' doesn't have object value", name);
    return v->value().toObject();
}

ShhValue& ShhExpression::lvalue()
{
    throw mkexception(1080, "This expression cannot be assigned to");
}

ShhQualifier::ShhQualifier(const char* term)
{ 
    m_items.add((char*)term);
    m_fqname.append(term);
}

ShhQualifier* ShhQualifier::add(const char* term)
{ 
    m_items.add((char*)term); 
    m_fqname.append(term);
    return this; 
}

// returns full-qualified name
const char* ShhQualifier::fqname() 
{
    return m_fqname;
}


void ShhExpressionList::evaluate(ShhValueList& results)
{
    results.clear();
    if (this != NULL) 
    {
        for(int i=0,n=m_size; i<n; i++)
        {
            results.add(new ShhValue(get(i)->evaluate()));
        }
    }

}



ShhArithmetic::ShhArithmetic(int op, ShhExpression* left, ShhExpression* right)
{
    m_operator = op;
    m_left = left;
    m_right = right;
}

ShhValue ShhArithmetic::evaluate()
{
    ShhValue value1 = m_left->evaluate();
    ShhValue value2 = m_right->evaluate();

    switch(m_operator)
    {
    case '+': return value1 + value2; break;
    case '-': return value1 - value2; break;
    case '*': return value1 * value2; break;
    case '/': 
        //if (value2.toInt() == 0) throw mkexception(1003, "division by zero");
        return value1 / value2;

    case '%': 
        if (value2.toInt() == 0) throw mkexception(1010, "modulus by zero");
        return value1.toInt() % value2.toInt(); 

    case MIN: 
        return (value1 < value2) ? value1 : value2;

    case MAX:
        return (value1 > value2) ? value1 : value2;
        break;

    default:
        throw mkexception(1004, "unknown arithmetic operator: %d", m_operator);
    }
}

ShhVariableRef::ShhVariableRef(const char* name)
: m_name(name)
{
}

ShhValue ShhVariableRef::evaluate()
{
    return m_module->var(m_name)->value();
}

ShhValue& ShhVariableRef::lvalue()
{
    return m_module->var(m_name)->value();
}


/*
ShhVariableLV::ShhVariableLV(const char* name) 
: m_name(name)
{
}

ShhValue& ShhVariableLV::lvalue()
{
    return m_module->var(m_name)->value();
}
*/


ShhPropertyRef::ShhPropertyRef(ShhExpression* object, const char* property_name)
{
    m_object = object;
    m_property_name = property_name;
}

ShhValue ShhPropertyRef::evaluate()
{
    ShhValue o = m_object->evaluate();
    if (!o.isObject())
        throw mkexception(1038, "expression doesn't evaluate as object");
    
    ShhObject* obj = o.toObject();

    try
    {
        if (obj->hasMethod(m_property_name))
        {
            return obj->executeMethod(m_property_name, NULL);
        }

    } 
    catch(ShhObjectException* ex)
    {
        throw wrap(1011, ex);
    }

    try 
    {
       
        return obj->getProperty(m_property_name);

    } catch (ShhObjectException* ex) {

        throw wrap(1002, ex);
    }
}


ShhValue& ShhPropertyRef::lvalue()
{
    ShhValue& o = m_object->lvalue();
    if (!o.isObject())
        throw mkexception(1038, "expression doesn't evaluate as object");

    ShhObject* obj = o.toObject();
    if (obj == NULL)
        throw mkexception(1039, "object is NULL");

    try 
    {
        return obj->getProperty(m_property_name);

    } catch (ShhObjectException* ex) {

        throw wrap(1040, ex);
    }
}


ShhValueMethodCall::ShhValueMethodCall(ShhExpression* object, const char* method_name, ShhExpressionList* args)
{
    m_object = object;
    m_method_name = method_name;
    m_args = args;
}

ShhValue ShhValueMethodCall::evaluate()
{
    ShhValue base = m_object->evaluate();
    ShhObject* obj = requireObjectValue(base);

    try 
    {
        if (m_args == NULL || m_args->size() == 0)
            return obj->executeMethod(m_method_name, NULL);
    } 
    catch(ShhObjectException* ex)
    {
        throw wrap(1012, ex);
    }

    
    // evaluate arguments
    ShhValueList args;
    for(int i=0,n=m_args->size(); i<n; i++)
    {
        ShhValue value = m_args->get(i)->evaluate();
        args.add(value.clone());
    }

    try 
    {
        return obj->executeMethod(m_method_name, &args);
    }
    catch(ShhObjectException* ex)
    {
        throw wrap(1013, ex);
    }
}




ShhConcat::ShhConcat(ShhExpression* left, ShhExpression* right)
{
    m_left = left;
    m_right = right;
}

ShhValue ShhConcat::evaluate()
{
    string L, R;
    m_left->evaluate().toString(L);
    m_right->evaluate().toString(R);
    int size = L.length() + R.length() + 1;
    char* result = (char*) m_module->scratch().malloc( size );
    memcpy(result, L, L.length());
    memcpy(result + L.length(), R, R.length() + 1);
    
    ShhValue v(result);
    return v;
}



ShhFunctionCall::ShhFunctionCall(const char* function, ShhExpressionList* args)
{
    m_function = function;
    if (args != NULL) 
        m_args = args;
    else
        m_args = ShhExpressionList::null;
}

ShhValue ShhFunctionCall::evaluate()
{
    
    // evaluate arguments
    ShhValueList args;
    if (m_args != NULL)
    {
        for(int i=0, n=m_args->size(); i<n; i++)
        {
            ShhValue arg = m_args->get(i)->evaluate();
            args.add(arg.clone());
        }
    }

    // execute function
    try
    {
        return m_module->executeFunction(m_function, args);
    }
    catch(ShhObjectException* oex)
    {
        throw wrap(oex->code(), oex);
    }
    
}



///////////////////////////////////////////////////////////////////
// PREDICATE NODES (BOOLEAN EXPRESSIONS)
///////////////////////////////////////////////////////////////////

ShhComparison::ShhComparison(int op, ShhExpression* left, ShhExpression* right)
{
    m_operator = op;
    m_left = left;
    m_right = right;
}

bool ShhComparison::check()
{
    ShhValue lv = m_left->evaluate();
    ShhValue rv = m_right->evaluate();

    switch(m_operator)
    {
    case '<': return lv < rv;
    case '>': return lv > rv;
    case '=': return lv == rv;
    case NE:  return lv != rv;
    case LE:  return lv <= rv;
    case GE:  return lv >= rv;
    default:
        throw mkexception(1015, "unknown boolean operator: %d", m_operator);
    }

    
}


ShhBooleanArithmetic::ShhBooleanArithmetic(int op, ShhPredicate* left, ShhPredicate* right)
{
    m_operation = op;
    m_left = left;
    m_right = right;
}

bool ShhBooleanArithmetic::check()
{
    switch(m_operation)
    {
    case AND:  return m_left->check() && m_right->check(); 
    case OR:   return m_left->check() || m_right->check(); 
    case NOT:  return !m_left->check();
    default:
        throw mkexception(1014, "unknown boolean connector: %d", m_operation);
    }
}


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


ShhBatch::ShhBatch(ShhExecutable* first)
{
    if (first != NULL) m_statements.add(first);
}

void ShhBatch::execute()
{
    for(int i=0,n=m_statements.size(); i<n; i++)
    {
        m_statements.get(i)->execute();
    }
}

ShhBatch* ShhBatch::add(ShhExecutable* statement)
{
    if (statement != NULL) m_statements.add(statement);
    return this;
}


ShhAssignment::ShhAssignment(ShhExpression* lvalue, ShhExpression* ex)
: m_lvalue(lvalue)
{
    m_expression = ex;
}

void ShhAssignment::execute()
{
    ShhValue& lvalue = m_lvalue->lvalue();
    ShhValue  rvalue = m_expression->evaluate();
    lvalue = rvalue;
}

ShhObjectCtor::ShhObjectCtor(const char* type, ShhExpressionList* args)
: m_type(type)
{
    m_args = args;
}

ShhValue ShhObjectCtor::evaluate()
{
    ShhValueList params; m_args->evaluate(params);
    try
    {
        ShhObject* object = m_module->createObject(m_type, m_location);
        object->constructor(&params);
        ShhValue tmp(object);
        return tmp;
    }
    catch(ShhObjectException *oex)
    {
        throw ShhNode::wrap(1023, oex);
    }
}



ShhPrint::ShhPrint(ShhExpression* ex, bool newline_after)
{

⌨️ 快捷键说明

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