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;
}