コード例 #1
0
ファイル: Interpreter.cpp プロジェクト: DRDivider/TWIScript
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;
}
コード例 #2
0
ファイル: Interpreter.cpp プロジェクト: DRDivider/TWIScript
static bool operator==(FunctionIdentifier left, FunctionIdentifier right)
{
    bool argumentsEquality = true;
    ListIterator<Argument> leftIterator = makeIterator(&left.arguments);
    ListIterator<Argument> rightIterator = makeIterator(&right.arguments);

    while (hasNext(&leftIterator) && hasNext(&rightIterator))
    {
        // checks only definitions. Reference types CAN be assigned to a non reference value.
        // Reference only mean that the memory of a 'Value' belongs to another 'Value' and shouldn't be freed
        if (getNext(&leftIterator)->type.definition != getNext(&rightIterator)->type.definition)
        {
            argumentsEquality = false;
            break;
        }
    }

    argumentsEquality = argumentsEquality && (!hasNext(&leftIterator) && !hasNext(&rightIterator));
    return (left.name == right.name) && argumentsEquality;
}
コード例 #3
0
ファイル: Interpreter.cpp プロジェクト: DRDivider/TWIScript
static bool calcFunctionIdentifier(Scope* mainScope, Scope* tmpScope, MemoryStack* stack, RuntimeError* error, ASTNode* node, FunctionIdentifier* result)
{
    assert(node->nodeType == AST_FUNCTION_CALL);

    result->name = node->functionCall.identifier;
    result->arguments = {};

    bool stillWorking = true;

    ListIterator<ASTNode> args = makeIterator(&node->functionCall.arguments);
    while (stillWorking && hasNext(&args))
    {
        ASTNode* node = getNext(&args);
        Argument* arg = scopePushToList<Argument>(tmpScope, stack, &result->arguments);

        arg->identifier = {};

        if (node->nodeType == AST_EXPRESSION_CONSTANT)
        {
            arg->type = Type{ getTypeDefinition(mainScope, makeSlice("s32")), false };
        }
        else if (node->nodeType == AST_EXPRESSION_IDENTIFIER || node->nodeType == AST_EXPRESSION_DOT)
        {
            Value value;
            if (getValue(mainScope, node, error, &value))
            {
                arg->type = value.type;
            }
            else
            {
                stillWorking = false;
            }
        }
        else if (node->nodeType == AST_FUNCTION_CALL)
        {
            FunctionIdentifier identifier = { };
            if (calcFunctionIdentifier(mainScope, tmpScope, stack, error, node, &identifier))
            {
                Function* func = getFunction(mainScope, identifier);
                if (func)
                    arg->type = func->returnType;
                else
                {
                    *error = RuntimeError{ RET_UNDEFINED_FUNCTION, identifier.name, node->functionCall.lineNumber };
                    stillWorking = false;
                }
            }
            else
                stillWorking = false;
        }
    }

    return stillWorking;
}
コード例 #4
0
ファイル: Interpreter.cpp プロジェクト: DRDivider/TWIScript
static bool runStatements(LinkedList<ASTNode>* statements, MemoryStack* stack, Scope* scope, RuntimeError* error)
{
    bool stillWorking = true;

    ListIterator<ASTNode> iterator = makeIterator(statements);
    while (stillWorking && hasNext(&iterator))
    {
        stillWorking = runStatement(getNext(&iterator), stack, scope, error);
    }

    return stillWorking;
}
コード例 #5
0
ファイル: value.cpp プロジェクト: Ehnonymoose/MSE
String ScriptCollectionBase::toCode() const {
	String ret = _("[");
	bool first = true;
	ScriptValueP it = makeIterator();
	while (ScriptValueP v = it->next()) {
		if (!first) ret += _(",");
		first = false;
		// todo: include keys
		ret += v->toCode();
	}
	ret += _("]");
	return ret;
}
コード例 #6
0
ファイル: oplog_interface_mock.cpp プロジェクト: guoyr/mongo
std::unique_ptr<TransactionHistoryIteratorBase> OplogInterfaceMock::makeTransactionHistoryIterator(
    const OpTime& startOpTime) const {
    return std::make_unique<TransactionHistoryIteratorMock>(startOpTime, makeIterator());
}
コード例 #7
0
ファイル: Interpreter.cpp プロジェクト: DRDivider/TWIScript
bool run(ASTNode* mainNode, RuntimeError* error, ExternalFunctions externals, char** libsToLoad, int libsCount)
{
    assert(mainNode->nodeType == AST_MAIN);

    getValueFunc = getGetValueFuncPtr();

    MemoryStack stack = makeMemoryStack(MEGABYTE(16));
    Array<HINSTANCE> libraries = makeArray<HINSTANCE>(KILOBYTE(1));

    Scope scalarTypesScope = makeScope(nullptr);
    Scope globalScope = makeScope(&scalarTypesScope);

    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s64"), {}, 8 });
    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u64"), {}, 8 });
    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("f64"), {}, 8 });

    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s32"), {}, 4 });
    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u32"), {}, 4 });
    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("f32"), {}, 4 });

    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s16"), {}, 2 });
    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u16"), {}, 2 });

    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s8"), {}, 1 });
    pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u8"), {}, 1 });

    ExternalArgumentDefinition binarys32Args[] = { { "a", "s32" }, { "b", "s32" } };
    ExternalArgumentDefinition binaryf32Args[] = { { "a", "f32" }, { "b", "f32" } };
    ExternalDefinition buildInExternals[] = {
        { &scalarS32FuncsHandler, "opAdd", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opSub", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opEqualsOrLess", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opEqualsOrsGreater", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opLess", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opGreater", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opEquals", "s32", binarys32Args, ArrayCount(binarys32Args) },
        { &scalarS32FuncsHandler, "opNot", "s32", binarys32Args, ArrayCount(binarys32Args) },
    };

    loadExternals(&scalarTypesScope, &stack, ExternalFunctions{ buildInExternals, ArrayCount(buildInExternals) });
    loadExternals(&scalarTypesScope, &stack, externals);
    loadLibrariries(&libraries, &scalarTypesScope, &stack, libsToLoad, libsCount);

    bool stillWorking = true;

    // load all global function and type definitions
    ListIterator<ASTNode> iterator = makeIterator(&mainNode->main.statements);
    while (stillWorking && hasNext(&iterator))
    {
        ASTNode* statement = getNext(&iterator);
        if (statement->nodeType == AST_STATEMENT_FUNCTION_DEFINITION ||
            statement->nodeType == AST_STATEMENT_TYPE_DEFINITION)
            stillWorking = runStatement(statement, &stack, &globalScope, error);
        else
        {
            // TODO: illigal statement exception? Or do this on parsing stage? 
        }
    }

    if (stillWorking)
    {
        FunctionIdentifier mainIdentifier = {};
        mainIdentifier.name = makeSlice("main");

        Function* func = getFunction(&globalScope, mainIdentifier);

        if (func != nullptr)
            stillWorking = runStatement(func->body, &stack, &globalScope, error);
        else
        {
            stillWorking = false;
            *error = RuntimeError{ RET_UNDEFINED_FUNCTION, mainIdentifier.name, 0 };
        }
    }

    scopeFreeMemory(&globalScope, &stack);
    scopeFreeMemory(&scalarTypesScope, &stack);

    freeAllLibraries(&libraries);

    freeArray(&libraries);
    freeMemoryStack(&stack);
    return stillWorking;
}
コード例 #8
0
PropInfo * SimplePropStore::partialGet(FastEnvironment * f,const proposition * prop) const
{
	return records.partialGet(makeIterator(f,prop->args->begin()),
							makeIterator(f,prop->args->end()));
};
コード例 #9
-1
ファイル: Interpreter.cpp プロジェクト: DRDivider/TWIScript
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;
    }
}