Пример #1
0
/* parses(source) -> boolean */
int DuckParses(int argument_count, void* data)
{
    L_TOKEN*      lexing;
    char*         buffer;
    int           error = 0;

    VALUE argument = GetRecord("source", gCurrentContext);

    gLastExpression.type = VAL_PRIMITIVE;
    gLastExpression.data.primitive = 0;

    if (argument.type == VAL_STRING) 
    {
        lexing = LexSourceBuffer(argument.data.string, &buffer, CONTEXT_FREE_GRAMMAR);
        if (lexing == NULL) 
        {
            gLastExpression.data.primitive = -1;
            FreeLexing(lexing, buffer);
            //return 1;
            return 0;
        }
        gLastExpression.data.primitive = ParseSucceeds(lexing, PARSE_TABLE, CONTEXT_FREE_GRAMMAR);
        if (gLastExpression.data.primitive == 0) {
            FreeLexing(lexing, buffer);
            return 0;
        }

        /* free lexing */
        FreeLexing(lexing, buffer);
    }

    return error;
}
Пример #2
0
void ClearAllGC()
{
    unsigned int index;
    /* contexts */
    for (index = 0;
         index < gGCManager.ctx_size;
         index++)
    {
        CONTEXT* context = gGCManager.contexts[index];
        ClearContext(context);
    }

    /* functions */
    for (index = 0;
         index < gGCManager.func_size;
         index++)
    {
        FUNCTION* function = gGCManager.functions[index];
        ClearFunction(function);
    }

    /* dictionaries */
    for (index = 0;
         index < gGCManager.table_size;
         index++)
    {
        HASH_TABLE* table = gGCManager.tables[index];
        ClearDictionary(table);
    }

    /* strings */
    for (index = 0;
         index < gGCManager.str_size;
         index++)
    {
        char* string = gGCManager.strings[index];
        ClearString(string);
    }

    /* parse tree */
    AST_STORE *cur_ast, *next_ast;
    cur_ast = gGCManager.parseTrees;
    while (cur_ast) {
        next_ast = cur_ast->next;
        FreeParseTree(cur_ast->parseTree);
        free(cur_ast);
        cur_ast = next_ast;
    }

    /* lexings */
    LEXING_STORE *cur_lex, *next_lex;
    cur_lex = gGCManager.lexings;
    while (cur_lex) {
        next_lex = cur_lex->next;
        FreeLexing(cur_lex->tokens, cur_lex->buffer);
        free(cur_lex);
        cur_lex = next_lex;
    }
}
Пример #3
0
/* eval(source) */
int DuckEval(int argument_count, void* data)
{
    L_TOKEN*      lexing;
    SYNTAX_TREE*  ast;
    char*         buffer;
    int           error = 0;

    VALUE argument = GetRecord("source", gCurrentContext);

    gLastExpression.type = VAL_NIL;
    gLastExpression.data.primitive = 0;

    CLOSURE* currentContext;
    currentContext = gCurrentContext;

    int prev_line_error = line_error;
    SYNTAX_TREE* prev_failed_production = failed_production;

//  if (gCurrentContext->parent) gCurrentContext = gCurrentContext->parent;
    gCurrentContext = gGlobalContext;

    if (argument.type == VAL_STRING) 
    {
        lexing = LexSourceBuffer(argument.data.string, &buffer, CONTEXT_FREE_GRAMMAR);
        if (lexing == NULL) {
            printf("Error lexing source or empty source string.\n");
            FreeLexing(lexing, buffer);
            return 1;
        }
        ast = ParseSource(lexing, PARSE_TABLE, CONTEXT_FREE_GRAMMAR);
        if (ast == NULL) {
            printf("Error parsing source.\n");
            FreeLexing(lexing, buffer);
            return 1;
        }

        /* ReduceProgramAST(&ast); */
        error = InterpretNode(ast);

        if (error)
        {
            printf("%s\n", ErrorMessage(error));
            PrintStackTrace();
            FreeLexing(lexing, buffer);
            FreeParseTree(ast);

            ClearCallStack(&gStackTrace);

            line_error = prev_line_error;
            failed_production = prev_failed_production;

            return 1;
        }

        /* sanitize last expression for use in program */
        //gLastExpression = ReallocStrings(gLastExpression);

        /* free lexing and parse tree */
        //FreeLexing(lexing, buffer);
        //FreeParseTree(ast);
        GCAddLexing(lexing, buffer);
        GCAddParseTree(ast);
    }

    gCurrentContext = currentContext;
    return error;
}
Пример #4
0
/* lex a source buffer for a program */
L_TOKEN* LexSourceBuffer(const char*    source_buffer,
                         char**         stripped,
                         GRAMMAR_TABLE  table)
{
    const char* buffer;
    char*       format;
    int*        lineNumbers;
    int         line;
    int         size;
    int         i, j;
    int         a, b;

    L_TOKEN* start = NULL;
    L_TOKEN* end = NULL;

    buffer = source_buffer;
    size = strlen(buffer);
    
    // count lines
    lineNumbers = (int*)malloc((size+1)*sizeof(int));
    line = 0;
    for (i = 0; i <= size; i++)
    {
        lineNumbers[i] = line;
        if (buffer[i] == '\n')

            line++;
    }

    // strip clean
    format = (char*)malloc(size+1);
    j = 0;
    for (i = 0; i < size; i++)
    {
        if (buffer[i] == '/' &&
            buffer[i+1] == '/')
        {
            // inline comments
            while (i < size && buffer[i] != '\n') i++;
            i--;
        }
        else if (buffer[i] == '/' &&
                 buffer[i+1] == '*')
        {
            // multiline comments
            i++; i++;
            while (i < size - 1 &&
                   (buffer[i] != '*' ||
                    buffer[i+1] != '/'))
            {
                i++;
            }
            i++;
        }
#ifdef IGNORE_MACROS
        else if (buffer[i] == '#')
        {
            while (i < size && buffer[i] != '\n') i++;
            i--;
        }
#endif
#ifdef SEMICOLON_COMMENTS
        else if (buffer[i] == ';')
        {
            while (i < size && buffer[i] != '\n') i++;
            i--;
        }
#endif
        else if (isSpace(buffer[i]))
        {
            // whitespace
            format[j] = ' ';
            lineNumbers[j] = lineNumbers[i];

            while (i < size && isSpace(buffer[i]))
            {
                if (buffer[i] == '\n') {
                    format[j] = '\n';
                    lineNumbers[j] = lineNumbers[i];
                }
                i++;
            }
            i--;
            j++;
        }
        else if (buffer[i] == '"' ||
                 buffer[i] == '\'')
        {
            char quote = buffer[i];
            // string
            format[j++] = buffer[i++];
            while (i < size - 1 && buffer[i] != quote)
            {
                if (buffer[i] == '\\')
                {
                    lineNumbers[j] = lineNumbers[i];
                    format[j++] = buffer[i++];
                }
                lineNumbers[j] = lineNumbers[i];
                format[j++] = buffer[i++];
            }
            lineNumbers[j] = lineNumbers[i];
            format[j++] = buffer[i];
        }
        else
        {
            // character
            lineNumbers[j] = lineNumbers[i];
            format[j] = buffer[i];
            j++;
        }
    }
    
    format[j] = 0;
    size = j;

    // lex
    // printf("Lexing...\n\n");

    for (i = 0; i < size; i++)
    {
        line = lineNumbers[i];
        if (isAlpha(format[i]))
        {
            a = i;
            // alpha
            while (i < size &&
                   (isAlpha(format[i]) ||
                    isNumeric(format[i]) ||
                    format[i] == '_'))
            {
                i++;
            }
            b = i;
            LexAddBlock(&start, &end, IDENTIFIER(format,
                                                 a,
                                                 b,
                                                 line,
                                                 table));
            i--;
        }
        else if (isNumeric(format[i]))
        {
            // numeric
            a = i;
            while (i < size &&
                   isNumeric(format[i]))
            {
                i++;
            }
            if (format[i] == '.') {
                i++;
                while (i < size &&
                       isNumeric(format[i]))
                {
                    i++;
                }
                b = i;
                LexAddBlock(&start, &end, FLOAT(format,
                                                a,
                                                b,
                                                line));
                i--;
            } else {
                b = i;
                LexAddBlock(&start, &end, INTEGER(format,
                                                  a,
                                                  b,
                                                  line));
                i--;
            }
        }
        else if (format[i] == '"' ||
                 format[i] == '\'')
        {
            char delimiter = format[i];
            // string
            a = i++;
            while (i < size &&
                   format[i] != delimiter)
            {
                i++;
            }
            b = i++;
            LexAddBlock(&start, &end, STRING(format,
                                             a,
                                             b+1,
                                             line));
            i--;
        }
        else if (isGlyph(format[i]))
        {
            a = i; b = 0;
            // symbol
            while (i < size &&
                   isGlyph(format[i]))
            {
                i++;
                if (FindToken(&format[a], i - a, table))
                    b = i;
            }
            b = b ? b : i;
            LexAddBlock(&start, &end, TOKEN(format,
                                            a,
                                            b,
                                            line,
                                            table));
            i = b - 1;
        }
        else if (format[i] == '\n')
        {
#ifdef LEX_NEWLINES
            // end line
            LexAddBlock(&start, &end, NEWLINE(line));
#endif
        }
        else if (format[i] == ' ')
        {
            // whitespace
        }
        else
        {
            // ?
            PrintLexing(start);
            printf("Syntax error on line %i: ", line+1);
            printf("Illegal token %i.\n", format[i]);
            FreeLexing(start, format);
            *stripped = 0;
            return NULL;
        }
    }
    
#ifdef LEX_NEWLINES
    // add newline to the end
    LexAddBlock(&start, &end, NEWLINE(line));
#endif
    
    // add $ to the end
    LexAddBlock(&start, &end, EOFSYMBOL(line));

    free(lineNumbers);
    *stripped = format;
    return start;
}