Reference

This chapter is a reference for everything defined in the header files of the project.

Index

struct _allNameDefinitions
#include <dname.h>

A list of all of a name’s definitions.

Public Members

NameDefinition *definitions
size_t numDefinitions
struct _bcode
#include <dasm.h>

A struct for generic Decision bytecode.

Public Members

DebugInfo debugInfo
char *code

The bytecode as an array of bytes.

size_t size

The size of the bytecode in bytes.

struct _insToLink *linkList

An array of instructions that will need to be linked.

size_t linkListSize

The size of the linkList array.

struct _buildContext
#include <dcodegen.h>

A struct to keep track of information as we’re building the bytecode.

Public Members

Graph graph

The graph we’re building for.

LinkMetaList linkMetaList

A list of link metadata.

char *dataSection

The data section being built up.

size_t dataSectionSize

The size of the data section.

int stackTop

Where the stack pointer is relative to the base pointer.

bool debug

Do we want to build up debugging information?

struct _cFunction
#include <dcfunc.h>

A structure describing the semantics of a C function that Decision can call.

Public Members

DecisionCFunction function
const NodeDefinition definition
struct _compileOptions
#include <decision.h>

A set of options for when a sheet is compiled.

By default, there are no initial includes, and the sheet is not compiled in debug mode.

Public Members

struct _sheet **includes

A NULL-terminated array. Can itself be NULL to signify no initial includes.

struct _sheet **priors

A NULL-terminated array. If the sheet includes a sheet already in this list, an error is thrown.

bool debug

Compiles sheets with debug information. This allows for debugging the sheets, but sheets are not longer optimised. Note that compiled sheets do not store debug information, and thus cannot be debugged.

struct _debugAgenda
#include <ddebug.h>

Describes the “agenda” of how a debugging session should handle certain events.

NOTE: The breakpoint arrays can themselves be NULL, but if they aren’t, they should be terminated with an entry with a NULL sheet pointer.

Public Members

OnWireValue onWireValue
OnExecutionWire onExecutionWire
OnNodeActivated onNodedActivated
OnCall onCall
OnReturn onReturn
OnNodeBreakpoint onNodeBreakpoint
OnWireBreakpoint onWireBreakpoint
DebugNodeBreakpoint *nodeBreakpoints
DebugWireBreakpoint *wireBreakpoints
struct _debugInfo
#include <ddebug.h>

A collection of info used for debugging.

Public Members

InsDebugInfo *debugInfoList
size_t debugInfoSize
struct _debugNodeBreakpoint
#include <ddebug.h>

Describes a node breakpoint.

Public Members

struct _sheet *sheet
size_t nodeIndex
struct _debugSession
#include <ddebug.h>

A struct which keeps track of a debugging session.

NOTE: A sheet is pushed to the sheet stack if and only if the sheet has changed. If a function is called that is defined in the same sheet, this doesn’t count.

Public Members

DebugStackEntry sheetStack[DEBUG_SHEET_STACK_SIZE]
DVM vm
DebugAgenda agenda
int stackPtr
struct _debugStackEntry
#include <ddebug.h>

Describes an entry in the debugging session’s stack.

Public Members

struct _sheet *sheet
size_t numInternalCalls
struct _debugWireBreakpoint
#include <ddebug.h>

Describes a wire breakpoint.

Public Members

struct _sheet *sheet
Wire wire
struct _DVM

Public Members

char *pc

The program counter.

dint *basePtr

A pointer to the base of the stack.

dint *stackPtr

A pointer to the top of the stack.

dint *framePtr

A pointer to the start of the stack frame.

duint stackSize

The current size of the stack.

unsigned char _inc_pc

How many bytes to increment the program counter. This is determined automatically.

bool halted

The halted flag.

bool runtimeError

The runtime error flag.

struct _graph
#include <dgraph.h>

A collection of nodes and wires. Essentially a representation of the code that the user wrote.

Public Members

Node *nodes

The array of nodes.

size_t numNodes

The number of nodes in the nodes array.

Wire *wires

This list will be stored in lexicographical order, so binary search can be performed on it.

size_t numWires

The number of wires in the wires array.

struct _insCallInfo
#include <ddebug.h>

Describes a call in bytecode.

Public Members

struct _sheet *sheet
const struct _nodeDefinition *funcDef
bool isC
struct _insDebugInfo
#include <ddebug.h>

Describes what an instruction does.

Public Members

InsInfoCollection info
size_t ins
InsInfoType infoType
struct _insExecInfo
#include <ddebug.h>

Describes when an execution wire gets activated in bytecode.

Public Members

Wire execWire
union _insInfoCollection
#include <ddebug.h>

A union collection of all the different kinds of debug information that can be stored.

Public Members

InsValueInfo valueInfo
InsExecInfo execInfo
InsNodeInfo nodeInfo
InsCallInfo callInfo
struct _insNodeInfo
#include <ddebug.h>

Describes when a node “starts” in bytecode.

Public Members

size_t node
#include <dsheet.h>

A struct to describe which instructions needs to be replaced with linked pointers.

Public Members

size_t ins

Index of the LOADUI instruction in the text section.

size_t link

Index of the LinkMeta structure in the LinkMetaList.

struct _insValueInfo
#include <ddebug.h>

Describes when a value wire has a value in bytecode.

Public Members

Wire valueWire
int stackIndex
union _lexData
#include <dlex.h>

A union for storing the variable data types in Decision.

This is usually used in conjunction with DType to determine which element to get data from.

Public Members

dint integerValue
dfloat floatValue
bool booleanValue
char *stringValue
struct _lexStream
#include <dlex.h>

The structure of a lexical stream.

NOTE: It is actually implemented as an array.

Public Members

LexToken *tokenArray
size_t numTokens
struct _lexToken
#include <dlex.h>

The sturcture of a lexical token.

Public Members

LexType type
LexData data
struct _linkMeta
#include <dlink.h>

A structure describing a link.

Public Members

const char *name

The name of the object we are linking.

void *meta

A generic pointer to the metadata of the thing we are linking to, e.g. it can be a poiner to a SheetVariable or SheetFunction. If the value is -1, then we don’t know where the metadata is, so we will need to find out when linking.

char *_ptr

If the thing we’re linking to is in the sheet’s own data section, _ptr will store the index of the first byte before linking. Or if it is a function, it will be the index of the function in the text section instead. Otherwise, it is -1, which implies that the thing we want to link is in another castle… sorry, Mario.

LinkType type

The type of object we are linking.

struct _linkMetaList
#include <dlink.h>

A list of LinkMeta.

Public Members

LinkMeta *list
size_t size
struct _nameDefinition
#include <dname.h>

A struct saying where a name is defined.

Public Members

struct _sheet *sheet
CoreFunction coreFunc
struct _sheetVariable *variable
struct _sheetFunction *function
struct _cFunction *cFunction
union _nameDefinition::[anonymous] definition
NameType type
struct _node
#include <dgraph.h>

A struct for storing node data.

Public Members

const NodeDefinition *definition

The definition of the node. This is where you would get details like the node’s name.

size_t lineNum

What line is the node on in the original source code?

int *_stackPositions

Used by Code Generation.

DType *reducedTypes

Needs to be malloc’d, and have as many elements as sockets. Can be NULL if the types are the same as in *definition.

LexData *literalValues

Needs to be malloc’d, and have startOutputIndex elements. Can be NULL if the default values are the same as in *definition.

size_t startOutputIndex

This will by default be the same value as in the definition, but in the event that the definition allows for infinite inputs, this value will change to signify where the start of the outputs actually is.

NameDefinition nameDefinition

If the node is the getter or setter of a variable, then this points to the variable. If the node is a Define or Return node, this points to the function. Otherwise, it points to the name definition of the node.

struct _nodeDefinition
#include <dgraph.h>

Defined a node in Decision, i.e. it’s name, what sockets it has, etc.

Public Members

const char *name

The name of the node.

const char *description

The node description. Can be NULL.

const SocketMeta *sockets

An array of the node’s sockets.

size_t numSockets

The number of sockets the node has.

size_t startOutputIndex

Any socket before this index is an input socket, the rest are output sockets. This is also equivalent to the number of input sockets the node has.

bool infiniteInputs

Can the node has infinite inputs?

struct _nodeSocket
#include <dgraph.h>

A struct for indexing a node’s socket.

Public Members

size_t nodeIndex

The node index in the graph.

size_t socketIndex

The socket index in the node.

struct _sheet
#include <dsheet.h>

A struct for storing sheet data.

Public Members

Graph graph

Can be empty if the sheet came from a Decision object file.

DebugInfo _debugInfo

If the sheet is compiled in debug mode, this will contain debugging information.

LinkMetaList _link

What can be linked in this sheet?

const char *filePath

Essentially the name of the sheet.

const char *includePath

i.e. what was the argument of the Include property that included this sheet. Default value is NULL.

struct _sheet **includes

The list of included sheets.

size_t numIncludes

The number of included sheets.

SheetVariable *variables

The list of variables defined in this sheet.

size_t numVariables

The number of variables in this sheet.

SheetFunction *functions

The list of functions defined in this sheet.

size_t numFunctions

The number of functions in this sheet.

CFunction *cFunctions

The list of C functions defined in this sheet.

size_t numCFunctions

The number of C functions in this sheet.

size_t _main

Points to the index of the first instruction of Start, not the RET instruction one before.

char *_text

The compiled bytecode.

size_t _textSize

The number of bytes the compiled bytecode has.

char *_data

The compiled data section.

size_t _dataSize

The number of bytes the data section has.

InstructionToLink *_insLinkList

A list of which instructions should link to which items.

size_t _insLinkListSize

The number of instructions to link.

size_t numStarts

Used by Semantic Analysis.

int startNodeIndex

If this value is -1, then no Start node exists.

bool hasErrors

If true, the sheet cannot be run.

bool allowFree

Allow sheets that include this sheet to free it?

bool _isCompiled

Has the sheet been compiled?

bool _isLinked

Has the sheet been linked?

struct _sheetFunction
#include <dsheet.h>

A struct for storing function data.

Note that if you want to know if the function is a subroutine, you can use d_is_subroutine.

Public Members

const NodeDefinition functionDefinition

The definition of the function, i.e. it’s name, it’s sockets, etc.

const NodeDefinition defineDefinition

The definition of the function’s Define node. This is determined automatically when adding a function to a sheet.

const NodeDefinition returnDefinition

The definition of the function’s Return node. This is determined automatically when adding a function to a sheet.

size_t defineNodeIndex

Used in Semantic Analysis.

size_t numDefineNodes

Used in Semantic Analysis.

size_t lastReturnNodeIndex

Used in Semantic Analysis.

size_t numReturnNodes

Used in Semantic Analysis.

struct _sheet *sheet

The sheet the function belongs to.

struct _sheetVariable
#include <dsheet.h>

A struct for storing variable data.

Public Members

const NodeDefinition getterDefinition

The definition of the variable’s getter node. This is determined automatically when a variable is added to a sheet.

const SocketMeta variableMeta

The variable metadata, i.e. it’s name, it’s type, etc.

struct _sheet *sheet

The sheet the variable belongs to.

struct _socketMeta
#include <dgraph.h>

Defines the metadata of a socket, i.e. it’s type, name, description, etc.

Public Members

const char *name

The name of the socket.

const char *description

The socket description. Can be NULL.

DType type

The data type of the socket. Can be vague.

LexData defaultValue

The default value of the socket. Although it is not used by the compiler, it can be used by other programs to place a value in the socket by default.

struct _syntaxNode
#include <dsyntax.h>

A syntax node in the syntax tree. It has 2 pointers: One for the child, and one for the next sibling.

Public Members

struct _lexToken *info

Only defined if definition == STX_TOKEN.

struct _syntaxNode *child
struct _syntaxNode *sibling
size_t onLineNum
SyntaxDefinition definition
struct _syntaxResult
#include <dsyntax.h>

A structure for the results given by definitions.

Public Members

SyntaxNode *node
bool success
struct _syntaxSearchResult
#include <dsyntax.h>

A structure for returning all occurances of a syntax definition.

Public Members

SyntaxNode **occurances
size_t numOccurances
struct _wire
#include <dgraph.h>

A struct for connecting two sockets together, effectively an edge of a graph.

Public Members

NodeSocket socketFrom

The output socket.

NodeSocket socketTo

The input socket.

file dasm.h
#include “dcfg.h”#include “ddebug.h”#include “dlink.h”#include “dvm.h”#include <stddef.h>

Header for reading / manipulating Decision machine code.

Typedefs

typedef struct _bcode BCode

Functions

BCode d_malloc_bytecode(size_t size)

Create a malloc’d BCode object, with a set number of bytes.

Return

The BCode object with malloc’d elements.

Parameters
  • size: The number of bytes.

BCode d_bytecode_ins(DIns opcode)

Quickly create bytecode that is the size of an opcode, which also has its first byte set as the opcode itself.

Return

The opcode-initialised bytecode.

Parameters
  • opcode: The opcode to initialise with.

void d_bytecode_set_byte(BCode bcode, size_t index, char byte)

Given some bytecode, set a byte in the bytecode to a given value.

Parameters
  • bcode: The bytecode to edit.

  • index: The index of the byte in the bytecode to set.

  • byte: The value to set.

void d_bytecode_set_fimmediate(BCode bcode, size_t index, fimmediate_t fimmediate)

Given some bytecode, set a full immediate value into the bytecode.

NOTE: There are no functions to set byte or half immediates for a good reason: Mixing immediate sizes during code generation is a bad idea, as inserting bytecode in the middle of another bit of bytecode could make some smaller immediates invalid, and they would have to increase in size, which would be a pain. Instead, we only work with full immediates during code generation, and reduce down the full immediate instructions to byte or half immediate instructions in the optimisation stage.

Parameters
  • bcode: The bytecode to edit.

  • index: The starting index of the section of the bytecode to edit.

  • fimmediate: The full immediate value to set.

void d_free_bytecode(BCode *bcode)

Free malloc’d elements of bytecode.

Parameters
  • bcode: The bytecode to free.

void d_concat_bytecode(BCode *base, BCode *after)

Append bytecode to the end of another set of bytecode.

Parameters
  • base: The bytecode to be added to.

  • after: The bytecode to append. Not changed.

void d_asm_text_dump(char *code, size_t size)

De-assemble Decision machine code, and print it to stdout.

Parameters
  • code: The machine code array to print.

  • size: The size of the machine code array.

void d_asm_data_dump(char *data, size_t size)

Print the data section in hex format.

Parameters
  • data: Pointer to the beginning of the data section.

  • size: The size of the data section.

void d_asm_lmeta_dump(LinkMetaList meta)

Print the lmeta section.

Parameters
  • meta: The link meta list to print.

Print the link section.

Parameters
  • list: The list of relational records to print.

  • size: The size of the list.

void d_asm_incl_dump(struct _sheet **includes, size_t size)

Print the incl section.

Parameters
  • includes: The list of sheets that are included.

  • size: The size of the list.

void d_asm_dump_all(struct _sheet *sheet)

Dump all of the sections of a sheet object.

Parameters
  • sheet: The sheet object to dump.

file dcfg.h
#include <stdint.h>

This header configures the source code, depending on macro definitions and the environment.

Defines

dint

An integer.

If DECISION_32 is defined, dint will be equivalent to int32_t. Otherwise, it will be equivalent to int64_t.

duint

An unsigned integer.

If DECISION_32 is defined, duint will be equivalent to uint32_t. Otherwise, it will be equivalent to uint64_t.

dfloat

A floating point number.

If DECISION_32 is defined, dfloat will be equivalent to float. Otherwise, it will be equivalent to double.

DINT_PRINTF_d

Helper definition for when we want to print a signed integer type in printf.

DINT_PRINTF_u

Helper definition for when we want to print an unsigned integer type in printf.

DINT_PRINTF_x

Helper definition for when we want to print an hexadecimal integer in printf.

DECISION_API

Goes in front of all functions and variables that we want programs to see.

By default, it is just extern, but since Windows likes being the special one, on Windows (if you build a DLL) it is __declspec(dllexport).

file dcfunc.h
#include “dcfg.h”#include “dgraph.h”#include “dtype.h”

This header file deals with C functions that Decision code can call.

Typedefs

typedef void (*DecisionCFunction)(DVM *vm)

This function prototype describes what C functions that are called by Decision should look like.

typedef struct _cFunction CFunction

Functions

CFunction d_create_c_function(DecisionCFunction function, const char *name, const char *description, SocketMeta *sockets, size_t numInputs, size_t numOutputs)

Create a function that calls a C function.

Parameters
  • function: The C function to call when this node is activated.

  • name: The name of the function.

  • description: The description of the function.

  • sockets: An array of socket metadata. This array should have at least numInputs + numOutputs elements in.

  • numInputs: The number of input sockets the function has.

  • numOutputs: The number of output sockets the function has.

CFunction d_create_c_subroutine(DecisionCFunction function, const char *name, const char *description, SocketMeta *sockets, size_t numInputs, size_t numOutputs)

Create a subroutine that calls a C function.

NOTE: The sockets array should not have any execution sockets in, these will automatically be added. Thus numInputs and numOutputs should not account for any execution nodes either.

Parameters
  • function: The C function to call when this node is activated.

  • name: The name of the function.

  • description: The description of the function.

  • sockets: An array of socket metadata. This array should have at least numInputs + numOutputs elements in.

  • numInputs: The number of input sockets the function has.

  • numOutputs: The number of output sockets the function has.

file dcodegen.h
#include “dasm.h”#include “dcfg.h”#include “ddebug.h”#include “dlink.h”#include “dsheet.h”#include “dvm.h”#include <stdbool.h>#include <stddef.h>

This header generates the bytecode from the user’s source code, so that it can be run on a Decision VM.

Defines

STACK_INDEX_TOP(context, index)

Given the index from the base of the stack, get the index from the top of the stack with the current context.

IS_INDEX_TOP(context, index)

Given the index from the base of the stack, is the index the top of the stack?

Typedefs

typedef struct _buildContext BuildContext

Functions

Add a future link to an instruction in bytecode.

Parameters
  • context: The context needed to store the link.

  • bcode: The bytecode containing the instruction to link.

  • insIndex: The index of the instruction to edit when linking is taking place.

  • linkMeta: The link metadata.

  • indexInList: Stores in the reference the index of the new metadata in the list.

  • wasDuplicate: Sets the reference to true if a matching linkMeta was already found in the array, false otherwise.

char *d_allocate_from_data_section(BuildContext *context, size_t size, size_t *index)

Allocate a number of bytes from the data section for some data. That data could be a string literal, variable, etc.

Return

A pointer to the start of the new allocation. Returns NULL if size is 0.

Parameters
  • context: The context that contains the built-up data section.

  • size: The size of the allocation in bytes.

  • index: Overwrites with the index of the start of the allocation from the start of the data section.

size_t d_allocate_string_literal_in_data(BuildContext *context, BCode *linkCode, size_t insIndex, char *stringLiteral)

Given a string literal, allocate memory from the data section to store the literal.

If there is a duplicate string literal found, the links to string literal passed are pointed to the literal already stored in the data section. NOTE: If the string was a duplicate, it is freed!

Return

The index of the data section where the string literal starts.

Parameters
  • context: The context containing the built-up data section.

  • linkCode: The bytecode to link to the string literal in the data section.

  • insIndex: The index of the LOADUI instruction to replace when linking is taking place.

  • stringLiteral: The string literal to place in the data section.

void d_allocate_variable(BuildContext *context, SheetVariable *variable, size_t size, size_t indexInLinkMeta)

Allocate memory from the data section to store a variable.

Parameters
  • context: The context containing the built-up data section.

  • variable: The variable data.

  • size: How many bytes to allocate for the variable.

  • indexInLinkMeta: The index of the variable’s LinkMeta entry in the build context.

BCode d_push_literal(BuildContext *context, NodeSocket socket, bool cvtFloat)

Generate bytecode to push a literal onto the stack.

Return

Bytecode to push the socket’s literal onto the stack.

Parameters
  • context: The context needed to build the bytecode.

  • socket: The socket of the literal to push onto the stack.

  • cvtFloat: Converts the literal to a float if possible.

BCode d_push_variable(BuildContext *context, size_t nodeIndex)

Given a node that is the getter of a variable, generate bytecode to push the value of the variable onto the stack.

Return

Bytecode to push the variable’s value onto the stack.

Parameters
  • context: The context needed to build the bytecode.

  • nodeIndex: The index of the node that is the getter of a variable.

BCode d_push_input(BuildContext *context, NodeSocket socket, bool forceFloat)

Given an input socket, generate bytecode to push the value of the input to the top of the stack.

Return

Bytecode to push the input’s value onto the stack.

Parameters
  • context: The context needed to build the bytecode.

  • socket: The input socket to get the value for.

  • forceFloat: Force integers to be converted to floats.

BCode d_push_node_inputs(BuildContext *context, size_t nodeIndex, bool order, bool ignoreLiterals, bool forceFloat)

Given a node, generate bytecode to push the values of the inputs to the top of the stack.

Return

Bytecode to push all input’s values onto the stack.

Parameters
  • context: The context needed to generate the bytecode.

  • nodeIndex: The index of the node whose input sockets to generate bytecode for.

  • order: If true, the inputs are pushed in order, such that the last input is at the top. If false, the inputs are pushed in reverse order, such that the first input is at the top.

  • ignoreLiterals: Do not generate bytecode for non-float literal inputs.

  • forceFloat: Force integers to be converted to floats.

BCode d_generate_operator(BuildContext *context, size_t nodeIndex, DIns opcode, DIns fopcode, DIns fiopcode, bool forceFloat)

Given an operator node, generate the bytecode for it.

Return

Bytecode to get the output of an operator.

Parameters
  • context: The context needed to generate the bytecode.

  • nodeIndex: The index of the operator node to get the result for.

  • opcode: The operator instruction.

  • fopcode: The float variant of the instruction.

  • fiopcode: The full immediate variant of the instruction.

  • forceFloat: Should the output always be a float?

BCode d_generate_comparator(BuildContext *context, size_t nodeIndex, DIns opcode, DIns fopcode, fimmediate_t strCmpArg, bool notAfter)

Given a comparator node, generate the bytecode for it.

Return

Bytecode to get the output of a comparator.

Parameters
  • context: The context needed to generate the bytecode.

  • nodeIndex: The index of the comparator node to get the result for.

  • opcode: The comparator instruction.

  • fopcode: The float variant of the instruction.

  • strCmpArg: The SYS_STRCMP argument to use to compare strings.

  • notAfter: Do we invert the answer at the end?

BCode d_generate_call(BuildContext *context, size_t nodeIndex)

Given a node that calls a function or subroutine, generate the bytecode to call it.

Return

Bytecode to call the function or subroutine.

Parameters
  • context: The context needed to generate the bytecode.

  • nodeIndex: The index of the node to generate the bytecode for.

BCode d_push_argument(BuildContext *context, NodeSocket socket)

Given an output socket that is a function/subroutine argument, generate bytecode to push the value of the argument to the top of the stack.

Return

Bytecode to push the argument.

Parameters
  • context: The context needed to generate the bytecode.

  • socket: The output socket representing the function argument.

BCode d_generate_return(BuildContext *context, size_t returnNodeIndex)

Given a Return node, generate the bytecode to return from the function/subroutine with the return values.

Return

Bytecode to return from the function/subroutine.

Parameters
  • context: The context needed to generate the bytecode.

  • returnNodeIndex: The Return node to return with.

BCode d_generate_nonexecution_node(BuildContext *context, size_t nodeIndex)

Given a non-execution node, generate the bytecode to get the output.

Return

Bytecode to run the nonexecution node’s function.

Parameters
  • context: The context needed to generate the bytecode.

  • nodeIndex: The index of the non-execution node.

BCode d_generate_execution_node(BuildContext *context, size_t nodeIndex, bool retAtEnd)

Given an execution node, generate the bytecode to get the output.

Return

Bytecode to run the execution node’s subroutine.

Parameters
  • context: The context needed to generate the bytecode.

  • nodeIndex: The execution node.

  • retAtEnd: Should the bytecode return at the end?

BCode d_generate_start(BuildContext *context, size_t startNodeIndex)

Given a Start node, generate the bytecode for the sequence starting from this node.

Return

The bytecode generated for the Start function.

Parameters
  • context: The context needed to generate the bytecode.

  • startNodeIndex: The Start node index.

BCode d_generate_function(BuildContext *context, SheetFunction func)

Given a function, generate the bytecode for it.

Return

The bytecode generated for the function.

Parameters
  • context: The context needed to generate the bytecode.

  • func: The function to generate the bytecode for.

void d_codegen_compile(Sheet *sheet, bool debug)

Given that Semantic Analysis has taken place, generate the bytecode for a given sheet.

Parameters
  • sheet: The sheet to generate the bytecode for.

  • debug: If true, we include debug information as well.

file dcore.h
#include “dcfg.h”

This header contains the core Decision functions.

Defines

NUM_CORE_FUNCTIONS

Returns the number of core functions.

Typedefs

typedef enum _coreFunction CoreFunction

Enums

enum _coreFunction

An enum of the core functions.

NOTE: They need to be in alphabetical order in order for binary search to work!

Values:

CORE_ADD
CORE_AND
CORE_DIV
CORE_DIVIDE
CORE_EQUAL
CORE_FOR
CORE_IF_THEN
CORE_IF_THEN_ELSE
CORE_LENGTH
CORE_LESS_THAN
CORE_LESS_THAN_OR_EQUAL
CORE_MOD
CORE_MORE_THAN
CORE_MORE_THAN_OR_EQUAL
CORE_MULTIPLY
CORE_NOT
CORE_NOT_EQUAL
CORE_OR
CORE_PRINT
CORE_SET
CORE_SUBTRACT
CORE_TERNARY
CORE_WHILE
CORE_XOR

Functions

const NodeDefinition *d_core_get_definition(const CoreFunction core)

Get the definition of a core function.

Return

The definition of the core function.

Parameters
  • core: The core function to get the definition of.

CoreFunction d_core_find_name(const char *name)

Given the name of the core function, get the CoreFunction.

Return

The corresponding CoreFunction. Value is -1 if the name doesn’t exist as a core function.

Parameters
  • name: The name to query.

void d_core_dump_json()

Dump the core functions and subroutines to stdout in JSON format.

file ddebug.h
#include “dcfg.h”#include “dgraph.h”#include “dlex.h”#include “dtype.h”#include “dvm.h”#include <stddef.h>

This header contains functions to debug Decision sheets.

Defines

NO_DEBUG_INFO

An empty DebugInfo struct.

NO_AGENDA

An empty agenda, i.e. nothing will happen when debugging.

DEBUG_SHEET_STACK_SIZE

The size of a sheet stack in a debugging session. Since the stack is not dynamically allocated, this number should be just above the realistic number of sheet “hops”.

Typedefs

typedef struct _insValueInfo InsValueInfo
typedef struct _insExecInfo InsExecInfo
typedef struct _insNodeInfo InsNodeInfo
typedef struct _insCallInfo InsCallInfo
typedef enum _insInfoType InsInfoType
typedef union _insInfoCollection InsInfoCollection
typedef struct _insDebugInfo InsDebugInfo
typedef struct _debugInfo DebugInfo
typedef void (*OnWireValue)(Sheet *sheet, Wire wire, DType type, LexData value)

Called when a value is transfered over a wire during a debugging session.

typedef void (*OnExecutionWire)(Sheet *sheet, Wire wire)

Called when an execution wire is activated during a debugging session.

typedef void (*OnNodeActivated)(Sheet *sheet, size_t nodeIndex)

Called when a node is activated during a debugging session.

typedef void (*OnCall)(Sheet *sheet, const NodeDefinition *funcDef, bool isC)

Called when a call occurs during a debugging session.

typedef void (*OnReturn)()

Called when a return occurs during a debugging session.

typedef void (*OnNodeBreakpoint)(Sheet *sheet, size_t nodeIndex)

Called when a node breakpoint is hit.

typedef void (*OnWireBreakpoint)(Sheet *sheet, Wire wire)

Called when a wire breakpoint is hit.

typedef struct _debugNodeBreakpoint DebugNodeBreakpoint
typedef struct _debugWireBreakpoint DebugWireBreakpoint
typedef struct _debugAgenda DebugAgenda
typedef struct _debugStackEntry DebugStackEntry
typedef struct _debugSession DebugSession

Enums

enum _insInfoType

The different kinds of information debugging can store and output.

Values:

INFO_VALUE
INFO_EXEC
INFO_NODE
INFO_CALL

Functions

void d_debug_add_value_info(DebugInfo *debugInfo, size_t ins, InsValueInfo valueInfo)

Add value information to a list of debug information.

Parameters
  • debugInfo: The debug info to add the value info to.

  • valueInfo: The value info to add.

void d_debug_add_exec_info(DebugInfo *debugInfo, size_t ins, InsExecInfo execInfo)

Add execution information to a list of debug information.

Parameters
  • debugInfo: The debug into to add the execution info to.

  • execInfo: The execution info to add.

void d_debug_add_node_info(DebugInfo *debugInfo, size_t ins, InsNodeInfo nodeInfo)

Add node information to a list of debug information.

Parameters
  • debugInfo: The debug info to add the node info to.

  • nodeInfo: The node info to add.

void d_debug_add_call_info(DebugInfo *debugInfo, size_t ins, InsCallInfo callInfo)

Add call information to a list of debug information.

Parameters
  • debugInfo: The debug info to add the call info to.

  • callInfo: The call info to add.

void d_debug_dump_info(DebugInfo debugInfo)

Dump the debugging information to stdout.

Parameters
  • debugInfo: The debugging info to dump.

void d_debug_free_info(DebugInfo *debugInfo)

Free debugging information.

Parameters
  • debugInfo: The debugging info to free.

DebugSession d_debug_create_session(struct _sheet *sheet, DebugAgenda agenda)

Create a debugging session.

Return

A debugging session in it’s starting state.

Parameters
  • sheet: The sheet to debug.

  • agenda: The agenda the session should use.

bool d_debug_continue_session(DebugSession *session)

Continue a debugging session until either a breakpoint is hit, or the VM halts.

Return

True if the debugger hit a breakpoint, false if the VM halted.

Parameters
  • session: The session to continue.

void d_debug_stop_session(DebugSession *session)

Stop a debugging session, freeing all of the memory malloc’d by the session. The session should not be used afterwards.

Parameters
  • session: The session to stop.

file decision.h
#include “dcfg.h”#include <stdbool.h>#include <stdio.h>

The main header for general use.

NOTE: This file is generated from decision.in.h with CMake.

Defines

DECISION_VERSION_MAJOR

The major verion number.

DECISION_VERSION_MINOR

The minor verion number.

DECISION_VERSION_PATCH

The patch verion number.

_STR(x)
_VERSION_STR(x)
DECISION_VERSION

The current version of Decision.

DEFAULT_COMPILE_OPTIONS

The default compile options.

VERBOSE(level, ...)

A macro to print verbose information depending on the level.

The arguments after level are fed into a printf statement.

If the level given is greater than or equal to the current verbose level, the message will be printed. Otherwise, it will not be printed.

Parameters
  • level: The verbose level at which to start displaying the message.

Typedefs

typedef struct _compileOptions CompileOptions

Functions

char d_get_verbose_level()

Get the current verbose level.

Return

The verbose level. It will be a number between 0 and 5.

void d_set_verbose_level(char level)

Set the current verbose level.

Parameters
  • level: The verbose level to set. If the number is bigger than 5, then the verbose level is set to 5.

bool d_run_sheet(struct _sheet *sheet)

Run the code in a given sheet, given that it has gone through d_codegen_compile, and it has exactly one defined Start function.

Return

If the sheet ran without any errors.

Parameters
  • sheet: The sheet to run.

bool d_run_function(struct _DVM *vm, struct _sheet *sheet, const char *funcName)

Run the specified function/subroutine in a given sheet, given the sheet has gone through d_codegen_compile.

Return

If the function/subroutine ran without any errors.

Parameters
  • vm: The VM to run the function on. The reason it is a seperate argument is because it allows you to push and pop arguments and return values seperately.

  • sheet: The sheet the function lives in.

  • funcName: The name of the function/subroutine to run.

Sheet *d_load_string(const char *source, const char *name, CompileOptions *options)

Take Decision source code and compile it into bytecode, but do not run it.

Return

A malloc’d sheet containing all of the compilation info.

Parameters
  • source: The source code to compile.

  • name: The name of the sheet. If NULL, it is set to "source".

  • options: A set of compile options. If NULL, the default settings are used.

bool d_run_string(const char *source, const char *name, CompileOptions *options)

Take Decision source code and compile it into bytecode. If it compiled successfully, run it in the virtual machine.

Return

If the code compiled/ran without any errors.

Parameters
  • source: The source code the compile.

  • name: The name of the sheet. If NULL, it is set to "source".

  • options: A set of compile options. If NULL, the default settings are used.

bool d_compile_string(const char *source, const char *filePath, CompileOptions *options)

Take Decision source code and compile it into bytecode. Then save it into a binary file if it compiled successfully.

Return

If the code compiled without any errors.

Parameters
  • source: The source code to compile.

  • filePath: Where to write the object file to.

  • options: A set of compile options. If NULL, the default settings are used.

Sheet *d_load_source_file(const char *filePath, CompileOptions *options)

Take Decision source code from a file and compile it into bytecode, but do not run it.

Return

A malloc’d sheet containing all of the compilation info.

Parameters
  • filePath: The file path of the source file to compile.

  • options: A set of compile options. If NULL, the default settings are used.

bool d_run_source_file(const char *filePath, CompileOptions *options)

Take Decision source code in a file and compile it into bytecode. If it compiled successfully, run it in the virtual machine.

Return

If the code compiled/ran without any errors.

Parameters
  • filePath: The file path of the source file to compile.

  • options: A set of compile options. If NULL, the default settings are used.

bool d_compile_file(const char *filePathIn, const char *filePathOut, CompileOptions *options)
Sheet *d_load_object_file(const char *filePath, CompileOptions *options)

Take a Decision object file and load it into memory.

Return

A malloc’d sheet object containing all of the compilation info.

Parameters
  • filePath: The file path of the object file.

  • options: A set of compile options. If NULL, the default settings are used. The debug setting is ignored, as object files cannot be debugged.

bool d_run_object_file(const char *filePath, CompileOptions *options)

Take a Decision object file, load it into memory, and run it in the virtual machine.

Return

If the code ran without any errors.

Parameters
  • filePath: The file path of the object file.

  • options: A set of compile options. If NULL, the default settings are used. The debug setting is ignored, as object files cannot be debugged.

short d_is_object_file(const char *filePath)

Decide whether a given file is a Decision object file, a Decision source file, or neither.

Return

1 if it is an object file, 0 if it is a source file, -1 if the file does not exist.

Parameters
  • filePath: The file path of the file to examine.

Sheet *d_load_file(const char *filePath, CompileOptions *options)

Take a Decision file, decide whether it is a source or an object file based on its contents, and load it into memory.

Return

A malloc’d sheet object containing all of the compilation info.

Parameters
  • filePath: The file path of the file to load.

  • options: A set of compile options. If NULL, the default settings are used.

bool d_run_file(const char *filePath, CompileOptions *options)

Take a Decision file, decide whether it is a source or an object file based on its contents, and run it in the virtual machine.

Return

If the code compiled/ran without any errors.

Parameters
  • filePath: The file path of the file to load.

  • options: A set of compile options. If NULL, the default settings are used.

file derror.h
#include “dcfg.h”#include <stdbool.h>#include <stddef.h>

This header deals with errors in Decision during runtime or compile time.

Defines

MAX_ERROR_SIZE

A macro constant stating the maximum size of formatted error messages.

ERROR_COMPILER(filePath, lineNum, isError, ...)

A macro function to be able to print formatted error messages.

If you don’t need the error to be formatted, it is more efficient to directly use d_error_compiler_push.

Functions

void d_error_compiler_push(const char *message, const char *filePath, size_t lineNum, bool isError)

Push a compile-time error message to the error list.

Parameters
  • message: The error message itself.

  • filePath: The file where the error occured.

  • lineNum: The line number of the error.

  • isError: If true, show ERROR, otherwise, show WARNING.

bool d_error_report()

Report if there were any compile-time errors or warnings to stdout.

Return

true if there were errors (warnings do not count as errors), false otherwise.

void d_error_free()

Free any compile-time error messages saved.

Should be called at the end of compilation.

file dgraph.h
#include “dcfg.h”#include “dname.h”#include “dtype.h”#include <stddef.h>

This header contains the definitions of Decision graphs, and their nodes and wires.

Defines

EMPTY_GRAPH

A graph wil no nodes or wires defined.

IS_WIRE_FROM(graph, wireIndex, socket)

Check if a wire starts from a given socket.

Typedefs

typedef struct _socketMeta SocketMeta
typedef struct _nodeDefinition NodeDefinition
typedef struct _nodeSocket NodeSocket
typedef struct _wire Wire
typedef struct _node Node
typedef struct _graph Graph

Functions

size_t d_definition_num_inputs(const NodeDefinition *nodeDef)

Get the number of input sockets a definition has.

Return

The number of input sockets the definition has.

Parameters
  • nodeDef: The definition of the node.

size_t d_definition_num_outputs(const NodeDefinition *nodeDef)

Get the number of output sockets a definition has.

Return

The number of output sockets the definition has.

Parameters
  • nodeDef: The definition of the node.

bool d_is_execution_definition(const NodeDefinition *nodeDef)

Is the definition an execution definition, i.e. does it have at least one execution socket?

Return

If the definition is an execution definition.

Parameters
  • nodeDef: The definition of the node.

bool d_is_node_index_valid(Graph graph, size_t nodeIndex)

Given a graph, does a given node index exist within that graph?

Return

If the node index exists in the graph.

Parameters
  • graph: The graph to query.

  • nodeIndex: The node index to query.

size_t d_node_num_inputs(Graph graph, size_t nodeIndex)

Get the number of input sockets a node has.

Return

The number of input sockets the node has, 0 if the index is not valid.

Parameters
  • graph: The graph to query.

  • nodeIndex: The node index to query.

size_t d_node_num_outputs(Graph graph, size_t nodeIndex)

Get the number of output sockets a node has.

Return

The number of output sockets the node has, 0 if the index is not valid.

Parameters
  • graph: The graph to query.

  • nodeIndex: The node index to query.

size_t d_is_execution_node(Graph graph, size_t nodeIndex)

Is the node an execution node, i.e. does it have at least one execution socket?

Return

If the node is an execution node.

Parameters
  • graph: The graph to query.

  • nodeIndex: The node index to query.

bool d_is_socket_index_valid(const NodeDefinition *nodeDef, size_t socketIndex)

Given a node definition, does a given socket index exist within that node?

Return

If the socket index exists in the node.

Parameters
  • nodeDef: The node definition to query.

  • socketIndex: The socket index to query.

const NodeDefinition *d_get_node_definition(Graph graph, size_t nodeIndex)

Given the index of a node, get the definition of the node.

Return

The definition of the node, or NULL if the index does not exist.

Parameters
  • graph: The graph the node belongs to.

  • nodeIndex: The node to get the definition of.

bool d_is_node_socket_valid(Graph graph, NodeSocket socket)

Given a NodeSocket, does it exist in the graph?

Return

If the node socket index exists in the given graph.

Parameters
  • graph: The graph to query.

  • socket: The node socket index to query.

bool d_is_input_socket(Graph graph, NodeSocket socket)

Is the given socket an input socket?

Return

If the socket is an input socket.

Parameters
  • graph: The graph the socket belongs to.

  • socket: The socket to query.

SocketMeta d_get_socket_meta(Graph graph, NodeSocket nodeSocket)

Get the metadata of a node’s socket.

Return

The socket’s metadata.

Parameters
  • graph: The graph the socket belongs to.

  • nodeSocket: The socket to get the metadata for.

short d_wire_cmp(Wire wire1, Wire wire2)

Since wires are stored in lexicographical order, return an integer value stating the equality, or inequality of the wires.

Return

0 if wire1 == wire2, > 0 if wire1 > wire2, and < 0 if wire1 < wire2.

Parameters
  • wire1: The first wire.

  • wire2: The second wire.

int d_wire_find_first(Graph graph, NodeSocket socket)

Given a socket, find the first wire in a sheet that originates from the given socket.

Return

The index of the wire, or -1 if it is not found.

Parameters
  • graph: The graph to search for the wire.

  • socket: The “from” socket to search for.

size_t d_socket_num_connections(Graph graph, NodeSocket socket)

Get the number of connections via wires a socket has.

Return

The number of connected wires to a socket.

Parameters
  • graph: The graph the socket belongs to.

  • socket: The socket to query.

bool d_graph_add_wire(Graph *graph, Wire wire, const char *filePath)

Add a wire to a sheet, connecting two sockets.

Return

If the operation was successful.

Parameters
  • graph: The graph to add the wire to. Both nodes have to belong to this graph.

  • wire: The wire to add to the sheet.

  • filePath: In case we error, say where we errored from.

size_t d_graph_add_node(Graph *graph, Node node)

Add a node to a graph.

Return

The new node index.

Parameters
  • graph: The graph to add the node to.

  • node: The node to add.

void d_graph_dump(Graph graph)

Dump the contents of a Graph to stdout.

Parameters
  • graph: The graph to dump.

void d_graph_free(Graph *graph)

Free the malloc’d elements of a Graph structure. Note that you may also need to free the Graph itself if you malloc’d it.

Parameters
  • graph: The graph to free.

void d_definition_free(const NodeDefinition nodeDef, bool freeSocketStrs)

Free the malloc’d elements of a NodeDefinition.

Parameters
  • nodeDef: The definition whose elements free from memory.

  • freeSocketStrs: If true, free the names and descriptions of sockets.

file dlex.h
#include “dcfg.h”#include <stdbool.h>#include <stddef.h>

This header provides Lexical Analysis for Decision.

Defines

LEX_DATATYPE_START

The starting token of the data types.

LEX_DATATYPE_END

The ending token of the data types.

LEX_VARTYPE_START

The starting token of the variable types.

LEX_VARTYPE_END

The ending token of the variable types.

LEX_LITERAL_START

The starting token of the literal types.

LEX_LITERAL_END

The ending token of the literal types.

Typedefs

typedef enum _lexType LexType
typedef union _lexData LexData
typedef struct _lexToken LexToken
typedef struct _lexStream LexStream

Enums

enum _lexType

An enum for all the types of lexical tokens.

Values:

TK_NAME

The name token represents the name of all nodes, variables and properties.

TK_EXECUTIONTYPE
TK_INTEGERTYPE
TK_FLOATTYPE
TK_STRINGTYPE
TK_BOOLEANTYPE
TK_INTEGERLITERAL
TK_FLOATLITERAL
TK_STRINGLITERAL
TK_BOOLEANLITERAL
TK_IDENTIFIER
TK_OUTPUT
TK_LINE
TK_COMMA
TK_OR
TK_EOSNL
TK_EOSSC
TK_LBRACKET
TK_LPROPERTY
TK_LARRAY
TK_RBRACKET
TK_RPROPERTY
TK_RARRAY

Functions

bool d_lex_is_alpha(char c)

Checks if a character is a letter of the alphabet.

Return

If the character is a letter of the alphabet.

Parameters
  • c: The character to query.

bool d_lex_is_digit(char c)

Check if a character is a digit.

Return

If the character is a digit.

Parameters
  • c: The character to query.

bool d_lex_is_hex(char c)

Check if a character is a hexadecimal digit.

Return

If the character is a hexadecimal digit.

Parameters
  • c: The character to query.

bool d_lex_is_octal(char c)

Check if a character is an octal digit.

Return

If the character is an octal digit.

Parameters
  • c: The character to query.

bool d_lex_is_name_char(char c)

Check if a character is a valid name character.

Return

If the character is a valid name character.

Parameters
  • c: The character to query.

const char *d_lex_get_string_literal(const char *source, size_t *i, const char *filePath, size_t lineNum)

For some source text, starting at the character at index *i, extract a string literal.

The first character (i.e. source[*i]) must be a string quote, or an error will occur.

Return

A malloc’d string. NULL if the string is errorneous.

Parameters
  • source: The source text.

  • i: A pointer to an index, where the start of a string literal should be. It will be set to just after where the literal ends when the function returns.

  • filePath: In the event we error, say what the file path was.

  • lineNum: In the event we error, say what line it was on.

const char *d_lex_get_name(const char *source, size_t *i, const char *filePath, size_t lineNum)

For some source text, starting at the character at index *i, extract a name.

It must follow the syntax rules for names.

Return

A malloc’d string representing the name. NULL if the name is errorneous.

Parameters
  • source: The source text.

  • i: A pointer to an index, where the start of a name should be. It will be set to just after where the name ends when the function returns.

  • filePath: In the event we error, say what the file path was.

  • lineNum: In the event we error, say what line it was on.

LexStream d_lex_create_stream(const char *source, const char *filePath)

Create a stream of lexical tokens from some source text that you can extract tokens from.

NOTE: The source code needs to have a newline (\n) as it’s last non-NULL character!

Return

A new malloc’d LexStream. If there was an error, numTokens = 0 and tokenArray = NULL.

Parameters
  • source: The source text. Can be text read from a source file.

  • filePath: In case we error, say what the file path was.

void d_lex_free_stream(LexStream stream)

Frees the token array from a stream. The stream should not be used after this function is called on it.

Parameters
  • stream: The stream to free from memory.

void d_lex_dump_stream(LexStream stream)

Print the contents of a LexStream.

Parameters
  • stream: The stream to print to the screen.

file dlink.h
#include “dcfg.h”#include <stddef.h>

This header deals with linking sheets together before they are run.

Typedefs

typedef enum _linkType LinkType
typedef struct _linkMeta LinkMeta
typedef struct _linkMetaList LinkMetaList

Enums

enum _linkType

Describes what type of object we want to link.

Values:

A string literal.

A variable that stores it’s data directly.

A variable that stores it’s data indirectly, e.g. a String.

The default value of a string variable.

A function.

A C function.

Functions

Create a new LinkMeta structure.

Return

A new LinkMeta with the given parameters.

Parameters
  • type: The type of object this link will point to.

  • name: The name of the object this link will point to.

  • meta: A pointer to the metadata of the object the link points to.

Create an empty LinkMetaList.

Return

An empty LinkMetaList.

Add a LinkMeta item to a list.

Parameters
  • list: The list to push the item onto.

  • item: The item to push onto.

Free a LinkMetaList object.

Parameters
  • list: The list to free.

Change an instruction’s full immediate to point somewhere.

NOTE: If you don’t like the fact that you can’t run 32-bit Decision code on 64-bit machines and vice versa, blame it on this function.

Parameters
  • ins: A pointer to first byte of the instruction.

  • ptr: The memory address for the instruction to load.

Precalculate the pointers to external variables and functions for linking.

Parameters
  • sheet: The sheet to precalculate the pointers for.

Link a sheet’s properties from itself to itself and included sheets.

Parameters
  • sheet: The sheet to link.

Recursively go through the tree of included sheets and link them all with d_link_self.

Parameters
  • sheet: The sheet to recurse from.

If the sheet includes objects, but doesn’t know where they live, i.e. linkMeta.meta == -1 && linkMeta._ptr == -1, then find them and reference them in the sheet.

Parameters
  • sheet: The sheet to find the locations of includes.

Call d_link_find_included, d_link_precalculate_ptr, d_link_self, and d_link_includes_recursive on a sheet.

Parameters
  • sheet: The sheet to link.

file dmalloc.h
#include “dcfg.h”#include <stddef.h>

This header contains wrapper functions for system functions to do with memory allocation.

Functions

void *d_malloc(size_t size)

A wrapper function for malloc with error checking.

Return

A pointer to the allocated memory.

Parameters
  • size: The size of the allocation.

void *d_realloc(void *ptr, size_t size)

A wrapper function for realloc with error checking.

Return

A pointer to the reallocated memory.

Parameters
  • ptr: The memory allocation to reallocate.

  • size: The size of the new allocation.

void *d_calloc(size_t num, size_t size)

A wrapper function for calloc with error checking.

Return

A pointer to the allocated memory.

Parameters
  • num: The number of elements to allocate.

  • size: The size of each element.

file dname.h
#include “dcfg.h”#include “dcore.h”#include <stdbool.h>#include <stddef.h>

This header contains functions to handle the names of things in Decision, like the names of variables, functions, etc.

Typedefs

typedef enum _nameType NameType
typedef struct _nameDefinition NameDefinition
typedef struct _allNameDefinitions AllNameDefinitions

Enums

enum _nameType

An enum for saying what a name corresponds to.

Values:

NAME_CORE
NAME_VARIABLE
NAME_FUNCTION
NAME_CFUNCTION

Functions

AllNameDefinitions d_get_name_definitions(struct _sheet *sheet, const char *name)

Get all of the places where a name is defined, and what the name’s type is.

We will also check recursively up the includes of sheets.

Return

An array of NameDefinition.

Parameters
  • sheet: The sheet to start looking from.

  • name: The name to query.

void d_free_name_definitions(AllNameDefinitions *definitions)

Free an AllNameDefinitions struct. It should not be used after it has been freed.

Parameters
  • definitions: The structure to free.

const NodeDefinition *d_get_definition(struct _sheet *sheet, const char *name, size_t lineNum, const char *funcName, NameDefinition *nameDef)

Get a node’s definition from it’s name.

Return

The node’s definition.

Parameters
  • sheet: The sheet the node is a part of.

  • name: The name of the node.

  • lineNum: In case we error, say where we errored from.

  • funcName: If the name is Define or Return, we need the function name so we can get the correct sockets.

  • nameDef: A pointer that is set to the node’s name definition. If the node definition returns NULL, do not trust this value.

file dobj.h
#include “dcfg.h”#include <stddef.h>

This header deals with Decision object files, i.e. compiled files.

Functions

const char *d_obj_generate(struct _sheet *sheet, size_t *size)

Given a sheet has been compiled, create the contents of the sheet’s object file.

This function is essentially the reverse of d_obj_load.

NOTE: You cannot compile the sheet if it has any C functions defined in it!

Return

A malloc’d string of the contents of the future object file.

Parameters
  • sheet: The sheet to use to create the object.

  • size: A pointer to a size that is overwritten with the size of the generated string.

Sheet *d_obj_load(const char *obj, size_t size, const char *filePath, struct _sheet **includes, struct _sheet **priors)

Given a binary object string, create a malloc’d Sheet structure from it.

This function is essentially the reverse of d_obj_generate.

Return

The malloc’d sheet generated from the object string.

Parameters
  • obj: The object string.

  • size: The size of the object string.

  • filePath: Where the object file the object string came from is located.

  • includes: A NULL-terminated list of initially included sheets. Can be NULL.

  • priors: A NULL-terminates list of sheets that, if included, will throw an error. Can be NULL.

file doptimize.h
#include “dcfg.h”#include <stdbool.h>#include <stddef.h>

This header deals with optimising generated bytecode from dcodegen.h by checking for specific senarios and helps to reduce the number of instructions.

Functions

void d_optimize_remove_ins_to_link(struct _sheet *sheet, size_t index)

Remove one instruction-to-link record from a sheet.

Parameters
  • sheet: The sheet to remove the record from.

  • index: The index of the record to remove.

void d_optimize_remove_bytecode(struct _sheet *sheet, size_t start, size_t len)

Remove a section of bytecode, and make any adjustments to the data that is nessesary.

Parameters
  • sheet: The sheet containing the bytecode to remove from.

  • start: The starting index of the bytecode to remove.

  • len: How many bytes to remove, starting from start.

void d_optimize_all(struct _sheet *sheet)

Try and optimise all possible senarios.

Parameters
  • sheet: The sheet containing the bytecode to optimise.

bool d_optimize_not_consecutive(struct _sheet *sheet)

Try and find consecutive NOT instructions.

Return

If we were able to optimise.

Parameters
  • sheet: The sheet containing the bytecode to optimize.

bool d_optimize_push_pop_consecutive(struct _sheet *sheet)

Try and find POP instructions immediately following PUSH instructions.

Return

If we were able to optimise.

Parameters
  • sheet: The sheet containing the bytecode to optimise.

d_optimize_useless(struct _sheet *sheet)

Try and find useless instructions in the bytecode, e.g. poping 0 items.

Return

If we were able to optimise.

Parameters
  • sheet: The sheet containing the bytecode to optimise.

bool d_optimize_call_func_relative(struct _sheet *sheet)

Try and find instructions that link to functions that are defined in the same sheet, and if possible, just replace with a relative call rather than an absolute one.

Return

If we were able to optimise.

Parameters
  • sheet: The sheet containing the bytecode to optimize.

bool d_optimize_simplify(struct _sheet *sheet)

Try and find instructions that can be simplified, i.e. POPB 1 = POP.

Return

If we were able to optimise.

Parameters
  • sheet: The sheet containing the bytecode to optimise.

bool d_optimize_shrink_fimmediate(struct _sheet *sheet)

For instructions that have full immediate operands, try and replace them with equivalent instructions that use immediates that are smaller, i.e. half and byte immediates.

Return

If we were able to optimise.

Parameters
  • sheet: The sheet containing the bytecode to optimise.

file dsemantic.h
#include “dcfg.h”#include “dcfunc.h”#include “dcore.h”#include “dlex.h”#include “dsheet.h”#include “dsyntax.h”#include “dtype.h”#include <stdbool.h>#include <stddef.h>

This header checks that the program we’re about to compile is correct.

Functions

void d_semantic_scan_properties(Sheet *sheet, SyntaxNode *root, Sheet **priors, bool debugIncluded)

Sets the properties of the sheet, given the syntax tree.

Parameters
  • sheet: A pointer to the sheet where we want to set the properties.

  • root: The root node of the syntax tree.

  • priors: A NULL-terminated list of sheets that, if included, will produce an error.

  • debugIncluded: If true, compile included sheets in debug mode.

void d_semantic_scan_nodes(Sheet *sheet, SyntaxNode *root)

Sets the nodes of the sheet, given the syntax tree.

NOTE: This function also sets the connections between the nodes.

Parameters
  • sheet: A pointer to the sheet where we want to set the properties.

  • root: The root node of the syntax tree.

void d_semantic_reduce_types(Sheet *sheet)

Take the connections of a sheet which may have “vague” connections, and reduce them to unique types with the information we have.

e.g. If Multiply has at least one Float input, the output must be a Float.

Parameters
  • sheet: The sheet to reduce the types on.

void d_semantic_detect_loops(Sheet *sheet)

After a sheet has been connected in d_semantic_scan_nodes, go through the sheet and see if there are any loops.

“Loops are bad, and should be given coal at christmas.”

In retrospect, this was a bad quote. Instead, give it something that won’t cause climate change, like a really cheap sticker.

While we are here, we also check to see if there are any redundant nodes.

Parameters
  • sheet: The connected sheet to check for loops.

void d_semantic_check_subroutine_returns(Sheet *sheet)

After a sheet has been checked for loops with d_semantic_detect_loops, check to see if all execution paths from the Define of a subroutine end with a Return.

Parameters
  • sheet: The sheet to check.

void d_semantic_scan(Sheet *sheet, SyntaxNode *root, Sheet **priors, bool debugIncluded)

Perform Semantic Analysis on a syntax tree.

Parameters
  • sheet: The sheet to put everything into.

  • root: The valid syntax tree to scan everything from.

  • priors: A NULL-terminated list of sheets that, if included, will produce an error. This is to prevent circular includes.

  • debugIncluded: If true, compile any included sheets in debug mode.

file dsheet.h
#include “dcfg.h”#include “dcfunc.h”#include “ddebug.h”#include “dgraph.h”#include “dlink.h”#include <stdbool.h>#include <stddef.h>

This header contains definitions for Sheets in Decision.

Typedefs

typedef struct _sheetVariable SheetVariable
typedef struct _sheetFunction SheetFunction
typedef struct _sheet Sheet

Functions

void d_sheet_add_variable(Sheet *sheet, const SocketMeta varMeta)

Add a variable property to the sheet.

Parameters
  • sheet: The sheet to add the variable onto.

  • varMeta: The variable metadata to add.

void d_sheet_add_function(Sheet *sheet, const NodeDefinition funcDef)

Add a function to a sheet.

Parameters
  • sheet: The sheet to add the function to.

  • funcDef: The function definition to add.

void d_sheet_add_c_function(Sheet *sheet, CFunction cFunction)

Add a C function to a sheet.

NOTE: To create a C function, have a look at dcfunc.h.

Parameters
  • sheet: The sheet to add the C function to.

  • cFunction: The C function to add.

bool d_is_subroutine(SheetFunction func)

Is the given function a subroutine?

Return

If the function is a subroutine.

Parameters
  • func: The function to query.

void d_sheet_add_include(Sheet *sheet, Sheet *include)

Add a reference to another sheet to the current sheet, which can be used to get extra functionality.

Parameters
  • sheet: The sheet to add the include to.

  • include: The sheet to include.

Sheet *d_sheet_add_include_from_path(Sheet *sheet, const char *includePath, Sheet **priors, bool debugInclude)

Add a reference to another sheet to the current sheet, which can be used to get extra functionality.

Return

A pointer to the sheet that was created from the include path.

Parameters
  • sheet: The sheet to add the include to.

  • includePath: The path from sheet to the sheet being included. Note that this should be equivalent to the argument of the Include property.

  • priors: A NULL-terminated list of sheets that, if included, will throw an error. This is to prevent circular includes.

  • debugInclude: If we can compile the included sheet in debug mode, do so if set to true.

Sheet *d_sheet_create(const char *filePath)

Create a malloc’d sheet object.

Return

The malloc’d sheet object.

Parameters
  • filePath: The file where this sheet originated.

void d_sheet_free(Sheet *sheet)

Free malloc’d memory in a sheet.

NOTE: This will also free all included sheets recursively that have the allowFree property set to true, which is the default!

Parameters
  • sheet: The sheet to free from memory.

void d_variables_dump(SheetVariable *variables, size_t numVariables)

Dump the details of an array of variables to stdout.

Parameters
  • variables: The array of variables.

  • numVariables: The number of variables in the array.

void d_functions_dump(SheetFunction *functions, size_t numFunctions)

Dump the details of an array of functions to stdout.

Parameters
  • functions: The array of functions.

  • numFunctions: The number of functions in the array.

void d_c_functions_dump(CFunction *functions, size_t numFunctions)

Dump the details of an array of C functions to stdout.

Parameters
  • functions: The array of C functions.

  • numFunctions: The number of functions in the array.

void d_sheet_dump(Sheet *sheet)

Dump the contents of a Sheet struct to stdout.

Parameters
  • sheet: The sheet to dump.

file dsyntax.h
#include “dcfg.h”#include <stdbool.h>#include <stddef.h>

This header deals with checking the syntax of the program, and generating a syntax tree from lexical tokens.

Typedefs

typedef enum _syntaxDefinition SyntaxDefinition
typedef struct _syntaxNode SyntaxNode
typedef struct _syntaxResult SyntaxResult
typedef struct _syntaxSearchResult SyntaxSearchResult

Enums

enum _syntaxDefinition

An enum for each kind of syntax definition.

Values:

STX_TOKEN

A single element related to a lexical token.

STX_lineIdentifier
STX_listOfLineIdentifier
STX_dataType
STX_literal
STX_argument
STX_propertyArgument
STX_listOfArguments
STX_listOfPropertyArguments
STX_statement
STX_propertyStatement
STX_program

Functions

SyntaxNode *d_syntax_create_node(SyntaxDefinition d, struct _lexToken *info, size_t line)

Create a malloc’d syntax node with default nulled family pointers.

Return

A pointer to a malloc’d SyntaxNode.

Parameters
  • d: What definition does this syntax node have?

  • info: The corresponding lexical token, if any.

  • line: The line number this syntax definition appears in.

SyntaxNode *d_syntax_last_sibling(SyntaxNode *node)

Get the pointer to the last of a chain of children with the same common parent.

Return

The last sibling.

Parameters
  • node: The node to find the last sibling of.

void d_syntax_add_child(SyntaxNode *parent, SyntaxNode *child)

Add a child node to a parent node.

Parameters
  • parent: The parent node to attach the child onto.

  • child: The child node to add onto the parent.

size_t d_syntax_get_num_children(SyntaxNode *parent)

Get how many children a node has.

Return

The number of children parent has.

Parameters
  • parent: The node to query.

SyntaxNode *d_syntax_get_child_by_index(SyntaxNode *parent, size_t index)

Get a node’s child from it’s index.

Return

The indexth child of the parent. NULL if the index is out of range.

Parameters
  • parent: The parent node to get the child from.

  • index: The index of the child we want.

SyntaxNode *d_syntax_get_child_by_definition(SyntaxNode *parent, SyntaxDefinition definition)

Find the first occurance of a child with a specific definition.

Return

The first child of parent with the given definition. NULL if there is none.

Parameters
  • parent: The parent to get the child from.

  • definition: The definition we want from the child.

SyntaxSearchResult d_syntax_get_all_nodes_with(SyntaxNode *root, SyntaxDefinition definition, bool traverseChildrenOfFound)

Return all occurances of a tree with a given definition as a malloc’d SyntaxSearchResult.

Return

A malloc’d SyntaxSearchResult.

Parameters
  • root: The root node to search from.

  • definition: The definition we want our found nodes to have.

  • traverseChildrenOfFound: If we find a node that we want, should we also traverse the children of that found node?

void d_syntax_dump_tree_raw(SyntaxNode *root, int n)

Dump the contents of a tree recursively.

Parameters
  • root: The root node to start from.

  • n: The “level” of the recursion, so we can print the tree with proper indentation.

void d_syntax_dump_tree(SyntaxNode *root)

Dump the contents of a tree recursively.

Parameters
  • root: The root node to start from.

void d_syntax_free_tree(SyntaxNode *root)

Free all the nodes from a syntax tree.

Parameters
  • root: The root node of the tree.

void d_syntax_free_results(SyntaxSearchResult results)

Free search results from memory.

Parameters
  • results: The results to free.

SyntaxResult d_syntax_parse(struct _lexStream stream, const char *filePath)

Parse a lexical stream, and generate a syntax tree.

Return

The malloc’d root node of the syntax tree, and whether the parsing was successful or not.

Parameters
  • stream: The stream to parse from.

  • filePath: In case we error, say what the file path was.

file dtype.h
#include “dcfg.h”#include “dlex.h”#include <stdbool.h>

This header deals with discrete data types in Decision.

Defines

TYPE_VAR_MIN

The least-valued data type that is a variable type.

TYPE_VAR_MAX

The highest-valued data type that is a variable type.

TYPE_NUMBER

A vague type representing all numbers.

TYPE_BITWISE

A vague type representing bitwise types.

TYPE_COMPARABLE

A vague type representing types that can be compared, i.e. one value can be “more” than another.

TYPE_VAR_ANY

A vague type representing all variable types.

TYPE_FROM_LEX(x)

A macro to convert from lexical token types (LexType) to DType.

TYPE_FROM_LEX_LITERAL(x)

A macro to convert from lexical token literals to DType.

Typedefs

typedef enum _dType DType

Enums

enum _dType

An enum for the data types in Decision.

The values go up in powers of 2. This is so that we can combine data types to make vague data types, e.g. a number is TYPE_INTEGER | TYPE_FLOAT.

Note that there are several macros for common vague data types, e.g. TYPE_NUMBER, TYPE_BITWISE, TYPE_VAR_ANY, …

Values:

TYPE_NONE = 0
TYPE_EXECUTION = 1
TYPE_INT = 2
TYPE_FLOAT = 4
TYPE_STRING = 8
TYPE_BOOL = 16
TYPE_NAME = 32

Functions

bool d_type_is_vague(DType vague)

Given a possible vague data type, return if it is actually vague.

NOTE: Vague means more than one variable data type, e.g. Integer | Float

Return

If the data type is vague.

Parameters
  • vague: The possible vague data type.

const char *d_type_name(DType type)

Get a string representation for the name of a data type.

Return

The string representation of the data type.

Parameters
  • type: The type to get the name of.

file dvm.h
#include “dcfg.h”#include “derror.h”#include <stdbool.h>#include <stdint.h>

This header contains functionality for the Decision VM - the object that will run the generated bytecode.

Defines

NUM_OPCODES

Macro constant representing the number of opcodes.

VM_STACK_SIZE_MIN

The minimum, and starting, size of the VM’s stack.

VM_STACK_SIZE_SCALE_INC

How much should the stack size increase once it reaches capacity?

VM_STACK_SIZE_SCALE_DEC

How much should the stack size decrease to save memory?

BIMMEDIATE_SIZE
bimmediate_t
BIMMEDIATE_MIN
BIMMEDIATE_MAX
BIMMEDIATE_PRINTF
HIMMEDIATE_SIZE
himmediate_t
HIMMEDIATE_MIN
HIMMEDIATE_MAX
FIMMEDIATE_SIZE
fimmediate_t
FIMMEDIATE_MIN
FIMMEDIATE_MAX
HIMMEDIATE_PRINTF
FIMMEDIATE_PRINTF
ERROR_RUNTIME(vm, ...)

A macro function to be able to print formatted error messages.

This is to d_vm_runtime_error what ERROR_COMPILER is to d_error_compiler_push.

Typedefs

typedef enum _dIns DIns
typedef enum _dSyscall DSyscall
typedef struct _DVM DVM

Enums

enum _dIns

The Decision VM Instruction Set.

Values:

OP_RET = 0

Equivalent to RETN 0.

OP_RETN = 1

pop(stackFrame w/ I(1) return values)

OP_ADD = 2

push(pop() + pop())

OP_ADDF = 3

pushFloat(popFloat() + popFloat())

OP_ADDBI = 4

push(pop() + I(1))

OP_ADDHI = 5

push(pop() + I(|M|/2))

OP_ADDFI = 6

push(pop() + I(|M|))

OP_AND = 7

push(pop() & pop())

OP_ANDBI = 8

push(pop() & I(1))

OP_ANDHI = 9

push(pop() & I(|M|/2))

OP_ANDFI = 10

push(pop() & I(|M|))

OP_CALL = 11

pc = pop(); push(stackFrame w/ I(1) arguments)

OP_CALLC = 12

(*pop())(this) w/ I(1) arguments

OP_CALLCI = 13

(*I(|M|))(this) w/ I(1) arguments

OP_CALLI = 14

pc = I(|M|); push(stackFrame w/ I(1) arguments)

OP_CALLR = 15

pc += pop(); push(stackFrame w/ I(1) arguments)

OP_CALLRB = 16

pc += I(1); push(stackFrame w/ I(1) arguments)

OP_CALLRH = 17

pc += I(|M|/2); push(stackFrame w/ I(1) arguments)

OP_CALLRF = 18

pc += I(|M|); push(stackFrame w/ I(1) arguments)

OP_CEQ = 19

push(pop() == pop())

OP_CEQF = 20

push(popFloat() == popFloat())

OP_CLEQ = 21

push(pop() <= pop())

OP_CLEQF = 22

push(popFloat() <= popFloat())

OP_CLT = 23

push(pop() < pop())

OP_CLTF = 24

push(popFloat() < popFloat())

OP_CMEQ = 25

push(pop() >= pop())

OP_CMEQF = 26

push(popFloat() >= popFloat())

OP_CMT = 27

push(pop() > pop())

OP_CMTF = 28

push(popFloat() > popFloat())

OP_CVTF = 29

push((dfloat)pop())

OP_CVTI = 30

push((dint)pop())

OP_DEREF = 31

push(*pop())

OP_DEREFI = 32

push(*I(|M|))

OP_DEREFB = 33

push(*((uint8_t *)pop()))

OP_DEREFBI = 34

push(*((uint8_t *)I(|M|)))

OP_DIV = 35

push(pop() / pop())

OP_DIVF = 36

pushFloat(popFloat() / popFloat())

OP_DIVBI = 37

push(pop() / I(1))

OP_DIVHI = 38

push(pop() / I(|M|/2))

OP_DIVFI = 39

push(pop() / I(|M|))

OP_GET = 40

push(get(pop()))

OP_GETBI = 41

push(get(I(1)))

OP_GETHI = 42

push(get(I(|M|/2)))

OP_GETFI = 43

push(get(I(|M|)))

OP_INV = 44

push(~pop())

OP_J = 45

pc = pop()

OP_JCON = 46

IF pop() THEN pc = pop() ELSE pop()

OP_JCONI = 47

IF pop() THEN pc = I(|M|)

OP_JI = 48

pc = I(|M|)

OP_JR = 49

pc += pop()

OP_JRBI = 50

pc += I(1)

OP_JRHI = 51

pc += I(|M|/2)

OP_JRFI = 52

pc += I(|M|)

OP_JRCON = 53

IF pop() THEN pc += pop() ELSE pop()

OP_JRCONBI = 54

IF pop() THEN pc += I(1)

OP_JRCONHI = 55

IF pop() THEN pc += I(|M|/2)

OP_JRCONFI = 56

IF pop() THEN pc += I(|M|)

OP_MOD = 57

push(pop() % pop())

OP_MODBI = 58

push(pop() % I(1))

OP_MODHI = 59

push(pop() % I(|M|/2))

OP_MODFI = 60

push(pop() % I(|M|))

OP_MUL = 61

push(pop() * pop())

OP_MULF = 62

pushFloat(popFloat() * popFloat())

OP_MULBI = 63

push(pop() * I(1))

OP_MULHI = 64

push(pop() * I(|M|/2))

OP_MULFI = 65

push(pop() * I(|M|))

OP_NOT = 66

push(!pop())

OP_OR = 67

push(pop() | pop())

OP_ORBI = 68

push(pop() | I(1))

OP_ORHI = 69

push(pop() | I(|M|/2))

OP_ORFI = 70

push(pop() | I(|M|))

OP_POP = 71

pop() once

OP_POPB = 72

pop() I(1) times

OP_POPH = 73

pop() I(|M|/2) times

OP_POPF = 74

pop() I(|M|) times

OP_PUSHB = 75

push(I(1))

OP_PUSHH = 76

push(I(|M|/2))

OP_PUSHF = 77

push(I(|M|))

OP_PUSHNB = 78

push(0) I(1) times

OP_PUSHNH = 79

push(0) I(|M|/2) times

OP_PUSHNF = 80

push(0) I(|M|) times

OP_SETADR = 81

*((dint *)pop()) = pop()

OP_SETADRB = 82

*((uint8_t *)pop()) = pop()

OP_SUB = 83

push(pop() - pop())

OP_SUBF = 84

pushFloat(popFloat() - popFloat())

OP_SUBBI = 85

push(pop() - I(1))

OP_SUBHI = 86

push(pop() - I(|M|/2))

OP_SUBFI = 87

push(pop() - I(|M|))

OP_SYSCALL = 88

push(syscall(I(1), pop(), pop(), pop()))

OP_XOR = 89

push(pop() ^ pop())

OP_XORBI = 90

push(pop() ^ I(1))

OP_XORHI = 91

push(pop() ^ I(|M|/2))

OP_XORFI = 92

push(pop() ^ I(|M|))

enum _dSyscall

The Decision VM Syscall specification.

Values:

SYS_PRINT = 0

Print a value to stdout.

  • arg0: 0: Integer, 1: Float, 2: String, 3: Boolean.

  • arg1: If set to 1, it will print a newline at the end, otherwise it will not.

  • arg2: The value to print.

  • Returns: The value 0.

SYS_STRCMP = 1

Compare two strings.

  • arg0: 0: Equal, 1: Less Than or Equal, 2: Less Than, 3: More Than or Equal, 4: More Than.

  • arg1: The first string pointer.

  • arg2: The second string pointer.

  • Returns: 1 if true, 0 if false.

SYS_STRLEN = 2

Get the length of a string.

  • arg0: Unused.

  • arg1: Unused.

  • arg2: The string to get the length of.

  • Returns: The length of the string.

Functions

size_t d_vm_frame(DVM *vm)

Get the number of elements in the current stack frame.

Return

The number of elements in the stack frame.

Parameters
  • vm: The VM whose stack to query.

dint d_vm_get(DVM *vm, dint index)

Get an integer from a value in the stack at a particular index.

  • If index is positive, it will index relative to the start of the stack frame.

  • If index is non-positive, it will index relative to the top of the stack.

Return

The integer value of the stack at the given index.

Parameters
  • vm: The VM whose stack to retrieve from.

  • index: The index of the stack.

dfloat d_vm_get_float(DVM *vm, dint index)

Get a float from a value in the stack at a particular index.

  • If index is positive, it will index relative to the start of the stack frame.

  • If index is non-positive, it will index relative to the top of the stack.

Return

The float value of the stack at the given index.

Parameters
  • vm: The VM whose stack to retrieve from.

  • index: The index of the stack.

void *d_vm_get_ptr(DVM *vm, dint index)

Get a pointer from a value in the stack at a particular index.

  • If index is positive, it will index relative to the start of the stack frame.

  • If index is non-positive, it will index relative to the top of the stack.

Return

The pointer value of the stack at the given index.

Parameters
  • vm: The VM whose stack to retrieve from.

  • index: The index of the stack.

void d_vm_insert(DVM *vm, dint index, dint value)

Insert an integer into the stack at a particular index.

  • If index is positive, it will index relative to the start of the stack frame.

  • If index is non-positive, it will index relative to the top of the stack.

Parameters
  • vm: The VM whose stack to insert to.

  • index: The index of the stack to insert to, i.e. value will be at this location when the function returns.

  • value: The value to insert into the stack.

void d_vm_insert_float(DVM *vm, dint index, dfloat value)

Insert a float into the stack at a particular index.

  • If index is positive, it will index relative to the start of the stack frame.

  • If index is non-positive, it will index relative to the top of the stack.

Parameters
  • vm: The VM whose stack to insert to.

  • index: The index of the stack to insert to, i.e. value will be at this location when the function returns.

  • value: The value to insert into the stack.

void d_vm_insert_ptr(DVM *vm, dint index, void *ptr)

Insert a pointer into the stack at a particular index.

  • If index is positive, it will index relative to the start of the stack frame.

  • If index is non-positive, it will index relative to the top of the stack.

Parameters
  • vm: The VM whose stack to insert to.

  • index: The index of the stack to insert to, i.e. ptr will be at this location when the function returns.

  • ptr: The pointer to insert into the stack.

dint d_vm_pop(DVM *vm)

Pop an integer from the top of the stack.

Return

The integer at the top of the stack.

Parameters
  • vm: The VM whose stack to pop from.

void d_vm_popn(DVM *vm, size_t n)

Pop n elements from the stack.

Parameters
  • vm: The VM whose stack to pop from.

  • n: The number of elements to pop.

dfloat d_vm_pop_float(DVM *vm)

Pop a float from the top of the stack.

Return

The float at the top of the stack.

Parameters
  • vm: The VM whose stack to pop from.

void *d_vm_pop_ptr(DVM *vm)

Pop a pointer from the top of the stack.

Return

The pointer at the top of the stack.

Parameters
  • vm: The VM whose stack to pop from.

void d_vm_push(DVM *vm, dint value)

Push an integer value onto the stack.

Parameters
  • vm: The VM whose stack to push onto.

  • value: The value to push onto the stack.

void d_vm_pushn(DVM *vm, size_t n)

Push 0 onto the stack n times.

Parameters
  • vm: The VM whose stack to push onto.

  • n: The number of items to push onto the stack.

void d_vm_push_float(DVM *vm, dfloat value)

Push a float value onto the stack.

Parameters
  • vm: The VM whose stack to push onto.

  • value: The value to push onto the stack.

void d_vm_push_ptr(DVM *vm, void *ptr)

Push a pointer onto the stack.

Parameters
  • vm: The VM whose stack to push onto.

  • ptr: The pointer to push onto the stack.

void d_vm_remove(DVM *vm, dint index)

Remove the value from the stack at a particular index.

  • If index is positive, it will index relative to the start of the stack frame.

  • If index is non-positive, it will index relative to the top of the stack.

Parameters
  • vm: The VM whose stack to remove from.

  • index: The index to remove from the stack.

void d_vm_remove_len(DVM *vm, dint index, size_t len)

Remove a number of values from the stack, starting at a particular index.

  • If index is positive, it will index relative to the start of the stack frame.

  • If index is non-positive, it will index relative to the top of the stack.

Parameters
  • vm: The VM whose stack to remove from.

  • index: The index to start removing from the stack.

  • len: The number of items to remove from the stack.

void d_vm_set(DVM *vm, dint index, dint value)

Set the value of an element in the stack at a particular index.

  • If index is positive, it will index relative to the start of the stack frame.

  • If index is non-positive, it will index relative to the top of the stack.

Parameters
  • vm: The VM whose stack to set the element of.

  • index: The index of the stack.

  • value: The value to set.

void d_vm_set_float(DVM *vm, dint index, dfloat value)

Set the value of an element in the stack at a particular index.

  • If index is positive, it will index relative to the start of the stack frame.

  • If index is non-positive, it will index relative to the top of the stack.

Parameters
  • vm: The VM whose stack to set the element of.

  • index: The index of the stack.

  • value: The value to set.

void d_vm_set_ptr(DVM *vm, dint index, void *ptr)

Set the value of an element in the stack at a particular index.

  • If index is positive, it will index relative to the start of the stack frame.

  • If index is non-positive, it will index relative to the top of the stack.

Parameters
  • vm: The VM whose stack to set the element of.

  • index: The index of the stack.

  • ptr: The value to set.

size_t d_vm_top(DVM *vm)

Get the number of elements in the stack.

Return

The number of elements in the stack.

Parameters
  • vm: The VM whose stack to query.

unsigned char d_vm_ins_size(DIns opcode)

Given an opcode, get the total size of the instruction involving that opcode in bytes.

Return

The size of the instruction in bytes. 0 if the opcode doesn’t exist.

Parameters
  • opcode: The opcode to query.

DVM d_vm_create()

Create a Decision VM in its starting state, with malloc’d elements.

Return

A Decision VM in its starting state.

void d_vm_reset(DVM *vm)

Reset a Decision VM to its starting state.

Parameters
  • vm: A Decision VM to set to its starting state.

void d_vm_free(DVM *vm)

Free the malloc’d elements of a Decision VM. Note that this makes the VM unusable unless you call d_vm_reset on it.

Parameters
  • vm: The Decision VM to free.

void d_vm_runtime_error(DVM *vm, const char *error)

Print a runtime error to stdout, and halt the VM.

Unlike compiler errors, these errors aren’t stored anywhere.

Parameters
  • vm: The VM that came across the error.

  • error: The error message to display.

void d_vm_parse_ins_at_pc(DVM *vm)

Given a Decision VM, at it’s current position in the program, parse the instruction at that position.

Parameters
  • vm: The VM to use to parse the instruction.

void d_vm_add_pc(DVM *vm, dint rel)

Add to the program counter to go +rel bytes.

NOTE: The VM will ALWAYS increment the PC after any instruction that isn’t a jump, call or return.

Parameters
  • vm: The VM whose PC to add to.

  • rel: How many bytes to go forward. Can be negative.

void d_vm_inc_pc(DVM *vm)

Increment the program counter in a Decision VM, to go to the next instruction.

NOTE: The VM will ALWAYS increment the PC after any instruction that isn’t a jump, call or return.

Parameters
  • vm: The VM whose PC to add to.

bool d_vm_run(DVM *vm, void *start)

Get a virtual machine to start running instructions in a loop, until it is halted.

Return

If it ran without any runtime errors.

Parameters
  • vm: The VM to run the bytecode in.

  • start: A pointer to the start of the bytecode to execute.

void d_vm_dump(DVM *vm)

Dump the contents of a Decision VM to stdout for debugging.

Parameters
  • vm: The VM to dump the contents of.

dir src