HTMLify

parser.c
Views: 15 | Author: abh
#include "string.h"
#include "stdbool.h"
#include "tokens.h"
#include "parser.h"


int count_split_points(const char *command) {
    int i, sc=0, cl = strlen(command);
    for (i=0; i<cl; i++)
        if (command[i]==' ')
            sc++;
    return sc;
}

char **command_splitter(const char *command) {
    char **split, *cmd, *token;
    int i, si=0, cl, sc=0;
    
    cl = strlen(command);
    cmd = malloc(cl+1);
    strcpy(cmd, command); 
    sc = count_split_points(cmd);
    split = malloc(sizeof(char*)*sc);
    
    token = strtok(cmd, " ");
    if (token != NULL) {
        split[si] = (char*)malloc(strlen(token) + 1);
        strcpy(split[si], token);
        si++;
    }
    while ((token = strtok(NULL, " ")) != NULL) {
        split[si] = (char*)malloc(strlen(token) + 1);
        strcpy(split[si], token);
        si++;
    }

    return split;
}

Token *tokenize(const char *command, int *count) {
    Token *tokens = NULL;
    char **cparts = command_splitter(command), *cpart = malloc(33), *cmd;
    int sp = count_split_points(command), i, tc=0;
    bool concat = false;
    cmd = malloc(strlen(command)+1);
    strcpy(cmd, command);

    if (sp == 0)
        return tokens;

    for (i=0; i<=sp; i++) {
        if (concat) {
            strcat(cpart, " ");
            strcat(cpart, cparts[i]);
        } else {
            strcpy(cpart, cparts[i]);
        }

        if (cpart[0] == '\"')
            concat = true;
        if (cpart[strlen(cpart)-1] == '\"')
            concat = false;

        if (concat)
            continue;

        TokenType type;
        TokenValue value;
        Token token;

        type = Token_type(cpart);

        switch (type) {
            case KEYWORD:
                value.keyword = Get_keyword(cpart);
                break;
            case OPERATOR:
                value.operator = Get_operator(cpart);
                break;
            case LITERAL:
                value.literal = malloc(strlen(cpart)+1);
                strcpy(value.literal, cpart);
                break;
            case VARIABLE:
                value.variable = Get_variable(cpart, true);
                break;
            case NONE:
                value.variable = Variable_init(NULL, none);
        }

        token.type = type;
        token.value = value;
        tokens = realloc(tokens, sizeof(Token) * ++tc);
        tokens[tc-1] = token;
    }

    if (count != NULL)
        *count = tc;
    return tokens;
}

char *execute_command(const char *command) {
    int tc;
    Token *tokens = tokenize(command, &tc); 
    char *r = malloc(256);


    switch (tc) {
        case 0:
            strcpy(r, "");
            break;
        case 1:
            if (tokens[0].type == VARIABLE) {
                Variable_repr(tokens[0].value.variable, r);
            } else {
                strcpy(r, "Invalid Command or Expression");
            }
            break;
        case 2:
            switch (tokens[1].type) {
                case VARIABLE:
                    Variable *tmpvar;
                    char *varname = tokens[1].value.variable->name;
                    bool exist = Exist_variable(varname);
                    switch (tokens[0].value.keyword) {
                        case DEF:
                            if (!exist) {
                                Variable_init(tokens[1].value.variable->name, none);
                            }
                            break;
                        case INT:
                            tmpvar = Get_variable(varname, true);
                            tmpvar->type = integer;
                            break;
                        case FLOAT:
                            tmpvar = Get_variable(varname, true);
                            tmpvar->type = floating;
                            break;
                        case CHAR:
                            tmpvar = Get_variable(varname, true);
                            tmpvar->type = character;
                            break;
                        case STR:
                            tmpvar = Get_variable(varname, true);
                            tmpvar->type = string;
                            break;
                        case DEL:
                            Del_variable(tokens[1].value.variable->name);
                            break;
                        case PRINT:
                            Variable_repr(tokens[1].value.variable, r);
                            break;
                        case TYPE:
                            strcpy(r, Type_token((const Token)tokens[1]));
                    }
                    break;
                default:
                    strcpy(r, Type_token(tokens[1]));
            }
            break;
        case 3:
            if (
                tokens[0].type == VARIABLE &&
                tokens[1].type == OPERATOR &&
                tokens[2].type == VARIABLE
               ) {
                Variable t = Variable_op(
                            tokens[0].value.variable,
                            tokens[1].value.operator,
                            tokens[2].value.variable
                            );
                Variable_repr(&t, r);
            } else if (
                tokens[0].type == VARIABLE && 
                tokens[1].type == OPERATOR &&
                tokens[2].type == LITERAL
                    ) {
                tokens[0].value.variable->value = Literal_value(tokens[2].value.literal, tokens[0].value.variable->type);
            } else {
                strcpy(r, "Invalid Command: tokens should be in VAR OP VAR or VAR OP LIT order");
            }
            break;
        case 4:
            strcpy(r, "Invalid Command: no command supoorted 4 arguments");
            break;
        case 5:
            if (
                tokens[0].type == VARIABLE &&
                tokens[1].type == OPERATOR && tokens[1].value.operator == ASN &&
                tokens[2].type == VARIABLE &&
                tokens[3].type == OPERATOR && tokens[3].value.operator != ASN &&
                tokens[4].type == VARIABLE
               ) {
                Variable_assign(
                        tokens[0].value.variable,
                        Variable_op(
                            tokens[2].value.variable,
                            tokens[3].value.operator,
                            tokens[4].value.variable
                            ).value
                        );
            } else {
                strcpy(r, "Invalid Command");
            }
            break;
    }

    // temp
    // for (int i=0; i<Variables_count; i++)
    //     printf(">>> | Variable: %s, Type: %d, Value: %d\n", Variables[i].name, Variables[i].type, Variables[i].value._int);

    return r;
}

Comments