📄 nodes.cpp
字号:
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, ¶ms);
}
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 + -