HTMLify
tokens.c
Views: 2 | Author: abh
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "tokens.h"
Variable *Variables = NULL;
int Variables_count = 0;
// Variable functions
Variable *Variable_init(char *name, VarType type) {
static Variable var;
var.type = type;
if (name != NULL) {
strcpy(var.name, name);
Variables = realloc(Variables, ++Variables_count*sizeof(Variable));
Variables[Variables_count-1] = var;
} else {
var.name[0] = '\0';
}
return &var;
}
void Variable_assign(Variable *var, VarValue value) {
switch (var->type) {
case character:
var->value._char = value._char;
break;
case integer:
var->value._int = value._int;
break;
case floating:
var->value._float = value._float;
break;
case string:
var->value._str = value._str;
break;
case none:
break;
}
}
void Variable_repr(Variable *var, char *str) {
switch (var->type) {
case character:
sprintf(str, "%c", var->value._char);
break;
case integer:
sprintf(str, "%d", var->value._int);
break;
case floating:
sprintf(str, "%.2f", var->value._float);
break;
case string:
sprintf(str, "%s", var->value._str);
break;
case none:
// sprintf(str, "");
break;
}
}
Variable Variable_op(Variable *this, Operator op, const Variable *that) {
Variable result = *Variable_init(NULL, this->type);
switch (op) {
case ASN:
Variable_assign(this, that->value);
return *this;
case ADD:
switch (this->type) {
case character:
result.value._char = this->value._char + that->value._char;
break;
case integer:
result.value._int = this->value._int + that->value._int;
break;
case floating:
result.value._float = this->value._float + that->value._float;
break;
}
break;
case SUB:
switch (this->type) {
case character:
result.value._char = this->value._char + that->value._char;
break;
case integer:
result.value._int = this->value._int + that->value._int;
break;
case floating:
result.value._float = this->value._float + that->value._float;
break;
}
break;
case DIV:
switch (this->type) {
case integer:
result.value._int = this->value._int / that->value._int;
break;
case floating:
result.value._float = this->value._float / that->value._float;
}
break;
case MUL:
switch (this->type) {
case integer:
result.value._int = this->value._int * that->value._int;
break;
case floating:
result.value._float = this->value._float * that->value._float;
}
break;
}
return result;
}
Variable *Get_variable(char *name, bool named) {
for (int i = 0; i<Variables_count; i++) {
if (strcmp(Variables[i].name, name) == 0)
return &Variables[i];
}
static Variable *var;
if (named)
return Variable_init(name, none);
return Variable_init(NULL, none);
}
void Del_variable(char *name) {
bool found = false;
if (Variables_count == 0)
return;
if (strcmp(Variables[Variables_count-1].name, name)==0) {
Variables_count--;
return;
}
for (int i = 0; i<Variables_count-1; i++) {
if (strcmp(Variables[i].name, name) == 0)
found = true;
if (found)
Variables[i] = Variables[i+1];
}
if (found)
Variables_count--;
}
bool Exist_variable(char *name) {
for (int i=0; i<Variables_count; i++)
if (strcmp(Variables[i].name, name) == 0)
return true;
return false;
}
VarValue Literal_value(const char *name, VarType type) {
VarValue value;
int len = strlen(name);
switch (type) {
case character:
if (len > 2) {
value._char = name[1];
} else {
value._char = '\0';
}
break;
case integer:
// if (len == 0) {
// value._int = 0;
// } else {
// value._int = atoi(name);
// }
sscanf(name, "%d", &value._int);
break;
case floating:
// if (len == 0) {
// value._float = 0.0;
// } else {
// value._float = atof(name);
sscanf(name, "%f", &value._float);
// }
break;
case string:
strcpy(value._str, name);
value._str[len-1] = '\0';
value._str = &value._str[1];
break;
case none:
break;
}
return value;
}
// Token functions
TokenType Token_type(const char *name) {
int i, len = strlen(name);
// Operators
if (len == 1) {
if (strcmp(name, "=") == 0)
return OPERATOR;
if (strcmp(name, "+") == 0)
return OPERATOR;
if (strcmp(name, "-") == 0)
return OPERATOR;
if (strcmp(name, "/") == 0)
return OPERATOR;
if (strcmp(name, "*") == 0)
return OPERATOR;
}
// Keywords
char _kws_[][16] = {
"DEF", "def",
"INT", "int",
"FLOAT", "float",
"CHAR", "char",
"STR", "str",
"DEL", "del",
"PRINT", "print",
"TYPE", "type"
};
for (i=0; i<17; i++)
if (strcmp(name, _kws_[i]) == 0)
return KEYWORD;
// Literals
bool is_int = true;
for (i=0; i<len; i++)
if (name[i] < 48 || 57 < name[i])
is_int = false;
if (is_int)
return LITERAL;
bool is_float = true;
for (i=0; i<len; i++)
if (name[i] < 48 || 57 < name[i] || name[i] != '.')
is_float = false;
if (is_float)
return LITERAL;
bool is_char = false;
char _tbec_[5] = { '\'', '\"', '\\', '\n', '\r' };
if ((len == 3 || len == 4)) {
if (name[0] == '\'' && name[len-1] == '\'') {
if (len == 3) {
bool ve = true;
for (i=0; i<5; i++)
if (_tbec_[i] == name[1])
ve = false;
if (ve)
is_char = true;
}
if (len == 4) {
if (name[1] == '\\') {
for (i=0; i<6; i++)
if (_tbec_[i] == name[2])
is_char = true;
}
}
}
}
if (is_char)
return LITERAL;
bool is_str = false;
/* char _tbec_[5] */
if (name[0] == '\"' && name[len-1] == '\"') {
int si = 0;
bool es_before = false;
char ch;
for (si=1; si<len-1; si++) {
es_before = false;
ch = name[si];
if (ch == '\\') {
es_before = true;
continue;
}
if (es_before) {
bool ve = false;
for (i=0; i<5; i++)
if (_tbec_[i] == ch)
ve = true;
if (!ve)
break;
}
}
if (!es_before)
is_str = true;
}
bool is_variable = true;
char _ainc_[63] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
for (i=0; i<len; i++) {
char ch = name[i];
if (i == 0 && 48 <= ch && ch <= 57)
is_variable = false;
if (ch == '.')
is_variable = false;
bool vch = false;
int j;
for (j=0; j<63; j++)
if (_ainc_[j] == ch)
vch = true;
if (!vch)
is_variable = false;
}
if (is_variable)
return VARIABLE;
return NONE;
}
Keyword Get_keyword(const char *name) {
if (strcmp(name, "def") == 0 || strcmp(name, "DEF") == 0)
return DEF;
if (strcmp(name, "int") == 0 || strcmp(name, "INT") == 0)
return INT;
if (strcmp(name, "float") == 0 || strcmp(name, "FLOAT") == 0)
return FLOAT;
if (strcmp(name, "char") == 0 || strcmp(name, "CHAR") == 0)
return CHAR;
if (strcmp(name, "str") == 0 || strcmp(name, "STR") == 0)
return STR;
if (strcmp(name, "del") == 0 || strcmp(name, "DEL") == 0)
return DEL;
if (strcmp(name, "print") == 0 || strcmp(name, "PRINT") == 0)
return PRINT;
if (strcmp(name, "type") == 0 || strcmp(name, "TYPE") == 0)
return TYPE;
};
Operator Get_operator(const char *name) {
if (name[0] == '=')
return ASN;
if (name[0] == '+')
return ADD;
if (name[0] == '-')
return SUB;
if (name[0] == '/')
return DIV;
if (name[0] == '*')
return MUL;
};
char *Type_token(Token token) {
switch (token.type) {
case OPERATOR:
switch (token.value.operator) {
case ASN:
return "Assign Operator";
case ADD:
return "Addition Operator";
case SUB:
return "Substraction Operator";
case DIV:
return "Division Operator";
case MUL:
return "Multipication Operator";
}
break;
case KEYWORD:
switch (token.value.keyword) {
case DEF:
return "Keyword: Define";
case INT:
return "Int cast keyword";
case CHAR:
return "Char cast keyword";
case FLOAT:
return "Float cast keyword";
case STR:
return "String cast keyword";
case DEL:
return "Keyword: Delete";
case PRINT:
return "Print Keyword";
case TYPE:
return "Type Keyword";
}
case VARIABLE:
switch (token.value.variable->type) {
case character:
return "Character Type Variable";
case integer:
return "Integer Type Variable";
case floating:
return "Floating point Type Variable";
case string:
return "Stling Type Variable";
case none:
return "None Type Variable";
}
case LITERAL:
return "Literal";
case NONE:
return "NONE";
}
}