Skip to content

Commit

Permalink
Add bytecode hunks, disassembly, and constants
Browse files Browse the repository at this point in the history
  • Loading branch information
paked committed Sep 27, 2018
1 parent 223b0be commit cbc5fa1
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 32 deletions.
33 changes: 1 addition & 32 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,32 +1 @@
# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app
build
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "vendor/uslib"]
path = vendor/uslib
url = [email protected]:paked/us.git
45 changes: 45 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/bash

# Quick function which exits if the last command ran fails. Intended to be used
# after compiling something.
function compileCheckError() {
if [ ! $? -eq 0 ]; then
echo "Compilation failed, exiting."

exit 1
fi
}

PROJECT_DIR="$(git rev-parse --show-toplevel)"

if [ ! $? -eq 0 ]; then
echo "For whatever reason, project isn't being built as a git repository. Assuming current directory is the project dir."

PROJECT_DIR=$(pwd)
fi

BUILD_DIR=$PROJECT_DIR/build
SRC_DIR=$PROJECT_DIR/src
VENDOR_DIR=$PROJECT_DIR/vendor

USLIB_FLAGS="-I$VENDOR_DIR/uslib"

GCC="gcc"
GPP="g++ -Wall -Werror -std=c++11"

START_TIME=$(date +%s)

mkdir -p $BUILD_DIR
pushd $BUILD_DIR

echo "Building program..."
$GPP -o loaf $SRC_DIR/main.cpp $USLIB_FLAGS

echo "Done!"

END_TIME=$(date +%s)
TOTAL_TIME=$(expr $END_TIME - $START_TIME)

echo "Took to build project: $TOTAL_TIME"

popd
2 changes: 2 additions & 0 deletions env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
alias m="./build.sh"
alias r="./build/loaf"
Empty file added src/debug.cpp
Empty file.
193 changes: 193 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
#include <stdlib.h>
#include <stdio.h>

#include <us.hpp>

#define REALLOC(Type, ptr, count) ((Type*) realloc(ptr, count * sizeof(Type)))

enum ProgramResult : uint32 {
PROGRAM_RESULT_OK,
PROGRAM_RESULT_COMPILE_ERROR,
PROGRAM_RESULT_RUNTIME_ERROR
};

typedef uint8 Instruction;

enum OPCode : Instruction {
OP_RETURN,
OP_CONSTANT
};

typedef int Value;

// Constants keeps track of all the available constants in a program. Zero is initialisation.
// TODO(harrison): force constants count to fit within the maximum addressable space by opcodes (256)
#define CONSTANTS_CAPACITY_GROW(c) ( ((c) < 8) ? 8 : (c)*2 )
struct Constants {
int count;
int capacity;

// NOTE(harrison): Don't store any references to this pointer. It can change
// unexpectedly.
Value* values;
};

// returns -1 on failure
int constants_add(Constants* constants, Value val) {
if (constants->capacity < constants->count + 1) {
constants->capacity = CONSTANTS_CAPACITY_GROW(constants->capacity);

constants->values = REALLOC(Value, constants->values, constants->capacity);

if (constants->values == 0) {
return -1;
}
}

*(constants->values + constants->count) = val;

constants->count += 1;

return constants->count - 1;
}

// Hunk represents a section of Loaf bytecode from a file/module/whatever
// distinction I decide to make. Zero is initialisation. There is no explicit
// free function as Hunk's are expected to last the duration of the program, so
// the operating system can dispose of their memory much better than us.
#define HUNK_CAPACITY_GROW(c) ( ((c) < 8) ? 8 : (c)*2 )
struct Hunk {
int count;
int capacity;

// NOTE(harrison): Don't store any references to this pointer. It can change
// unexpectedly.
uint8* code;
uint32* lines;

Constants constants;
};

bool hunk_write(Hunk* hunk, Instruction in, uint32 line) {
if (hunk->capacity < hunk->count + 1) {
hunk->capacity = HUNK_CAPACITY_GROW(hunk->capacity);

hunk->code = REALLOC(uint8, hunk->code, hunk->capacity);
if (hunk->code == 0) {
return false;
}

hunk->lines = REALLOC(uint32, hunk->lines, hunk->capacity);
if (hunk->lines == 0) {
return false;
}
}

*(hunk->code + hunk->count) = in;
*(hunk->lines + hunk->count) = line;

hunk->count += 1;

return true;
}

int hunk_addConstant(Hunk* hunk, Value val) {
return constants_add(&hunk->constants, val);
}

int hunk_disassembleInstruction(Hunk* hunk, int offset) {
printf("%04d | %04d | ", hunk->lines[offset], offset);

uint8 in = hunk->code[offset];
#define SIMPLE_INSTRUCTION(code) \
case code: \
{ \
printf("%s\n", #code ); \
\
return offset + 1; \
} break; \

switch (in) {
SIMPLE_INSTRUCTION(OP_RETURN);

case OP_CONSTANT:
{
printf("%s %d\n", "OP_CONSTANT", hunk->constants.values[hunk->code[offset + 1]]);

return offset + 2;
} break;

default:
{
printf("Unknown opcode: %d\n", in);
};
}

return offset + 1;

#undef SIMPLE_INSTRUCTION
}

void hunk_disassemble(Hunk* hunk, const char* name) {
printf("=== %s ===\n", name);

int i = 0;

while (i < hunk->count) {
i += hunk_disassembleInstruction(hunk, i);
}
}

int main(int argc, char** argv) {
Hunk hunk = {0};

if (!hunk_write(&hunk, OP_CONSTANT, 0)) {
printf("ERROR: could not write chunk data\n");
return -1;
}

int constant = hunk_addConstant(&hunk, 22);
if (constant == -1) {
printf("ERROR: could not add constant\n");

return -1;
}

if (!hunk_write(&hunk, constant, 0)) {
printf("ERROR: could not write chunk data\n");

return -1;
}

if (!hunk_write(&hunk, OP_RETURN, 1)) {
printf("ERROR: could not write chunk data\n");
return -1;
}

hunk_disassemble(&hunk, "main");

return 0;
}

/*
int main(int argc, char** argv) {
Program program = {0};
Hunk hunk = {0};
Instruction constant = program_addConstant(&program, 22);
hunk_write(&hunk, OP_CONSTANT);
hunk_write(&hunk, constant);
ProgramResult res = program_execute(&program, &hunk);
if (res != PROGRAM_RESULT_OK) {
// printf("%s\n", program_getError(&program));
return 1;
}
printf("Program finished executing...\n");
return 0;
}*/
1 change: 1 addition & 0 deletions vendor/uslib
Submodule uslib added at ee6107

0 comments on commit cbc5fa1

Please sign in to comment.