#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N_LINES 256
#define LINE_MAX_CH 128
#define N_VAR_ABC 26
#define N_VAR_X 1024
#define N_ATOM 20
#define ATOM_MAX_CH 16
#define N_LABELS 16
char code[N_LINES][LINE_MAX_CH];
int var_abc[N_VAR_ABC];
int var_x[N_VAR_X];
char atom[N_ATOM][ATOM_MAX_CH];
int labels[N_LABELS];
int get_atom_token(char *d, char *s) {
char *p;
p = s;
while ((*s != ' ' ) && (*s != 0) && (*s != ',') && (*s != '\n')) {
*d = *s;
s++;
d++;
}
*d = 0;
while ((*s == ',') || (*s == ' ') || (*s == '\n')) s++;
return (s-p);
}
int get_atoms(int line) {
int i;
int length;
int length2;
length = 0;
for (i = 0; ; i++) {
if((length2 = get_atom_token(atom[i], code[line] + length)) == 0)
break;
length += length2;
}
return 9;
}
int get_index_of_x_var(char *s) {
int i;
s++;
i = 0;
while (*s != 0) {
i += *s - '0';
i *= 10;
s++;
}
i /= 10;
return i;
}
int strint(char *s) {
int i;
i = 0;
while (*s != 0) {
i += *s - '0';
i *= 10;
s++;
}
i /= 10;
return i;
}
int main(int argc, char *argv[]) {
FILE *fp;
int line_counter;
int i;
int op1, op2, op3;
int op1_num, op2_num, op3_num;
int labelc;
if((fp = fopen(argv[1], "r")) == NULL) {
perror("Can't open file");
exit(1);
}
line_counter = 0;
while(!feof(fp)) {
fgets(code[line_counter], LINE_MAX_CH, fp);
line_counter++;
}
for (i = 0; i < N_VAR_ABC; i++)
var_abc[i] = 0;
for (i = 0; i < N_VAR_X; i++)
var_x[i] = 0;
for (i = 0; i < N_LABELS; i++)
labels[i] = -1;
for (i = 0; i < line_counter; i++) {
get_atoms(i);
if (strcmp(atom[0], "label") == 0) {
labelc = strint(atom[1]);
labels[labelc] = i;
}
}
for(i = 0; i < N_LABELS; i++)
fprintf(stderr, "%i\n", labels[i]);
fprintf(stderr, "\n\n");
for (i = 0; i < line_counter; i++) {
get_atoms(i);
if(strcmp(atom[0], "add") == 0) {
if((atom[1][0] == 'x') && ((atom[1][1] >= '0' ) && (atom[1][1] <= '9'))) {
op1 = get_index_of_x_var(atom[1]);
if((atom[2][0] == 'x') && ((atom[2][1] >= '0' ) && (atom[2][1] <= '9'))) {
op2 = get_index_of_x_var(atom[2]);
if((atom[3][0] == 'x') && ((atom[3][1] >= '0' ) && (atom[3][1] <= '9'))) {
op3 = get_index_of_x_var(atom[3]);
var_x[op1] = var_x[op2] + var_x[op3];
}
else if(((atom[3][0] >= 'a') && (atom[3][0] <= 'z')) && (atom [3][1] == 0)) {
op3 = atom[3][0] - 'a';
var_x[op1] = var_x[op2] + var_abc[op3];
}
else if((atom[3][0] >= '0') && (atom[3][0] <= '9')) {
op3_num = strint(atom[3]);
var_x[op1] = var_x[op2] + op3_num;
}
}
else if(((atom[2][0] >= 'a') && (atom[2][0] <= 'z')) && (atom [2][1] == 0)) {
op2 = atom[2][0] - 'a';
if((atom[3][0] == 'x') && ((atom[3][1] >= '0' ) && (atom[3][1] <= '9'))) {
op3 = get_index_of_x_var(atom[3]);
var_x[op1] = var_abc[op2] + var_x[op3];
}
else if(((atom[3][0] >= 'a') && (atom[3][0] <= 'z')) && (atom [3][1] == 0)) {
op3 = atom[3][0] - 'a';
var_x[op1] = var_abc[op2] + var_abc[op3];
}
else if((atom[3][0] >= '0') && (atom[3][0] <= '9')) {
op3_num = strint(atom[3]);
var_x[op1] = var_abc[op2] + op3_num;
}
}
else if(((atom[2][0] >= '0') && (atom[2][0] <= '9'))) {
op2_num = strint(atom[2]);
if((atom[3][0] == 'x') && ((atom[3][1] >= '0' ) && (atom[3][1] <= '9'))) {
op3 = get_index_of_x_var(atom[3]);
var_x[op1] = op2_num + var_x[op3];
}
else if(((atom[3][0] >= 'a') && (atom[3][0] <= 'z')) && (atom [3][1] == 0)) {
op3 = atom[3][0] - 'a';
var_x[op1] = op2_num + var_abc[op3];
}
else if((atom[3][0] >= '0') && (atom[3][0] <= '9')) {
op3_num = strint(atom[3]);
var_x[op1] = op2_num + op3_num;
}
}
}
else if(((atom[1][0] >= 'a') && (atom[1][0] <= 'z')) && (atom [1][1] == 0)) {
op1 = atom[1][0] - 'a';
if((atom[2][0] == 'x') && ((atom[2][1] >= '0' ) && (atom[2][1] <= '9'))) {
op2 = get_index_of_x_var(atom[2]);
if((atom[3][0] == 'x') && ((atom[3][1] >= '0' ) && (atom[3][1] <= '9'))) {
op3 = get_index_of_x_var(atom[3]);
var_abc[op1] = var_x[op2] + var_x[op3];
}
else if(((atom[3][0] >= 'a') && (atom[3][0] <= 'z')) && (atom [3][1] == 0)) {
op3 = atom[3][0] - 'a';
var_abc[op1] = var_x[op2] + var_abc[op3];
}
else if((atom[3][0] >= '0') && (atom[3][0] <= '9')) {
op3_num = strint(atom[3]);
var_abc[op1] = var_x[op2] + op3_num;
}
}
else if(((atom[2][0] >= 'a') && (atom[2][0] <= 'z')) && (atom [2][1] == 0)) {
op2 = atom[2][0] - 'a';
if((atom[3][0] == 'x') && ((atom[3][1] >= '0' ) && (atom[3][1] <= '9'))) {
op3 = get_index_of_x_var(atom[3]);
var_abc[op1] = var_abc[op2] + var_x[op3];
}
else if(((atom[3][0] >= 'a') && (atom[3][0] <= 'z')) && (atom [3][1] == 0)) {
op3 = atom[3][0] - 'a';
var_abc[op1] = var_abc[op2] + var_abc[op3];
}
else if((atom[3][0] >= '0') && (atom[3][0] <= '9')) {
op3_num = strint(atom[3]);
var_abc[op1] = var_abc[op2] + op3_num;
}
}
else if((atom[2][0] >= '0') && (atom[2][0] <= '9')) {
op2 = strint(atom[2]);
if((atom[3][0] == 'x') && ((atom[3][1] >= '0' ) && (atom[3][1] <= '9'))) {
op3 = get_index_of_x_var(atom[3]);
var_abc[op1] = op2_num + var_x[op3];
}
else if(((atom[3][0] >= 'a') && (atom[3][0] <= 'z')) && (atom [3][1] == 0)) {
op3 = atom[3][0] - 'a';
var_abc[op1] = op2_num + var_abc[op3];
}
else if((atom[3][0] >= '0') && (atom[3][0] <= '9')) {
op3_num = strint(atom[3]);
var_abc[op1] = op2_num + op3_num;
}
}
}
}
if(strcmp(atom[0], "mul") == 0) {
if((atom[1][0] == 'x') && ((atom[1][1] >= '0' ) && (atom[1][1] <= '9'))) {
op1 = get_index_of_x_var(atom[1]);
if((atom[2][0] == 'x') && ((atom[2][1] >= '0' ) && (atom[2][1] <= '9'))) {
op2 = get_index_of_x_var(atom[2]);
if((atom[3][0] == 'x') && ((atom[3][1] >= '0' ) && (atom[3][1] <= '9'))) {
op3 = get_index_of_x_var(atom[3]);
var_x[op1] = var_x[op2] * var_x[op3];
}
else if(((atom[3][0] >= 'a') && (atom[3][0] <= 'z')) && (atom [3][1] == 0)) {
op3 = atom[3][0] - 'a';
var_x[op1] = var_x[op2] * var_abc[op3];
}
else if((atom[3][0] >= '0') && (atom[3][0] <= '9')) {
op3_num = strint(atom[3]);
var_x[op1] = var_x[op2] * op3_num;
}
}
else if(((atom[2][0] >= 'a') && (atom[2][0] <= 'z')) && (atom [2][1] == 0)) {
op2 = atom[2][0] - 'a';
if((atom[3][0] == 'x') && ((atom[3][1] >= '0' ) && (atom[3][1] <= '9'))) {
op3 = get_index_of_x_var(atom[3]);
var_x[op1] = var_abc[op2] * var_x[op3];
}
else if(((atom[3][0] >= 'a') && (atom[3][0] <= 'z')) && (atom [3][1] == 0)) {
op3 = atom[3][0] - 'a';
var_x[op1] = var_abc[op2] * var_abc[op3];
}
else if((atom[3][0] >= '0') && (atom[3][0] <= '9')) {
op3_num = strint(atom[3]);
var_x[op1] = var_abc[op2] * op3_num;
}
}
else if(((atom[2][0] >= '0') && (atom[2][0] <= '9'))) {
op2_num = strint(atom[2]);
if((atom[3][0] == 'x') && ((atom[3][1] >= '0' ) && (atom[3][1] <= '9'))) {
op3 = get_index_of_x_var(atom[3]);
var_x[op1] = op2_num * var_x[op3];
}
else if(((atom[3][0] >= 'a') && (atom[3][0] <= 'z')) && (atom [3][1] == 0)) {
op3 = atom[3][0] - 'a';
var_x[op1] = op2_num * var_abc[op3];
}
else if((atom[3][0] >= '0') && (atom[3][0] <= '9')) {
op3_num = strint(atom[3]);
var_x[op1] = op2_num * op3_num;
}
}
}
else if(((atom[1][0] >= 'a') && (atom[1][0] <= 'z')) && (atom [1][1] == 0)) {
op1 = atom[1][0] - 'a';
if((atom[2][0] == 'x') && ((atom[2][1] >= '0' ) && (atom[2][1] <= '9'))) {
op2 = get_index_of_x_var(atom[2]);
if((atom[3][0] == 'x') && ((atom[3][1] >= '0' ) && (atom[3][1] <= '9'))) {
op3 = get_index_of_x_var(atom[3]);
var_abc[op1] = var_x[op2] * var_x[op3];
}
else if(((atom[3][0] >= 'a') && (atom[3][0] <= 'z')) && (atom [3][1] == 0)) {
op3 = atom[3][0] - 'a';
var_abc[op1] = var_x[op2] * var_abc[op3];
}
else if((atom[3][0] >= '0') && (atom[3][0] <= '9')) {
op3_num = strint(atom[3]);
var_abc[op1] = var_x[op2] * op3_num;
}
}
else if(((atom[2][0] >= 'a') && (atom[2][0] <= 'z')) && (atom [2][1] == 0)) {
op2 = atom[2][0] - 'a';
if((atom[3][0] == 'x') && ((atom[3][1] >= '0' ) && (atom[3][1] <= '9'))) {
op3 = get_index_of_x_var(atom[3]);
var_abc[op1] = var_abc[op2] * var_x[op3];
}
else if(((atom[3][0] >= 'a') && (atom[3][0] <= 'z')) && (atom [3][1] == 0)) {
op3 = atom[3][0] - 'a';
var_abc[op1] = var_abc[op2] * var_abc[op3];
}
else if((atom[3][0] >= '0') && (atom[3][0] <= '9')) {
op3_num = strint(atom[3]);
var_abc[op1] = var_abc[op2] * op3_num;
}
}
else if((atom[2][0] >= '0') && (atom[2][0] <= '9')) {
op2 = strint(atom[2]);
if((atom[3][0] == 'x') && ((atom[3][1] >= '0' ) && (atom[3][1] <= '9'))) {
op3 = get_index_of_x_var(atom[3]);
var_abc[op1] = op2_num * var_x[op3];
}
else if(((atom[3][0] >= 'a') && (atom[3][0] <= 'z')) && (atom [3][1] == 0)) {
op3 = atom[3][0] - 'a';
var_abc[op1] = op2_num * var_abc[op3];
}
else if((atom[3][0] >= '0') && (atom[3][0] <= '9')) {
op3_num = strint(atom[3]);
var_abc[op1] = op2_num * op3_num;
}
}
}
}
if(strcmp(atom[0], "set") == 0) {
if(!(((atom[1][0] >= 'a') && (atom[1][0] <= 'z')) && (atom [1][1] == 0))) {
perror("Virtual Machine: Destination Operand, wrong format");
exit(1);
}
op1 = atom[1][0] - 'a';
if((atom[2][0] == 'x') && ((atom[2][1] >= '0' ) && (atom[2][1] <= '9'))) {
op2 = get_index_of_x_var(atom[2]);
var_abc[op1] = var_x[op2];
}
else if(((atom[2][0] >= 'a') && (atom[2][0] <= 'z')) && (atom [2][1] == 0)) {
op2 = atom[2][0] - 'a';
var_abc[op1] = var_abc[op2];
}
else if((atom[2][0] >= '0') && (atom[2][0] <= '9')) {
op2 = strint(atom[2]);
var_abc[op1] = op2;
}
}
if(strcmp(atom[0], "print") == 0) {
op1 = atom[1][0] - 'a';
printf("%i\n", var_abc[op1]);
}
if (strcmp(atom[0], "jump") == 0) {
if(strcmp(atom[1], "to") == 0) {
if(strcmp(atom[2], "label") != 0) {
perror("Error in virual code");
exit(1);
}
i = labels[strint(atom[3])];
}
}
if (strcmp(atom[0], "less") == 0) {
if((atom[1][0] == 'x') && ((atom[1][1] >= '0' ) && (atom[1][1] <= '9'))) {
op2 = get_index_of_x_var(atom[1]);
op1_num = var_x[op2];
if((atom[2][0] == 'x') && ((atom[2][1] >= '0' ) && (atom[2][1] <= '9'))) {
op3 = get_index_of_x_var(atom[2]);
op2_num = var_x[op3];
}
else if(((atom[2][0] >= 'a') && (atom[2][0] <= 'z')) && (atom [2][1] == 0)) {
op3 = atom[2][0] - 'a';
op2_num = var_abc[op3];
}
else if((atom[2][0] >= '0') && (atom[2][1] <= '9')) {
op3 = strint(atom[2]);
op2_num = op3;
}
}
else if(((atom[1][0] >= 'a') && (atom[1][0] <= 'z')) && (atom [1][1] == 0)) {
op2 = atom[1][0] - 'a';
op1_num = var_abc[op2];
if((atom[2][0] == 'x') && ((atom[2][1] >= '0' ) && (atom[2][1] <= '9'))) {
op3 = get_index_of_x_var(atom[2]);
op2_num = var_x[op3];
}
else if(((atom[2][0] >= 'a') && (atom[2][0] <= 'z')) && (atom [2][1] == 0)) {
op3 = atom[2][0] - 'a';
op2_num = var_abc[op3];
}
else if((atom[2][0] >= '0') && (atom[2][1] <= '9')) {
op3 = strint(atom[2]);
op2_num = op3;
}
}
else if((atom[1][0] >= '0') && (atom[1][0] <= '9')) {
op2 = strint(atom[1]);
op1_num = op2;
if((atom[2][0] == 'x') && ((atom[2][1] >= '0' ) && (atom[2][1] <= '9'))) {
op3 = get_index_of_x_var(atom[2]);
op2_num = var_x[op3];
}
else if(((atom[2][0] >= 'a') && (atom[2][0] <= 'z')) && (atom [2][1] == 0)) {
op3 = atom[2][0] - 'a';
op2_num = var_abc[op3];
}
else if((atom[2][0] >= '0') && (atom[2][1] <= '9')) {
op3 = strint(atom[2]);
op2_num = op3;
}
}
if(op1_num < op2_num) {
i++;
get_atoms(i);
if(strcmp(atom[0], "to") != 0) {
perror("Error in virtual source code");
exit(1);
}
if(strcmp(atom[1], "label") != 0) {
perror("Error in virtual source code");
exit(1);
}
i = labels[strint(atom[2])];
}
}
}
fclose(fp);
return 0;
}