Reputation: 55
so, I have this code:
/*
* CXenon VM v0.0.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#define IADD 1 // integer add
#define ISUB 2 // integer substract
#define IMUL 3 // integer multiply
#define IDIV 4 // integer divide
#define ILT 5 // integer less than
#define IEQ 6 // integer equals
#define BR 7
#define BRT 8
#define BRF 9
#define ICONST 10 // integer constant
#define LOAD 11 // load from data memory
#define GLOAD 12 // global load from data memory
#define STORE 13 // store in data memory
#define GSTORE 14 // global store in data memory
#define PRINT 15 // print
#define PRINTLN 16 // print with trailing newline
#define POP 17 // pop from stack
#define CALL 18 // call function
#define RET 19
#define FADD 20
#define FSUB 21
#define FMUL 22
#define FDIV 23
#define FCONST 24
#define FLT 25
#define FEQ 26
#define FMT 27
#define FNEQ 28
#define IMT 29
#define INEQ 30
#define BCONST 31
#define BEQ 32
#define BNEQ 33
#define BTRUE 34
#define BFALSE 35
#define HALT 36
char* opcodes[] = {
"",
"IADD",
"ISUB",
"IMULL",
"IDIV",
"ILT",
"IEQ",
"BR",
"BRT",
"BRF",
"ICONST",
"LOAD",
"GLOAD",
"STORE",
"GSTORE",
"PRINT",
"PRINTLN",
"POP",
"CALL",
"RET",
"FADD",
"FSUB",
"FMUL",
"FDIV",
"FCONST",
"FLT",
"FEQ",
"FMT",
"FNEQ",
"IMT",
"INEQ",
"BCONST",
"BEQ",
"BNEQ",
"BTRUE",
"BFALSE",
"HALT"
};
struct stack_base{
char* somechars;
char achar;
int anint;
float afloat;
bool abool;
};
int vm_cpu(struct stack_base* code, bool trace, int datasize){
struct stack_base stack[100];
struct stack_base data[datasize];
int ip = 0; // instructionpointer
int fp; // framepointer
int sp = -1; // stackpointer
int v;
int addr;
int nargs;
int rvalue;
int a, b;
float fv;
float fa, fb;
bool bv;
bool ba, bb;
int opcode = code[ip].anint; // fetch
int size = sizeof(code); // declares size of code
//bool trace = false;
while(ip < size){
if(trace){
printf("%04d: %s\n",ip, opcodes[opcode]); // prints trace
}
ip++;
switch(opcode){
case ICONST:
v = code[ip].anint;
ip++;
sp++;
stack[sp].anint = v;
break;
case ISUB:
b = stack[sp--].anint;
a = stack[sp--].anint;
stack[++sp].anint = a - b;
break;
case IADD:
b = stack[sp--].anint;
a = stack[sp--].anint;
stack[++sp].anint = a + b;
break;
case IMUL:
b = stack[sp--].anint;
a = stack[sp--].anint;
stack[++sp].anint = a * b;
break;
case IDIV:
b = stack[sp--].anint;
a = stack[sp--].anint;
stack[++sp].anint = a/b;
break;
case ILT:
b = stack[sp--].anint;
a = stack[sp--].anint;
if(a > b){
stack[++sp].abool = true;
break;
}
else {
stack[++sp].abool = false;
break;
}
case IMT:
b = stack[sp--].anint;
a = stack[sp--].anint;
if(a < b){
stack[++sp].abool = true;
break;
}
else {
stack[++sp].abool = false;
break;
}
case IEQ:
b = stack[sp--].anint;
a = stack[sp--].anint;
if(a == b){
stack[++sp].abool = true;
break;
}
else {
stack[++sp].abool = false;
break;
}
case INEQ:
b = stack[sp--].anint;
a = stack[sp--].anint;
if(a != b){
stack[++sp].abool = true;
break;
}
else {
stack[++sp].abool = false;
break;
}
case FCONST:
fv = code[ip].afloat;
ip++;
sp++;
stack[sp].afloat = fv;
break;
case FSUB:
fb = stack[sp--].afloat;
fa = stack[sp--].afloat;
stack[++sp].afloat = fa + fb;
break;
case FADD:
fb = stack[sp--].afloat;
fa = stack[sp--].afloat;
stack[++sp].afloat = fa + fb;
break;
case FMUL:
fb = stack[sp--].afloat;
fa = stack[sp--].afloat;
stack[++sp].afloat = fa * fb;
break;
case FDIV:
fb = stack[sp--].afloat;
fa = stack[sp--].afloat;
stack[++sp].afloat = fa/fb;
break;
case FEQ:
fb = stack[sp--].afloat;
fa = stack[sp--].afloat;
if(fa == fb){
stack[++sp].abool = true;
break;
}
else {
stack[++sp].abool = false;
break;
}
case FLT:
fb = stack[sp--].afloat;
fa = stack[sp--].afloat;
if(fa > fb){
stack[++sp].abool = true;
break;
}
else {
stack[++sp].abool = false;
break;
}
case FMT:
fb = stack[sp--].afloat;
fa = stack[sp--].afloat;
if(fa < fb){
stack[++sp].abool = true;
break;
}
else {
stack[++sp].abool = false;
break;
}
case FNEQ:
fb = stack[sp--].afloat;
fa = stack[sp--].afloat;
if(fa != fb){
stack[++sp].abool = true;
break;
}
else {
stack[++sp].abool = false;
break;
}
case BCONST:
bv = code[ip].anint;
ip++;
sp++;
if(bv == BTRUE){
stack[sp].abool = true;
break;
}
else if(bv == BFALSE){
stack[sp].abool = false;
break;
}
case BNEQ:
bb = stack[sp--].abool;
ba = stack[sp--].abool;
if(ba == bb){
stack[++sp].abool = true;
break;
}
else {
stack[++sp].abool = false;
break;
}
case BEQ:
bb = stack[sp--].abool;
ba = stack[sp--].abool;
if(ba != bb){
stack[++sp].abool = true;
break;
}
else {
stack[++sp].abool = false;
break;
}
case PRINT:
v = stack[sp].anint;
sp--;
printf("%i", v);
break;
case PRINTLN:
//v = stack[sp].anint;
//fv = stack[sp].afloat;
bv = stack[sp].abool;
sp--;
printf("%d\n", bv);
break;
case GLOAD:
addr = code[ip].anint;
ip++;
v = data[addr].anint;
sp++;
stack[sp].anint = v;
break;
case GSTORE:
v = stack[sp].anint;
sp--;
addr = code[ip].anint;
ip++;
data[addr].anint = v;
break;
case CALL:
addr = code[ip++].anint;
nargs = code[ip++].anint;
stack[++sp].anint = nargs;
stack[++sp].anint = fp;
stack[++sp].anint = ip;
fp = sp;
ip = addr;
break;
case RET:
rvalue = stack[sp--].anint;
sp = fp;
ip = stack[sp--].anint;
fp = stack[sp--].anint;
nargs = stack[sp--].anint;
sp -= nargs;
stack[sp++].anint = rvalue;
break;
case HALT:
return 0;
break;
}
opcode = code[ip].anint;
}
}
void main(){
struct stack_base hello[] = {
BCONST, BTRUE,
BCONST, BTRUE,
BNEQ,
PRINTLN,
HALT
};
vm_cpu(hello, true, 4);
}
when I compile that code, I get these errors:
thewatcher@thewatcher ~/Xenon/CXenon/src $ gcc main.c -o test
main.c: In function ‘main’:
main.c:402:9: warning: initialization makes pointer from integer without a cast [enabled by default]
BCONST, BTRUE,
^
main.c:402:9: warning: (near initialization for ‘hello[0].somechars’) [enabled by default]
main.c:405:9: warning: initialization makes pointer from integer without a cast [enabled by default]
PRINTLN,
^
main.c:405:9: warning: (near initialization for ‘hello[1].somechars’) [enabled by default]
I don't understand why this happens and I have no idea how to solve this. Could someone help me?
Upvotes: 0
Views: 1848
Reputation: 1120
The structure member initialization in your main function is different from you structure definition. You structure member should be initialized like this.
struct stack_base hello[] = {
{
"hey there",'a',22,11,true
},
{
"thank you",'b',11,11,false
},
{
"hello",'c',11,11,true
}
};
And the following line,
int size = sizeof(code);
code
is just a pointer to the structure whose size is always 4 (older systems) or 8 (newer systems) bytes. I guess you are trying to find number of members in hello[]
structure array. In this case either you have to pass this number separately as a function to vm_cpu
function or use some logic to determine this number within the vm_cpu function.
In case you don't want to pass no. of members as an argument, initialize the structure in main
fn as follows:
struct stack_base hello[] = {
{
"abc",'a',11,11,true
},
{
"abc",'a',11,11,true
},
{
"abc",'a',11,11,true
},NULL
};
And in vm_cpu function, use the following logic to find out no. of structure array elements.
int size = 0;
struct stack_base *ptr = code;
while(ptr[size].somechars) {
size++;
ptr++;
}
size--;
printf("The no. of elements of structure array: %d\n", size);
Upvotes: 1
Reputation: 562
If you initialize your structure array hello
correctly, the errors you are facing should disappear. The way you initialize it currently is very confusing, as the compiler tells you:
warning: (near initialization for ‘hello[0].somechars’) [enabled by default]
Meaning that there is an error with the way you initialize your structure array (see here to fully understand the grammar involved in the error). Your second error:
warning: initialization makes pointer from integer without a cast
The compiler is also confused in your initialization of your structure array. Take, for example, this initialization:
struct my_struct {
int a;
int b;
}
//Create a structure assigning the value of a to 10 and b to 20:
struct my_struct foo = {10, 20};
This will initialize one structure, not multiple. If you wanted to use a similar syntax creating an array of structures, you could do something like this:
//Use my_struct from the previous example
struct my_struct foo[] {
{.a = 10, .b = 20},
{.a = 1, .b = 2},
{.a = 5, .b = 5}
};
To understand this syntax further, see designated initializers. The syntax above creates an array of structures with these members for each structure in the array:
foo[0].a = 10;
foo[0].b = 20;
foo[1].a = 1;
foo[1].b = 2;
foo[2].a = 5;
foo[2].b = 5;
Initialize struct stack_base hello[]
to have these values for each member:
//hello[0].somechars will be assigned the string "hello"
hello[0].achar = 'a';
hello[0].anint = 1;
hello[0].afloat = 1.0;
hello[0].abool = 0;
//hello[1].somechars will be assigned the string "bye bye"
hello[1].achar = 'b';
hello[1].anint = 2;
hello[1].afloat = 10.0;
hello[1].abool = 1;
Then, you could write:
struct stack_base hello[] {
{.achar = 'a', .anint = 1, .afloat = 1.0, .abool = 0},
{.achar = 'b', .anint = 2, .afloat = 10.0, .abool = 1}
};
//Assign strings to achar
strcpy(hello[0].somechars, "hello");
strcpy(hello[1].somechars, "bye bye");
In the example above, instead of assigning exact values to each member of the structure, it would make sense for you to replace the assignments to each member with the constants. For example, you might replace .anint = 1
with .anint = BCONST
, etc.
Currently, however, it is simply confusing the way you have initialized your structure array.
Upvotes: 0