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

📄 nodes.cpp

📁 Shorthand是一个强大的脚本语言
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    m_expression = ex;
    m_newline_after = newline_after;
}

void ShhPrint::execute()
{
    string s;
    ShhValue value = m_expression->evaluate();
    value.toString(s);
    if (m_newline_after) s.append('\n');
    m_module->puts(s);
}


ShhHTML::ShhHTML(const char* content)
{
    m_content = content;
}

void ShhHTML::execute()
{
    m_module->puts(m_content);
}



ShhConditionBlock::ShhConditionBlock(ShhPredicate* predicate, ShhExecutable* then_block, ShhExecutable* else_block)
{
    m_predicate = predicate;
    m_then = then_block;
    m_else = else_block;

}

void ShhConditionBlock::execute()
{
    bool cond = m_predicate->check();
    if (cond) {
        if (m_then != NULL) m_then->execute();
    } else {
        if (m_else != NULL) m_else->execute();
    }
}


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

}

void ShhVoidMethodCall::execute()
{
    
    ShhValue base = m_object->evaluate();
    ShhObject* obj = requireObjectValue(base);
    try {
        ShhValueList params;
        m_args->evaluate(params);
        obj->executeMethod(m_method_name, &params);
    } 
    catch (ShhObjectException* ex)
    {
        throw wrap(1021, ex);
    }
}

ShhPropertyAssignment::ShhPropertyAssignment(const char* object_name, const char* prop_name, ShhExpression* expression)
{
    m_object_name = object_name;
    m_property_name = prop_name;
    m_expression = expression;
}

void ShhPropertyAssignment::execute()
{
    ShhObject* obj = requireObjectVariable(m_object_name);
    obj->setProperty(m_property_name, m_expression->evaluate());
}


void ShhLoop::execute()
{
    ShhLoop* outer_loop = m_module->m_current_loop;
    m_module->m_current_loop = this;

    m_break_requested = false;
    m_continue_requested = false;

    try
    {
        loop();
    }
    catch(ShhLoopInterruption* irq)
    {
        // loop itself should catch this exception
        delete irq;
    }
    catch(...) 
    {
        m_module->m_current_loop = outer_loop;
        throw;
    }
    m_module->m_current_loop = outer_loop;
}


ShhGrid::ShhGrid(const char* object_name, ShhExecutable* body, 
    ShhExpression* start, ShhExpression* end
)
{
    m_object_name = object_name;
    m_body = body;
    m_start = start;
    m_end = end;
}

void ShhGrid::loop()
{
    ShhObject* obj = requireObjectVariable(m_object_name);

    //fputs("<TABLE>\n", stdout);

    try 
    {
        obj->executeMethod("EXECUTE", NULL);
        
        int hasnext = 1;
        int rownum = 0;

        int start = m_start ? m_start->evaluate().toInt() : 0;
        int end   = m_end   ? m_end->evaluate().toInt() : -1;

        if (start > 1)
        {
            for(int i=1; i<start; i++)
            {
               hasnext = obj->executeMethod("NEXT", NULL).toInt(); 
               if (!hasnext) break;
               rownum++;
            }
        }

        if (!hasnext) return;

        while( true )
        {
            rownum = obj->executeMethod("ROWNUM", NULL).toInt();

            if (end > 0 && rownum >= end) break;

            if(! obj->executeMethod("NEXT", NULL).toInt() )
                 break;

            try 
            {
                m_body->execute();
            }
            catch(ShhLoopInterruption* irq)
            {
                delete irq;
                if (m_break_requested) break;
            }

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

    //fputs("</TABLE>\n", stdout);

}


ShhWhileLoop::ShhWhileLoop(ShhPredicate* predicate, ShhExecutable* body)
{
    m_predicate = predicate;
    m_body = body;
}


void ShhWhileLoop::loop()
{
    bool b;
    while( (b = m_predicate->check()) == true )
    {
        try
        {
            m_body->execute();
        }
        catch(ShhLoopInterruption* irq)
        {
            delete irq;
            if (m_break_requested) break;
        }
    }
}


ShhForLoop::ShhForLoop(const char* counter, ShhExpression* from, ShhExpression* to, ShhExecutable* body)
{
    m_counter = NULL;
    m_counter_name = counter;
    m_from = from;
    m_to = to;
    m_body = body;
}

void ShhForLoop::loop()
{
    int from = m_from->evaluate().toInt();
    int to   = m_to->evaluate().toInt();

    if (to < from) { int tmp = to; to = from; from = tmp; }

    m_counter = m_module->var(m_counter_name);
    m_counter->value() = from;

    for(int i=from; i<=to; i++)
    {
        m_counter->value() = i;
        try
        {
            m_body->execute();
        }
        catch(ShhLoopInterruption* irq)
        {
            delete irq;
            if (m_break_requested) break;
        }
    }
}

ShhForeachLoop::ShhForeachLoop(ShhExpression* subject, ShhExpression* index, ShhExpression* value, ShhExecutable* body)
{
    m_subject = subject;
    m_index = index;
    m_value = value;
    m_body = body;
}

void ShhForeachLoop::loop()
{
    ShhValue subject = m_subject->evaluate();
    ShhHash* hash = subject.toHash();
    if (hash == NULL) return;
    ShhHashIterator iterator;
    hash->createIterator(iterator);
    
    ShhValue indexValue;
    ShhValue elementValue;

    while(iterator.next(indexValue, elementValue))
    {
        if (m_index != NULL) m_index->lvalue() = indexValue;
        if (m_value != NULL) m_value->lvalue() = elementValue;
        try
        {
            m_body->execute();
        }
        catch(ShhLoopInterruption* irq)
        {
            delete irq;
            if (m_break_requested) break;
        }
    }
}



ShhContinue::ShhContinue()
{
}

void ShhContinue::execute()
{
    if (m_module->m_current_loop == NULL)
        throw mkexception(1016, "CONTINUE used outside loop");
    m_module->m_current_loop->m_continue_requested = true;
    throw new ShhLoopInterruption();
}


ShhBreak::ShhBreak()
{
}

void ShhBreak::execute()
{
    if (m_module->m_current_loop == NULL)
        throw mkexception(1015, "BREAK used outside loop");
    m_module->m_current_loop->m_break_requested = true;
    throw new ShhLoopInterruption();
}



ShhInclude::ShhInclude(ShhExpression* name) : m_name(name)
{
}

void ShhInclude::execute()
{
    string name; m_name->evaluate().toString(name);
    m_module->switch_module(*this, name, true, 0);
}

ShhJump::ShhJump(ShhExpression* name) : m_name(name)
{
}

void ShhJump::execute()
{
    string name; m_name->evaluate().toString(name);
    m_module->switch_module(*this, name, false, 0);
}


ShhDefun* ShhDefunList::find(const char* name)
{
    for(int i=0,n=m_size; i<n; i++)
    {
        ShhDefun* f = get(i);
        if (stricmp(f->m_name, name) == 0) return f;
    }
    return NULL;
}

ShhLocalDecl::ShhLocalDecl(const char* name, ShhExpression* ex)
: m_name(name), m_expression(ex)
{
}

void ShhLocalDecl::execute()
{
    ShhModule* top = m_module->top();
    ShhVariableList* locals = top->m_locals;
    if (locals == NULL)
        throw mkexception(1031, "local declarations are valid only inside functions");

    ShhVariable* var = locals->find(m_name);
    if (var != NULL)
    {
        throw mkexception(1032, "local variable %s is already defined in this scope", m_name.cstr());
    }

    ShhValue initializer;
    if (m_expression != NULL) initializer = m_expression->evaluate();

    var = new ShhVariable(m_name);
    var->value() = initializer;
    locals->add(var);
}

/**
 * ShhDefun UDF definition.
 */
ShhDefun::ShhDefun(const char* name, ShhParameterList* parameters, ShhBatch* body)
: ShhFunction(name), m_name(name), m_parameters(parameters), m_body(body)
{
}

void ShhDefun::paste_location(string& location)
{
    location.printf("at %s:%d", m_module->getName(), m_location.first_line);
}

/**
 * execute() method DEFINES function, doesn't execute it
 */
void ShhDefun::execute()
{
    ShhDefunList& list = m_module->getFunctionList();
    ShhDefun* ef = list.find(ShhDefun::m_name);
    
    if (ef != NULL)
    {
        string other_location;
        ef->paste_location(other_location);
        throw mkexception(1028, "function has already been defined %s", other_location.cstr());
    }
    list.add(this);
}

/**
 * This is actual execution method of ShhFunction interface that 
 * DOES execute the function
 */
ShhValue ShhDefun::execute(ShhModule* module, const ShhValueList& args) const
{
    ShhValue returnValue;
    ShhModule* top = m_module->top();
    ShhVariableList* old_locals = top->m_locals;
    try 
    {
        ShhVariableList locals;
        for(int i=0,n=m_parameters->size(); i<n; i++)
        {
            ShhVariable* var = new ShhVariable(m_parameters->get(i)->name());
            locals.add(var);
            if (args.hasIndex(i))
                var->value() = *(args.get(i));
            else
                var->value() = ShhValue::EMPTY;
        }
        top->m_locals = &locals;
        try
        {
            m_body->execute();
        }
        catch(ShhReturnException*)
        {
        }
        top->m_locals = old_locals;

    } 
    catch (ShhObjectException* ex) 
    {

        m_module->m_locals = old_locals;
        throw wrap(1029, ex);
    }
    return returnValue;
}


ShhReturn::ShhReturn(ShhExpression* expression)
{
    m_expression = expression;
}

void ShhReturn::execute()
{
    ShhValue* result = m_module->top()->m_return_value;   
    
    if (result == NULL)
        throw mkexception(1030, "RETURN outside function");
    ShhValue value = m_expression->evaluate();
    *(result) = value;
    throw new ShhReturnException();

}


ShhArrayElement::ShhArrayElement(ShhExpression* object, ShhExpression* index)
{
    m_object = object;
    m_index = index;
}

ShhValue ShhArrayElement::evaluate()
{
    ShhValue indexObject = m_index->evaluate();
    int index = indexObject.toInt();
    ShhValue object = m_object->evaluate();
    if (!object.isArray())
    {
        return ShhValue::null();
        //throw mkexception(1048, "object is not array");
    }
    ShhArray* array = object.toArray();
    return array->get(index);
}

ShhValue& ShhArrayElement::lvalue()
{
    ShhValue indexObject = m_index->evaluate();
    int index = indexObject.toInt();
    ShhValue& object = m_object->lvalue();
    if (!object.isArray())
    {
        object.setArray((ShhArray*) m_module->createObject("ARRAY", m_location));
    }
    ShhArray* array = object.toArray();
    array->growTo(index);
    if (index+1 > array->size()) array->setCount(index+1);
    return array->get(index);
}

ShhHashElement::ShhHashElement(ShhExpression* object, ShhExpression* index)
{
    m_object = object;
    m_index = index;
}

ShhValue ShhHashElement::evaluate()
{
    ShhValue indexObject = m_index->evaluate();
    ShhValue object = m_object->evaluate();
    if (!object.isHash())
    {
        return ShhValue::null();
        //throw mkexception(1048, "object is not array");
    }
    ShhHash* hash = (ShhHash*) object.toHash();
    return hash->rvalue(indexObject);
}

ShhValue& ShhHashElement::lvalue()
{
    ShhValue indexObject = m_index->evaluate();
    ShhValue& object = m_object->lvalue();
    if (!object.isHash())
    {
        object.setHash((ShhHash*) m_module->createObject("HASH", m_location));
    }
    ShhHash* hash = object.toHash();
    return hash->lvalue(indexObject);
}

⌨️ 快捷键说明

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