Beispiel #1
0
ekBool ekCompilerFormatErrors(ekCompiler *compiler, ekString *output)
{
    struct ekContext *E = compiler->E;
    ekS32 i;
    for(i = 0; i < ekArraySize(E, &compiler->errors); i++)
    {
        ekError *error = compiler->errors[i];
        ekStringConcat(E, output, ekStringSafePtr(&error->filename));
        ekStringConcat(E, output, ":");
        appendInt(E, output, error->lineNo);
        ekStringConcat(E, output, ":");
        appendInt(E, output, error->col + 1); // "column" in an error is 1-indexed
        ekStringConcat(E, output, ": error: ");
        ekStringConcat(E, output, ekStringSafePtr(&error->explanation));
        ekStringConcat(E, output, "\n");

        if(error->line.len > 0)
        {
            ekS32 caratPos = error->col;

            ekStringConcat(E, output, ekStringSafePtr(&error->line));
            ekStringConcat(E, output, "\n");

            // draw the carat!
            for(; caratPos > 0; --caratPos)
            {
                ekStringConcat(E, output, " "); // how about that efficiency! /s
            }
            ekStringConcat(E, output, "^\n");
        }
    }
    return (ekArraySize(E, &compiler->errors) > 0) ? ekTrue : ekFalse;
}
Beispiel #2
0
static void ekCompileOptimizeArray(struct ekContext *E, ekCompiler *compiler, ekSyntax **a)
{
    ekS32 i;
    for(i = 0; i < ekArraySize(E, &a); i++)
    {
        ekCompileOptimizeChild(E, compiler, (ekSyntax *)a[i]);
    }
}
Beispiel #3
0
static void ekSyntaxDotRecurseArray(struct ekContext *E, ekSyntax **a, const char *myLineOpts, ekSyntax *syntax)
{
    ekS32 i;
    const char *childLineOpts = myLineOpts;
    for(unsigned int i = 0; i < ekArraySize(E, &a); i++)
    {
        REC_CHILD(a[i]);
    }
}
Beispiel #4
0
ekBool ekCompile(ekCompiler *compiler, const char *sourcePath, const char *source, ekU32 compileOpts)
{
    struct ekContext *E = compiler->E;
    ekBool success = ekFalse;
    ekToken emptyToken = {0};
    void *parser;

    compiler->sourcePath = sourcePath;
    compiler->source = source;

#ifdef EUREKA_TRACE_PARSER
    ekParseTrace(stderr, "--- ");
#endif

    ekTraceMem(("\n                                     "
                "--- start chunk compile ---\n"));

    parser = ekParseAlloc(E);
    compiler->root = NULL;

    ekLex(parser, source, ekParse, compiler);
    ekParse(parser, 0, emptyToken, compiler);

    if(compiler->root)
    {
        if(ekArraySize(E, &compiler->errors))
        {
            ekSyntaxDestroy(E, compiler->root);
            compiler->root = NULL;
        }
        else
        {
            if(compileOpts & ECO_OPTIMIZE)
            {
                ekCompileOptimize(E, compiler);
            }

            ekAssemble(E, compiler, ekTrue);
            success = ekTrue;

            if(!(compileOpts & ECO_KEEP_SYNTAX_TREE))
            {
                ekSyntaxDestroy(E, compiler->root);
                compiler->root = NULL;
            };
        }
    }

    ekParseFree(E, parser);

    ekTraceMem(("                                     "
                "---  end  chunk compile ---\n\n"));

    compiler->sourcePath = NULL;
    compiler->source = NULL;
    return success;
}
Beispiel #5
0
void ekCompileExplainError(ekCompiler *compiler, const char *explanation)
{
    ekS32 size = ekArraySize(compiler->E, &compiler->errors);
    if(size > 0)
    {
        ekError *error = compiler->errors[size - 1];
        ekStringSet(compiler->E, &error->explanation, explanation);
    }
}
Beispiel #6
0
ekS32 ekValueTypeId(struct ekContext *E, int format)
{
    ekS32 i;
    for(i=0; i<ekArraySize(E, &E->types); ++i)
    {
        ekValueType *t = E->types[i];

        if(t->format && (t->format == format))
        {
            return i;
        }
    }
    return -1;
}
Beispiel #7
0
ekSyntax * ekSyntaxCreateStatementExpr(struct ekContext * E, ekSyntax * expr)
{
    ekSyntax * syntax;

    if ((expr->type == EST_EXPRESSIONLIST) && (ekArraySize(E, &expr->v.a) == 0)) {
        // An empty statement. Without PYTHON_SCOPING, this only happens
        // when there are multiple semicolons in a row. However, when
        // it is enabled, one is created for every blank line!
        ekSyntaxDestroy(E, expr);
        return NULL;
    }

    syntax = ekSyntaxCreate(E, EST_STATEMENT_EXPR, expr->line);
    syntax->v.p = expr;
    return syntax;
}
Beispiel #8
0
ekS32 ekValueTypeRegister(struct ekContext *E, ekValueType *newType)
{
    ekS32 i;
    for(i=0; i<ekArraySize(E, &E->types); ++i)
    {
        ekValueType *t = E->types[i];
        if(!strcmp(newType->name, t->name))
        {
            return EVT_INVALID;
        }
    }

    // If you are hitting one of these asserts, then your custom type isn't handling a required function.
    // If you're a C++ person, pretend the compiler is telling you that you forgot to implement a pure virtual.
    // If you don't want to do anything for a particular function, explicitly set it to ekValueTypeFuncNotUsed.
    ekAssert(newType->funcDump); // required!

    newType->id = ekArrayPush(E, &E->types, newType);
    return newType->id;
}
Beispiel #9
0
static void ekSyntaxDotRecurse(struct ekContext *E, ekSyntax *syntax, const char *myLineOpts, ekSyntax *parent)
{
    char label[512];
    const char *myOpts = "shape=ellipse";
    const char *childLineOpts = NULL;

    if(!myLineOpts)
    {
        myLineOpts = "style=solid";
    }

    sprintf(label, "??: %d", syntax->type);

    switch(syntax->type)
    {

        case EST_KSTRING:
        {
            char *c;
            myOpts = "shape=house,color=blueviolet";
            sprintf(label, "K: \\\"%s\\\"", syntax->v.s);
            c = label;
            while(*c)
            {
                switch(*c)
                {
                    case '\n':
                    case '\t':
                    case '\r':
                        *c = ' ';
                        break;
                };
                c++; // this never gets old.
            };
        }
        break;

        case EST_KINT:
        {
            myOpts = "shape=house,color=blueviolet";
            sprintf(label, "%d", syntax->v.i);
        }
        break;

        case EST_KFLOAT:
        {
            myOpts = "shape=house,color=blueviolet";
            sprintf(label, "%3.3f", syntax->v.f);
        }
        break;

        case EST_BOOL:
        {
            myOpts = "shape=house,color=blueviolet";
            if(syntax->v.i)
                sprintf(label, "true");
            else
                sprintf(label, "false");
        }
        break;

        case EST_IDENTIFIER:
        {
            myOpts = "shape=house";
            sprintf(label, "V: \\\"%s\\\"", syntax->v.s);
        }
        break;

        case EST_INDEX:
        {
            strcpy(label, "Index");
            childLineOpts = "style=dotted,label=array";
            REC_CHILD(syntax->l.p);
            childLineOpts = "style=dotted,label=index";
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_STATEMENTLIST:
        {
            myOpts = "shape=box";
            strcpy(label, "StatementList");
            REC_ARRAY(syntax->v.a);
        }
        break;

        case EST_EXPRESSIONLIST:
        {
            if(ekArraySize(E, &syntax->v.a))
            {
                myOpts = "shape=egg";
                strcpy(label, "ExprList");
            }
            else
            {
                myOpts = "shape=egg, color=red";
                strcpy(label, "Stub");
            }
            REC_ARRAY(syntax->v.a);
        }
        break;

        case EST_IDENTIFIERLIST:
        {
            strcpy(label, "IdentList");
            if(syntax->v.i)
            {
                strcat(label, " [var]");
            }
            REC_ARRAY(syntax->v.a);
        }
        break;

        case EST_ARRAY:
        {
            strcpy(label, "Array");
            REC_CHILD(syntax->v.p);
        }
        break;

        case EST_MAP:
        {
            strcpy(label, "Map");
            REC_CHILD(syntax->v.p);
        }
        break;

        case EST_CALL:
        {
            myOpts = "shape=invtrapezium,color=blue";
            sprintf(label, "Call: %s(%d)", (syntax->v.s) ? syntax->v.s : "CFUNC", (ekS32)ekArraySize(E, &syntax->r.p->v.a));
            childLineOpts = "style=dotted,label=args";
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_STRINGFORMAT:
        {
            strcpy(label, "% (format)");
            childLineOpts = "style=dotted,label=format";
            REC_CHILD(syntax->l.p);
            childLineOpts = "style=dotted,label=args";
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_NULL:
        {
            myOpts = "shape=house,color=blueviolet";
            strcpy(label, "null");
        }
        break;

        case EST_THIS:
        {
            myOpts = "shape=house,color=blueviolet";
            strcpy(label, "this");
        }
        break;

        case EST_NOT:
        {
            strcpy(label, "Not (logical)");
            REC_CHILD(syntax->v.p);
        }
        break;

        case EST_BITWISE_NOT:
        {
            strcpy(label, "Not (bitwise)");
            REC_CHILD(syntax->v.p);
        }
        break;

        case EST_BITWISE_XOR:
        {
            if(syntax->v.i)
            {
                strcpy(label, "^= (xor)");
            }
            else
            {
                strcpy(label, "xor");
            }
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_BITWISE_AND:
        {
            if(syntax->v.i)
            {
                strcpy(label, "&= (bitwise and)");
            }
            else
            {
                strcpy(label, "And (bitwise)");
            }
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_BITWISE_OR:
        {
            if(syntax->v.i)
            {
                strcpy(label, "|= (bitwise or)");
            }
            else
            {
                strcpy(label, "Or (bitwise)");
            }
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_SHIFTLEFT:
        {
            if(syntax->v.i)
            {
                strcpy(label, "<<=");
            }
            else
            {
                strcpy(label, "<<");
            }
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_SHIFTRIGHT:
        {
            if(syntax->v.i)
            {
                strcpy(label, ">>=");
            }
            else
            {
                strcpy(label, ">>");
            }
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_AND:
        {
            strcpy(label, "And (logical)");
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_OR:
        {
            strcpy(label, "Or (logical)");
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_ADD:
        {
            if(syntax->v.i)
            {
                strcpy(label, "+=");
            }
            else
            {
                strcpy(label, "+");
            }
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_SUB:
        {
            if(syntax->v.i)
            {
                strcpy(label, "-=");
            }
            else
            {
                strcpy(label, "-");
            }
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_MUL:
        {
            if(syntax->v.i)
            {
                strcpy(label, "*=");
            }
            else
            {
                strcpy(label, "*");
            }
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_DIV:
        {
            if(syntax->v.i)
            {
                strcpy(label, "/=");
            }
            else
            {
                strcpy(label, "/");
            }
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_STATEMENT_EXPR:
        {
            strcpy(label, "StatementExpr");
            REC_CHILD(syntax->v.p);
        }
        break;

        case EST_ASSIGNMENT:
        {
            strcpy(label, "=");
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_CMP:
        {
            strcpy(label, "cmp");
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_EQUALS:
        {
            strcpy(label, "==");
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_NOTEQUALS:
        {
            strcpy(label, "!=");
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_GREATERTHAN:
        {
            strcpy(label, ">");
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_GREATERTHANOREQUAL:
        {
            strcpy(label, ">=");
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_LESSTHAN:
        {
            strcpy(label, "<");
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_LESSTHANOREQUAL:
        {
            strcpy(label, "<=");
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_INHERITS:
        {
            strcpy(label, "Inherits");
            REC_CHILD(syntax->l.p);
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_BREAK:
        {
            strcpy(label, "Break");
        }
        break;

        case EST_RETURN:
        {
            strcpy(label, "Return");
            if(syntax->v.p)
                REC_CHILD(syntax->v.p);
        }
        break;

        case EST_IFELSE:
        {
            strcpy(label, "IfElse");
            childLineOpts = "style=dotted,label=condition";
            REC_CHILD(syntax->v.p);
            childLineOpts = "style=dotted,label=true";
            REC_CHILD(syntax->l.p);
            if(syntax->r.p)
            {
                childLineOpts = "style=dotted,label=false";
                REC_CHILD(syntax->r.p);
            }
        }
        break;

        case EST_WHILE:
        {
            strcpy(label, "while");
            childLineOpts = "style=dotted,label=cond";
            REC_CHILD(syntax->v.p);
            childLineOpts = "label=body";
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_FOR:
        {
            strcpy(label, "for");
            childLineOpts = "style=dotted,label=vars";
            REC_CHILD(syntax->v.p);
            childLineOpts = "style=dotted,label=iter";
            REC_CHILD(syntax->l.p);
            childLineOpts = "label=body";
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_FUNCTION:
        {
            sprintf(label, "Function: \\\"%s\\\"", syntax->v.s);
            childLineOpts = "style=dotted,label=args";
            REC_CHILD(syntax->l.p);
            childLineOpts = "label=body";
            REC_CHILD(syntax->r.p);
        }
        break;

        case EST_FUNCTION_ARGS:
        {
            sprintf(label, "Function Args");
            childLineOpts = "style=dotted,label=args";
            REC_CHILD(syntax->l.p);
        }
        break;

        case EST_SCOPE:
        {
            sprintf(label, "scope");
            childLineOpts = "label=body";
            REC_CHILD(syntax->v.p);
        }
        break;
    };

    if(parent)
    {
        printf("s%p -> s%p [%s]\n", parent, syntax, myLineOpts);
    }
    printf("s%p [label=\"%s\",%s]\n", syntax, label, myOpts);
}