예제 #1
0
void PythonEngineAgros::materialValues(const QString &function, double from, double to,
                                       QVector<double> *keys, QVector<double> *values, int count)
{
    if (function.isEmpty())
        return;

    // function
    bool succesfulRun = runExpression(function);
    if (!succesfulRun)
    {
        ErrorResult result = currentPythonEngineAgros()->parseError();
        qDebug() << "Function: " << result.error();
    }

    // prepare keys
    double step = (to - from) / (count - 1);
    QString keysVector = "[";
    for (int i = 0; i < count; i++)
    {
        double key = from + i * step;
        keys->append(key);

        if (i == 0)
            keysVector += QString("%1").arg(key + EPS_ZERO);
        else if (i == (count - 1))
            keysVector += QString(", %1]").arg(key - EPS_ZERO);
        else
            keysVector += QString(", %1").arg(key);
    }

    // run expression
    runExpression(QString("agros2d_material_values = agros2d_material_eval(%1)").arg(keysVector));

    // extract values
    PyObject *result = PyDict_GetItemString(m_dict, "agros2d_material_values");
    if (result)
    {
        Py_INCREF(result);
        for (int i = 0; i < count; i++)
            values->append(PyFloat_AsDouble(PyList_GetItem(result, i)));
        Py_XDECREF(result);
    }

    // remove variables
    runExpression("del agros2d_material; del agros2d_material_values");

    // error during execution
    if (keys->size() != values->size())
    {
        keys->clear();
        values->clear();
    }
}
예제 #2
0
bool PythonEngine::runExpressionConsole(const QString &expression)
{
    bool successfulRun = runExpression(expression);
    emit executedScript();

    return successfulRun;
}
예제 #3
0
static bool runFunctionCall(ASTNode* node, MemoryStack* stack, Scope* scope, RuntimeError* error, Value* result)
{
    assert(node->nodeType == AST_FUNCTION_CALL);

    bool stillWorking = true;

    // TODO: change this to temporary memory?
    Scope identifierScope = makeScope(nullptr);
    FunctionIdentifier identifier = {};

    if (calcFunctionIdentifier(scope, &identifierScope, stack, error, node, &identifier))
    {
        Function* funcToCall = getFunction(scope, identifier);
        if (funcToCall)
        {
            Scope functionScope = makeScope(scope);

            ListIterator<ASTNode> iterator = makeIterator(&node->functionCall.arguments);
            ListIterator<Argument> iterator2 = makeIterator(&funcToCall->identifier.arguments);
            while (stillWorking && hasNext(&iterator))
            {
                ASTNode* node = getNext(&iterator);
                Argument* argFunctionRecieves = getNext(&iterator2);

                Variable* var =
                    defineAVariable(argFunctionRecieves->identifier, argFunctionRecieves->type, stack, &functionScope);

                stillWorking = runExpression(node, stack, scope, error, &var->value);
            }

            if (stillWorking)
            {
                assert(!hasNext(&iterator) && !hasNext(&iterator2));

                if (funcToCall->type == FT_INTERNAL)
                    stillWorking = runStatement(funcToCall->body, stack, &functionScope, error);
                else
                    funcToCall->func(funcToCall->identifier.name, &functionScope.variables, result);
                // TODO: externals error checking?
            }

            scopeFreeMemory(&functionScope, stack);
        }
        else
        {
            *error = RuntimeError{ RET_UNDEFINED_FUNCTION, identifier.name, node->functionCall.lineNumber };
            stillWorking = false;
        }
    }
    else
        stillWorking = false;

    scopeFreeMemory(&identifierScope, stack);
    return stillWorking;
}
예제 #4
-1
static bool runStatement(ASTNode* node, MemoryStack* stack, Scope* scope, RuntimeError* error)
{
    switch (node->nodeType)
    {
        case AST_STATEMENT_TYPE_DEFINITION:
        {
            if (getTypeDefinition(scope, node->typeDefinition.identifier, false))
            {
                *error = RuntimeError{
                    RET_TYPE_ALREADY_DEFINED,
                    node->typeDefinition.identifier,
                    node->typeDefinition.lineNumber
                };

                return false;
            }
            else
            {
                TypeDefinition* typeDef = scopePushToList(scope, stack, &scope->types);
                typeDef->identifier = node->typeDefinition.identifier;
                typeDef->members = {};

                ListIterator<ASTNode> iterator = makeIterator(&node->typeDefinition.definitions);

                int currOffsetInBytes = 0;
                while (hasNext(&iterator))
                {
                    ASTNode* node = getNext(&iterator);

                    StructMember* member = scopePushToList(scope, stack, &typeDef->members);
                    member->identifier = node->variableDeclaration.identifier;
                    member->type = makeType(scope, node->variableDeclaration.typeIdentifier);
                    member->offsetInBytes = currOffsetInBytes;

                    currOffsetInBytes += member->type.definition->totalSizeInBytes;
                }

                typeDef->totalSizeInBytes = currOffsetInBytes;
                return true;
            }
        } break;

        case AST_STATEMENT_VARIABLE_DECLARATION:
        {
            if (getVariable(scope, node->variableDeclaration.identifier, false))
            {
                *error = RuntimeError{ RET_VARIABLE_ALREADY_DEFINED, node->variableDeclaration.identifier, node->variableDeclaration.lineNumber };
                return false;
            }
            else
            {
                Variable* var = defineAVariable(
                    node->variableDeclaration.identifier,
                    makeType(scope, node->variableDeclaration.typeIdentifier), stack, scope);

                if (node->variableDeclaration.expression)
                    return runExpression(node->variableDeclaration.expression, stack, scope, error, &var->value);
                else
                    return true; // TODO: set default value
            }
        } break;

        case AST_STATEMENT_FUNCTION_DEFINITION:
        {
            Function func;

            func.type = FT_INTERNAL;
            func.identifier.name = node->functionDefinition.identifier;
            func.identifier.arguments = {};

            bool stillWorking = true;
            if (!node->functionDefinition.returnType)
                func.returnType = Type{ nullptr, 0 };
            else
            {
                func.returnType = makeType(scope, node->functionDefinition.returnType);
                if (!func.returnType.definition)
                {
                    *error = RuntimeError{ RET_UNDEFINED_TYPE, node->functionDefinition.returnType->typeIdentifier.name, node->functionDefinition.lineNumber };
                    stillWorking = false;
                }
            }

            ListIterator<ASTNode> args = makeIterator(&node->functionDefinition.arguments);
            while (stillWorking && hasNext(&args))
            {
                ASTNode* arg = getNext(&args);

                Argument* argument = scopePushToList(scope, stack, &func.identifier.arguments);
                argument->identifier = arg->variableDeclaration.identifier;
                argument->type = makeType(scope, arg->variableDeclaration.typeIdentifier);

                if (!argument->type.definition)
                {
                    *error = RuntimeError{ RET_UNDEFINED_TYPE, arg->variableDeclaration.typeIdentifier->typeIdentifier.name, arg->variableDeclaration.lineNumber };
                    stillWorking = false;
                }
            }

            func.body = node->functionDefinition.body;

            Function* hasFunc = getFunction(scope, func.identifier, false);
            if (hasFunc)
            {
                *error = RuntimeError{ RET_FUNCTION_ALREADY_DEFINED, node->functionDefinition.identifier, node->functionDefinition.lineNumber };
                stillWorking = false;
            }
            else
            {
                *scopePushToList(scope, stack, &scope->functions) = func;
            }

            return stillWorking;
        } break;

        case AST_STATEMENT_IF:
        {
            Scope ifScope = makeScope(scope);
            Value conditionResult = pushValue(&ifScope, stack, Type{ getTypeDefinition(scope, makeSlice("s32")), false });

            bool stillWorking = runExpression(node->ifStatement.condition, stack, scope, error, &conditionResult);

            if (stillWorking)
            {
                if (*(int*)conditionResult.memory != 0)
                {
                    stillWorking = runStatement(node->ifStatement.ifCase, stack, &ifScope, error);
                }
                else if (node->ifStatement.elseCase != nullptr)
                {
                    stillWorking = runStatement(node->ifStatement.elseCase, stack, &ifScope, error);
                }
            }

            scopeFreeMemory(&ifScope, stack);
            return stillWorking;
        } break;

        case AST_STATEMENT_WHILE:
        {
            Scope whileScope = makeScope(scope);
            Value conditionResult = pushValue(&whileScope, stack, Type{ getTypeDefinition(scope, makeSlice("s32")), false });

            bool stillWorking = runExpression(node->whileStatement.condition, stack, scope, error, &conditionResult);
            if (stillWorking)
            {
                while (*(int*)conditionResult.memory != 0)
                {
                    if (!(stillWorking = runStatement(node->whileStatement.body, stack, &whileScope, error))) break;
                    if (!(stillWorking = runExpression(node->whileStatement.condition, stack, scope, error, &conditionResult))) break;
                }
            }

            scopeFreeMemory(&whileScope, stack);
            return stillWorking;
        } break;

        case AST_STATEMENT_ASSIGNMENT:
        {
            Value value; 
            if (getValue(scope, node->assignment.lValue, error, &value))
            {
                return runExpression(node->assignment.expression, stack, scope, error, &value);
            }
            else
                return false;
        } break;

        case AST_STATEMENTS_BLOCK:
        {
            Scope blockScope = makeScope(scope);
            bool result = runStatements(&node->statementsBlock.statements, stack, &blockScope, error);
            scopeFreeMemory(&blockScope, stack);

            return result;
        } break;

        case AST_FUNCTION_CALL:
        {
            return runFunctionCall(node, stack, scope, error, nullptr);
        } break;

        default:
        {
            assert(!"this is not a statement!");
            return false;
        } break;
    }
}