Skip to content

Commit

Permalink
update opcodes
Browse files Browse the repository at this point in the history
  • Loading branch information
rmccullagh committed Oct 31, 2017
1 parent ae774ce commit df46ebf
Show file tree
Hide file tree
Showing 9 changed files with 398 additions and 34 deletions.
280 changes: 280 additions & 0 deletions 2
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <object.h>
#include <assert.h>

#define COMO_COMPILER 1

#include "como_ast.h"
#include "como_stack.h"
#include "como_debug.h"
#include "como_opcode.h"
#include "como_globals.h"
#include "como_parser.h"
#include "como_lexer.h"
#include "como_compiler.h"
#include "como_io.h"
#include "como_object.h"

static ComoFrame *global_frame = NULL;

static ComoOpCode *create_op(unsigned char op, Object *oper)
{
ComoOpCode *ret = malloc(sizeof(ComoOpCode));
ret->op_code = op;

ret->flags = 0;

if(oper != NULL) {
ret->flags |= COMO_OP_CODE_OPERAND_USED;
}

// TODO, line numbers

ret->operand = oper;
return ret;
}

static ComoFrame *create_frame(Object *code, const char *name)
{
size_t i;
ComoFrame *frame = malloc(sizeof(ComoFrame));

frame->cf_sp = 0;
frame->cf_stack_size = 0;

for(i = 0; i < (size_t)COMO_DEFAULT_FRAME_STACKSIZE; i++) {
frame->cf_stack[i] = NULL;
}

frame->cf_symtab = newMap(4);
frame->code = code;
frame->pc = 0;
frame->next = NULL;
frame->namedparameters = newArray(2);
frame->filename = NULL;
frame->call_stack = NULL;
frame->name = newString(name);
frame->caller = NULL;
return frame;
}

static int exception = 0;
static char exmessage[1024];

#define Como_SetError(fmt, ...) do { \
exception = 1; \
memset(exmessage, 0, sizeof(exmessage)); \
sprintf(exmessage, fmt, __VA_ARGS__); \
} while(0)

/* VM main loop */
Object *Como_EvalFrame(ComoFrame *frame)
{
#define O_INCRREF(O) \
O_REFCNT((O))++

#define O_DECREF(O) do { \
if(--O_REFCNT((O)) == 0) { \
objectDestroy((O)); \
} \
} while(0)

#define OPR_DECREF(Opcode) do { \
(Opcode)->flags |= COMO_OP_CODE_OPERAND_FREE; \
objectDestroy((Opcode)->operand); \
(Opcode)->operand = NULL; \
} while(0)

#define TARGET(Name) \
case Name:

#define VM_CONTINUE() \
goto next_opcode

#define VM_DISPATCH() \
break

#define NEXT_OPCODE() \
(ComoOpCode *)O_PTVAL(O_AVAL((frame)->code)->table[(frame)->pc++]);

#define POP() \
frame->cf_stack[--frame->cf_sp]

#define PUSH(Obj) \
frame->cf_stack[frame->cf_sp++] = Obj

#define OP1() \
opcode->operand

Object *retval = NULL;

for(;;)
{
ComoOpCode *opcode;
next_opcode:
opcode = NEXT_OPCODE();

#ifdef COMO_DEBUG
fprintf(stderr, "%s\n", instrstr(opcode));
#endif

switch(opcode->op_code)
{
TARGET(HALT)
{
return retval;
}

TARGET(LOAD_NAME)
{
Object *arg = OP1();
Object *value =
mapSearchEx(frame->cf_symtab, O_SVAL(arg)->value);

if(value == NULL) {
Como_SetError(
"Undefined symbol, %s", O_SVAL(arg)->value
);
} else {

O_INCRREF(value);

PUSH(value);

OPR_DECREF(opcode);
}

VM_DISPATCH();
}

TARGET(LOAD_CONST)
{
Object *arg = OP1();
PUSH(arg);
O_INCRREF(arg);

VM_DISPATCH();
}

TARGET(STORE_NAME)
{
Object *value = POP();
Object *name = OP1();

mapInsertEx(frame->cf_symtab, O_SVAL(name)->value, value);

O_INCRREF(value);

OPR_DECREF(opcode);

VM_DISPATCH();
}
TARGET(IADD)
{
Object *right = POP();
Object *left = POP();

if(Obj_CheckExact(right, IS_LONG) &&
Obj_CheckExact(left, IS_LONG))
{
long result = O_LVAL(left) + O_LVAL(right);

O_DECREF(left);
O_DECREF(right);

PUSH(newLong(result));
}
else
{
/* Temp char buffers */
char *_s1 = objectToString(left);
char *_s2 = objectToString(right);

Object *s1 = newString(_s1);
Object *s2 = newString(_s2);

Object *result = stringCat(s1, s2);

free(_s1);
free(_s2);

O_DECREF(s1);
O_DECREF(s2);

PUSH(result);
}

VM_DISPATCH();
}
}

if(exception) {
como_error_noreturn(frame, exmessage);
}
}

return retval;
}


static void destroy_frame(ComoFrame *frame)
{
uint32_t i;

objectDestroy(frame->lineno);
objectDestroy(frame->filename);
objectDestroy(frame->cf_symtab);
objectDestroy(frame->namedparameters);
objectDestroy(frame->name);

for(i = 0; i < O_AVAL(frame->code)->size; i++)
{
ComoOpCode *op = (ComoOpCode *)O_PTVAL((O_AVAL(frame->code))->table[i]);

if((op->flags & COMO_OP_CODE_OPERAND_USED) &&
!(op->flags & COMO_OP_CODE_OPERAND_FREE))
{
objectDestroy(op->operand);
}

free(op);
}

objectDestroy(frame->code);

fprintf(stdout, " --- Stack Pointer: %d\n", (int)frame->cf_sp);
fprintf(stdout, " --- Program Counter: %d\n", (int)frame->pc);

free(frame);

}

static void _como_compile_ast(ast_node *p, const char *filename, int dump_asm) {
Object *main_code = newArray(4);

global_frame = create_frame(main_code, "__main__");

global_frame->lineno = newLong(0L);
global_frame->filename = newString(filename);

como_compile(p, global_frame);

arrayPushEx(main_code, newPointer((void *)create_op(HALT, NULL)));

if(!dump_asm)
(void)Como_EvalFrame(global_frame);

destroy_frame(global_frame);
}


void como_compile_ast(ast_node *p, const char *filename) {
_como_compile_ast(p, filename, 0);
}


char *get_active_file_name(void) {
return "-";
}
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
CFLAGS = -L/usr/local/lib -g -Wall -Wextra -Wunused-parameter
CFLAGS = -DCOMO_DEBUG=1 -L/usr/local/lib -g -Wall -Wextra -Wunused-parameter
LIBS = -lobject
YACC = bison
YFLAGS = -y --warnings=all
LEX = flex

como: como_object.o como_ast_free.o como_io.o como_executor.o como_ast.o como_debug.o como_stack.o como_lexer.o como_parser.o como_compiler.o vm.o como.o
$(CC) como_io.o como_object.o como_executor.o como_debug.o como_ast.o como_stack.o como_parser.o como_lexer.o como_compiler.o vm.o como_ast_free.o como.o -o como $(CFLAGS) $(LIBS)
como: como_object.o como_ast_free.o como_io.o como_executor.o como_ast.o \
como_debug.o como_stack.o como_lexer.o como_parser.o como_compiler.o vm.o \
como_opcode.o como.o
$(CC) como_io.o como_object.o como_executor.o como_debug.o como_ast.o \
como_stack.o como_parser.o como_lexer.o como_compiler.o vm.o \
como_ast_free.o como_opcode.o como.o -o como $(CFLAGS) $(LIBS)

como_lexer.o: como_parser.c como_lexer.l

Expand Down
7 changes: 0 additions & 7 deletions como_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,6 @@
#define COMO_OP_CODE_OPERAND_USED 0x0001
#define COMO_OP_CODE_OPERAND_FREE 0x0002

typedef struct ComoOpCode
{
unsigned char op_code;
unsigned int flags;
Object *operand;
} ComoOpCode;

typedef struct ComoFrame
{
size_t cf_sp;
Expand Down
1 change: 1 addition & 0 deletions como_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void __attribute__ ((noreturn)) como_error_noreturn_ex(ComoFrame *frame, const c
#ifdef COMO_HAVE_DEBUG
#define como_debug(format, ...) \
como_debug_ex(__FILE__, __func__, __LINE__, format, ##__VA_ARGS__)

#else
#define como_debug(format, ...)
#endif
Expand Down
36 changes: 36 additions & 0 deletions como_opcode.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include <string.h>
#include <stdlib.h>

#include "como_opcode.h"
#include "como_debug.h"
#include "como_compiler.h"

const char * const str_opcodelist[] = {
"INONE", "LOAD_CONST", "STORE_NAME", "LOAD_NAME", "IS_LESS_THAN",
"JZ", "IPRINT", "IADD", "JMP", "IRETURN", "NOP", "LABEL", "HALT"
};

static char opcodebuffer[1024];

const char *instrstr(ComoOpCode *op)
{
memset(opcodebuffer, 0, sizeof(opcodebuffer));

const char *opcode = str_opcodelist[op->op_code];

memcpy(opcodebuffer, opcode, strlen(opcode));
memcpy(opcodebuffer + strlen(opcode), " ", 1);

if(op->operand != NULL)
{
char *operand = objectToString(op->operand);

memcpy(opcodebuffer + strlen(opcode) + 1, operand,
strlen(operand) + 1);

free(operand);
}

return opcodebuffer;
}

16 changes: 16 additions & 0 deletions como_opcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@
#ifndef COMO_OPCODE_H
#define COMO_OPCODE_H

#include <object.h>

typedef struct ComoOpCode
{
unsigned char op_code;
unsigned int flags;
unsigned int lineno;
Object *operand;
} ComoOpCode;

#define INONE 0x00
#define LOAD_CONST 0x01
#define STORE_NAME 0x02
Expand Down Expand Up @@ -54,4 +64,10 @@
#define LOAD_STRING 0x27
#define COMO_OPCODE_MAX 0x28

extern const char * const str_opcodelist[];

extern const char *instrstr(ComoOpCode *op);

//extern ComoOpCode *create_op(unsigned char op, int lineno, Object *arg);

#endif /* !COMO_OPCODE_H */
3 changes: 3 additions & 0 deletions test/sym
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
a = 1;
b = a;
c = a + b;
1 change: 1 addition & 0 deletions test/var
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a = ryan + 1;
Loading

0 comments on commit df46ebf

Please sign in to comment.