mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Packaged toy as a dll
This commit is contained in:
6
makefile
6
makefile
@@ -3,6 +3,12 @@ export OUTDIR = out
|
|||||||
all: $(OUTDIR)
|
all: $(OUTDIR)
|
||||||
$(MAKE) -C source
|
$(MAKE) -C source
|
||||||
|
|
||||||
|
library: clean $(OUTDIR)
|
||||||
|
$(MAKE) -C source library
|
||||||
|
|
||||||
|
static: clean $(OUTDIR)
|
||||||
|
$(MAKE) -C source static
|
||||||
|
|
||||||
test: clean $(OUTDIR)
|
test: clean $(OUTDIR)
|
||||||
$(MAKE) -C test
|
$(MAKE) -C test
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,20 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
//test variable sizes based on platform
|
||||||
|
#define STATIC_ASSERT(test_for_true) static_assert((test_for_true), "(" #test_for_true ") failed")
|
||||||
|
|
||||||
|
STATIC_ASSERT(sizeof(char) == 1);
|
||||||
|
STATIC_ASSERT(sizeof(short) == 2);
|
||||||
|
STATIC_ASSERT(sizeof(int) == 4);
|
||||||
|
STATIC_ASSERT(sizeof(float) == 4);
|
||||||
|
STATIC_ASSERT(sizeof(unsigned char) == 1);
|
||||||
|
STATIC_ASSERT(sizeof(unsigned short) == 2);
|
||||||
|
STATIC_ASSERT(sizeof(unsigned int) == 4);
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
|
|
||||||
//declare the singleton
|
//declare the singleton
|
||||||
Command command;
|
Command command;
|
||||||
@@ -106,4 +120,6 @@ void copyrightCommand(int argc, const char* argv[]) {
|
|||||||
printf("1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n\n");
|
printf("1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n\n");
|
||||||
printf("2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n\n");
|
printf("2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n\n");
|
||||||
printf("3. This notice may not be removed or altered from any source distribution.\n\n");
|
printf("3. This notice may not be removed or altered from any source distribution.\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -9,6 +9,26 @@
|
|||||||
#define TOY_VERSION_PATCH 0
|
#define TOY_VERSION_PATCH 0
|
||||||
#define TOY_VERSION_BUILD __DATE__ " " __TIME__
|
#define TOY_VERSION_BUILD __DATE__ " " __TIME__
|
||||||
|
|
||||||
|
//platform exports/imports
|
||||||
|
#if defined(WIN32) || defined(_WIN32)
|
||||||
|
|
||||||
|
#if defined(TOY_EXPORT)
|
||||||
|
#define TOY_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define TOY_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(linux)
|
||||||
|
|
||||||
|
#define TOY_API extern
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define TOY_API
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
//for processing the command line arguments
|
//for processing the command line arguments
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool error;
|
bool error;
|
||||||
@@ -29,6 +49,7 @@ void initCommand(int argc, const char* argv[]);
|
|||||||
void usageCommand(int argc, const char* argv[]);
|
void usageCommand(int argc, const char* argv[]);
|
||||||
void helpCommand(int argc, const char* argv[]);
|
void helpCommand(int argc, const char* argv[]);
|
||||||
void copyrightCommand(int argc, const char* argv[]);
|
void copyrightCommand(int argc, const char* argv[]);
|
||||||
|
#endif
|
||||||
|
|
||||||
//NOTE: assigning to a byte from a short loses data
|
//NOTE: assigning to a byte from a short loses data
|
||||||
#define AS_USHORT(value) (*(unsigned short*)(&(value)))
|
#define AS_USHORT(value) (*(unsigned short*)(&(value)))
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "opcodes.h"
|
#include "opcodes.h"
|
||||||
|
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "literal_array.h"
|
#include "literal_array.h"
|
||||||
|
|
||||||
@@ -13,9 +13,9 @@ typedef struct Compiler {
|
|||||||
int count;
|
int count;
|
||||||
} Compiler;
|
} Compiler;
|
||||||
|
|
||||||
void initCompiler(Compiler* compiler);
|
TOY_API void initCompiler(Compiler* compiler);
|
||||||
void writeCompiler(Compiler* compiler, Node* node);
|
TOY_API void writeCompiler(Compiler* compiler, Node* node);
|
||||||
void freeCompiler(Compiler* compiler);
|
TOY_API void freeCompiler(Compiler* compiler);
|
||||||
|
|
||||||
//embed the header with version information, data section, code section, etc.
|
//embed the header, data section, code section, function section, etc.
|
||||||
unsigned char* collateCompiler(Compiler* compiler, int* size);
|
TOY_API unsigned char* collateCompiler(Compiler* compiler, int* size);
|
||||||
|
|||||||
@@ -2032,9 +2032,11 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
//data section
|
//data section
|
||||||
const unsigned short literalCount = readShort(interpreter->bytecode, &interpreter->count);
|
const unsigned short literalCount = readShort(interpreter->bytecode, &interpreter->count);
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf(NOTICE "Reading %d literals\n" RESET, literalCount);
|
printf(NOTICE "Reading %d literals\n" RESET, literalCount);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < literalCount; i++) {
|
for (int i = 0; i < literalCount; i++) {
|
||||||
const unsigned char literalType = readByte(interpreter->bytecode, &interpreter->count);
|
const unsigned char literalType = readByte(interpreter->bytecode, &interpreter->count);
|
||||||
@@ -2044,9 +2046,11 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
//read the null
|
//read the null
|
||||||
pushLiteralArray(&interpreter->literalCache, TO_NULL_LITERAL);
|
pushLiteralArray(&interpreter->literalCache, TO_NULL_LITERAL);
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(null)\n");
|
printf("(null)\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LITERAL_BOOLEAN: {
|
case LITERAL_BOOLEAN: {
|
||||||
@@ -2056,9 +2060,11 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
pushLiteralArray(&interpreter->literalCache, literal);
|
pushLiteralArray(&interpreter->literalCache, literal);
|
||||||
freeLiteral(literal);
|
freeLiteral(literal);
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(boolean %s)\n", b ? "true" : "false");
|
printf("(boolean %s)\n", b ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2068,9 +2074,11 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
pushLiteralArray(&interpreter->literalCache, literal);
|
pushLiteralArray(&interpreter->literalCache, literal);
|
||||||
freeLiteral(literal);
|
freeLiteral(literal);
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(integer %d)\n", d);
|
printf("(integer %d)\n", d);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2080,9 +2088,11 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
pushLiteralArray(&interpreter->literalCache, literal);
|
pushLiteralArray(&interpreter->literalCache, literal);
|
||||||
freeLiteral(literal);
|
freeLiteral(literal);
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(float %f)\n", f);
|
printf("(float %f)\n", f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2093,9 +2103,11 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
pushLiteralArray(&interpreter->literalCache, literal);
|
pushLiteralArray(&interpreter->literalCache, literal);
|
||||||
freeLiteral(literal);
|
freeLiteral(literal);
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(string \"%s\")\n", s);
|
printf("(string \"%s\")\n", s);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2111,12 +2123,14 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
pushLiteralArray(array, interpreter->literalCache.literals[index]);
|
pushLiteralArray(array, interpreter->literalCache.literals[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(array ");
|
printf("(array ");
|
||||||
Literal literal = TO_ARRAY_LITERAL(array);
|
Literal literal = TO_ARRAY_LITERAL(array);
|
||||||
printLiteral(literal);
|
printLiteral(literal);
|
||||||
printf(")\n");
|
printf(")\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//finally, push the array proper
|
//finally, push the array proper
|
||||||
Literal literal = TO_ARRAY_LITERAL(array);
|
Literal literal = TO_ARRAY_LITERAL(array);
|
||||||
@@ -2140,12 +2154,14 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
setLiteralDictionary(dictionary, interpreter->literalCache.literals[key], interpreter->literalCache.literals[val]);
|
setLiteralDictionary(dictionary, interpreter->literalCache.literals[key], interpreter->literalCache.literals[val]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(dictionary ");
|
printf("(dictionary ");
|
||||||
Literal literal = TO_DICTIONARY_LITERAL(dictionary);
|
Literal literal = TO_DICTIONARY_LITERAL(dictionary);
|
||||||
printLiteral(literal);
|
printLiteral(literal);
|
||||||
printf(")\n");
|
printf(")\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//finally, push the dictionary proper
|
//finally, push the dictionary proper
|
||||||
Literal literal = TO_DICTIONARY_LITERAL(dictionary);
|
Literal literal = TO_DICTIONARY_LITERAL(dictionary);
|
||||||
@@ -2167,9 +2183,11 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
//push to the literal cache
|
//push to the literal cache
|
||||||
pushLiteralArray(&interpreter->literalCache, literal);
|
pushLiteralArray(&interpreter->literalCache, literal);
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(function)\n");
|
printf("(function)\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2181,9 +2199,11 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
|
|
||||||
pushLiteralArray(&interpreter->literalCache, identifier);
|
pushLiteralArray(&interpreter->literalCache, identifier);
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(identifier %s (hash: %x))\n", AS_IDENTIFIER(identifier), identifier.as.identifier.hash);
|
printf("(identifier %s (hash: %x))\n", AS_IDENTIFIER(identifier), identifier.as.identifier.hash);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
freeLiteral(identifier);
|
freeLiteral(identifier);
|
||||||
}
|
}
|
||||||
@@ -2199,13 +2219,13 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
//save the type
|
//save the type
|
||||||
pushLiteralArray(&interpreter->literalCache, typeLiteral);
|
pushLiteralArray(&interpreter->literalCache, typeLiteral);
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(type ");
|
printf("(type ");
|
||||||
printLiteral(typeLiteral);
|
printLiteral(typeLiteral);
|
||||||
printf(")\n");
|
printf(")\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// freeLiteral(typeLiteral);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2234,11 +2254,13 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
//save the type
|
//save the type
|
||||||
pushLiteralArray(&interpreter->literalCache, typeLiteral); //copied
|
pushLiteralArray(&interpreter->literalCache, typeLiteral); //copied
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(type ");
|
printf("(type ");
|
||||||
printLiteral(typeLiteral);
|
printLiteral(typeLiteral);
|
||||||
printf(")\n");
|
printf(")\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
freeLiteral(typeLiteral);
|
freeLiteral(typeLiteral);
|
||||||
}
|
}
|
||||||
@@ -2336,11 +2358,13 @@ void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int lengt
|
|||||||
|
|
||||||
const char* build = readString(interpreter->bytecode, &interpreter->count);
|
const char* build = readString(interpreter->bytecode, &interpreter->count);
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
if (strncmp(build, TOY_VERSION_BUILD, strlen(TOY_VERSION_BUILD))) {
|
if (strncmp(build, TOY_VERSION_BUILD, strlen(TOY_VERSION_BUILD))) {
|
||||||
printf(WARN "Warning: interpreter/bytecode build mismatch\n" RESET);
|
printf(WARN "Warning: interpreter/bytecode build mismatch\n" RESET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
consumeByte(interpreter, OP_SECTION_END, interpreter->bytecode, &interpreter->count);
|
consumeByte(interpreter, OP_SECTION_END, interpreter->bytecode, &interpreter->count);
|
||||||
|
|
||||||
@@ -2348,9 +2372,11 @@ void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int lengt
|
|||||||
readInterpreterSections(interpreter);
|
readInterpreterSections(interpreter);
|
||||||
|
|
||||||
//code section
|
//code section
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf(NOTICE "executing bytecode\n" RESET);
|
printf(NOTICE "executing bytecode\n" RESET);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//execute the interpreter
|
//execute the interpreter
|
||||||
execInterpreter(interpreter);
|
execInterpreter(interpreter);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "literal.h"
|
#include "literal.h"
|
||||||
#include "literal_array.h"
|
#include "literal_array.h"
|
||||||
#include "literal_dictionary.h"
|
#include "literal_dictionary.h"
|
||||||
@@ -33,17 +34,17 @@ typedef struct Interpreter {
|
|||||||
|
|
||||||
//native function API
|
//native function API
|
||||||
typedef int (*NativeFn)(Interpreter* interpreter, LiteralArray* arguments);
|
typedef int (*NativeFn)(Interpreter* interpreter, LiteralArray* arguments);
|
||||||
bool injectNativeFn(Interpreter* interpreter, char* name, NativeFn func);
|
TOY_API bool injectNativeFn(Interpreter* interpreter, char* name, NativeFn func);
|
||||||
//TODO: injectNativeHook
|
//TODO: injectNativeHook
|
||||||
|
|
||||||
//utilities for the host program
|
//utilities for the host program
|
||||||
bool parseIdentifierToValue(Interpreter* interpreter, Literal* literalPtr);
|
TOY_API bool parseIdentifierToValue(Interpreter* interpreter, Literal* literalPtr);
|
||||||
void setInterpreterPrint(Interpreter* interpreter, PrintFn printOutput);
|
TOY_API void setInterpreterPrint(Interpreter* interpreter, PrintFn printOutput);
|
||||||
void setInterpreterAssert(Interpreter* interpreter, PrintFn assertOutput);
|
TOY_API void setInterpreterAssert(Interpreter* interpreter, PrintFn assertOutput);
|
||||||
void setInterpreterError(Interpreter* interpreter, PrintFn errorOutput);
|
TOY_API void setInterpreterError(Interpreter* interpreter, PrintFn errorOutput);
|
||||||
|
|
||||||
//main access
|
//main access
|
||||||
void initInterpreter(Interpreter* interpreter); //start of program
|
TOY_API void initInterpreter(Interpreter* interpreter); //start of program
|
||||||
void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length); //run the code
|
TOY_API void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length); //run the code
|
||||||
void resetInterpreter(Interpreter* interpreter); //use this to reset the interpreter's environment between runs
|
TOY_API void resetInterpreter(Interpreter* interpreter); //use this to reset the interpreter's environment between runs
|
||||||
void freeInterpreter(Interpreter* interpreter); //end of program
|
TOY_API void freeInterpreter(Interpreter* interpreter); //end of program
|
||||||
|
|||||||
@@ -109,10 +109,12 @@ static Token makeErrorToken(Lexer* lexer, char* msg) {
|
|||||||
token.length = strlen(msg);
|
token.length = strlen(msg);
|
||||||
token.line = lexer->line;
|
token.line = lexer->line;
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("err:");
|
printf("err:");
|
||||||
printToken(&token);
|
printToken(&token);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@@ -125,11 +127,13 @@ static Token makeToken(Lexer* lexer, TokenType type) {
|
|||||||
token.lexeme = &lexer->source[lexer->current - token.length];
|
token.lexeme = &lexer->source[lexer->current - token.length];
|
||||||
token.line = lexer->line;
|
token.line = lexer->line;
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
//BUG #10: this shows TOKEN_EOF twice due to the overarching structure of the program - can't be fixed
|
//BUG #10: this shows TOKEN_EOF twice due to the overarching structure of the program - can't be fixed
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("tok:");
|
printf("tok:");
|
||||||
printToken(&token);
|
printToken(&token);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@@ -152,6 +156,7 @@ static Token makeIntegerOrFloat(Lexer* lexer) {
|
|||||||
token.length = lexer->current - lexer->start;
|
token.length = lexer->current - lexer->start;
|
||||||
token.line = lexer->line;
|
token.line = lexer->line;
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
if (type == TOKEN_LITERAL_INTEGER) {
|
if (type == TOKEN_LITERAL_INTEGER) {
|
||||||
printf("int:");
|
printf("int:");
|
||||||
@@ -160,6 +165,7 @@ static Token makeIntegerOrFloat(Lexer* lexer) {
|
|||||||
}
|
}
|
||||||
printToken(&token);
|
printToken(&token);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@@ -182,10 +188,12 @@ static Token makeString(Lexer* lexer, char terminator) {
|
|||||||
token.length = lexer->current - lexer->start - 2;
|
token.length = lexer->current - lexer->start - 2;
|
||||||
token.line = lexer->line;
|
token.line = lexer->line;
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("str:");
|
printf("str:");
|
||||||
printToken(&token);
|
printToken(&token);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@@ -207,10 +215,12 @@ static Token makeKeywordOrIdentifier(Lexer* lexer) {
|
|||||||
token.length = lexer->current - lexer->start;
|
token.length = lexer->current - lexer->start;
|
||||||
token.line = lexer->line;
|
token.line = lexer->line;
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("kwd:");
|
printf("kwd:");
|
||||||
printToken(&token);
|
printToken(&token);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@@ -224,10 +234,12 @@ static Token makeKeywordOrIdentifier(Lexer* lexer) {
|
|||||||
token.length = lexer->current - lexer->start;
|
token.length = lexer->current - lexer->start;
|
||||||
token.line = lexer->line;
|
token.line = lexer->line;
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("idf:");
|
printf("idf:");
|
||||||
printToken(&token);
|
printToken(&token);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ typedef struct {
|
|||||||
int line;
|
int line;
|
||||||
} Token;
|
} Token;
|
||||||
|
|
||||||
void initLexer(Lexer* lexer, char* source);
|
TOY_API void initLexer(Lexer* lexer, char* source);
|
||||||
Token scanLexer(Lexer* lexer);
|
Token scanLexer(Lexer* lexer);
|
||||||
|
|
||||||
//for debugging
|
//for debugging
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ typedef struct {
|
|||||||
#define TO_IDENTIFIER_LITERAL(value, l) _toIdentifierLiteral(value, l)
|
#define TO_IDENTIFIER_LITERAL(value, l) _toIdentifierLiteral(value, l)
|
||||||
#define TO_TYPE_LITERAL(value, c) ((Literal){ LITERAL_TYPE, { .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }})
|
#define TO_TYPE_LITERAL(value, c) ((Literal){ LITERAL_TYPE, { .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }})
|
||||||
|
|
||||||
void freeLiteral(Literal literal);
|
TOY_API void freeLiteral(Literal literal);
|
||||||
|
|
||||||
#define IS_TRUTHY(x) _isTruthy(x)
|
#define IS_TRUTHY(x) _isTruthy(x)
|
||||||
|
|
||||||
@@ -103,17 +103,16 @@ void freeLiteral(Literal literal);
|
|||||||
#define TYPE_PUSH_SUBTYPE(lit, subtype) _typePushSubtype(lit, subtype)
|
#define TYPE_PUSH_SUBTYPE(lit, subtype) _typePushSubtype(lit, subtype)
|
||||||
|
|
||||||
//BUGFIX: macros are not functions
|
//BUGFIX: macros are not functions
|
||||||
bool _isTruthy(Literal x);
|
TOY_API bool _isTruthy(Literal x);
|
||||||
Literal _toStringLiteral(char* str, int length);
|
TOY_API Literal _toStringLiteral(char* str, int length);
|
||||||
Literal _toIdentifierLiteral(char* str, int length);
|
TOY_API Literal _toIdentifierLiteral(char* str, int length);
|
||||||
Literal* _typePushSubtype(Literal* lit, Literal subtype);
|
TOY_API Literal* _typePushSubtype(Literal* lit, Literal subtype);
|
||||||
|
|
||||||
//utils
|
//utils
|
||||||
Literal copyLiteral(Literal original);
|
TOY_API Literal copyLiteral(Literal original);
|
||||||
char* copyString(char* original, int length);
|
TOY_API char* copyString(char* original, int length);
|
||||||
bool literalsAreEqual(Literal lhs, Literal rhs);
|
TOY_API bool literalsAreEqual(Literal lhs, Literal rhs);
|
||||||
int hashLiteral(Literal lit);
|
TOY_API int hashLiteral(Literal lit);
|
||||||
|
|
||||||
void printLiteral(Literal literal);
|
|
||||||
void printLiteralCustom(Literal literal, void (printFn)(const char*));
|
|
||||||
|
|
||||||
|
TOY_API void printLiteral(Literal literal);
|
||||||
|
TOY_API void printLiteralCustom(Literal literal, void (printFn)(const char*));
|
||||||
|
|||||||
@@ -5,13 +5,24 @@ CFLAGS +=$(addprefix -I,$(IDIR)) -g -Wall -W -pedantic -Wno-unused-parameter -Wn
|
|||||||
LIBS +=
|
LIBS +=
|
||||||
|
|
||||||
ODIR = obj
|
ODIR = obj
|
||||||
SRC = $(wildcard *.c)
|
SRC = $(filter-out $(wildcard *main.c),$(wildcard *.c))
|
||||||
OBJ = $(addprefix $(ODIR)/,$(SRC:.c=.o))
|
OBJ = $(addprefix $(ODIR)/,$(SRC:.c=.o))
|
||||||
|
|
||||||
OUT = ../$(OUTDIR)/toy
|
OUTNAME = toy
|
||||||
|
OUT = ../$(OUTDIR)/$(OUTNAME).dll
|
||||||
|
LIBLINE =-Wl,--out-implib=../$(OUTDIR)/lib$(OUTNAME).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive $(OBJ) -Wl,--no-whole-archive
|
||||||
|
|
||||||
all: $(OBJ)
|
REPLSRC = $(wildcard repl_main.c)
|
||||||
$(CC) -o $(OUT) $^ $(CFLAGS) $(LIBS)
|
REPLOUT = $(OUTNAME)repl.exe
|
||||||
|
|
||||||
|
all: library $(addprefix $(ODIR)/,$(REPLSRC:.c=.o))
|
||||||
|
$(CC) -DTOY_IMPORT $(CFLAGS) -o ../$(OUTDIR)/$(REPLOUT) $(addprefix $(ODIR)/,$(REPLSRC:.c=.o)) $(LIBS) -L$(realpath $(shell pwd)/../$(OUTDIR)) -l$(OUTNAME)
|
||||||
|
|
||||||
|
library: $(OBJ)
|
||||||
|
$(CC) -DTOY_EXPORT $(CFLAGS) -shared -o $(OUT) $(LIBLINE)
|
||||||
|
|
||||||
|
static: $(OBJ) $(addprefix $(ODIR)/,$(REPLSRC:.c=.o))
|
||||||
|
$(CC) $(CFLAGS) -o ../$(OUTDIR)/$(REPLOUT) $(addprefix $(ODIR)/,$(REPLSRC:.c=.o)) $(OBJ) $(LIBS)
|
||||||
|
|
||||||
$(OBJ): | $(ODIR)
|
$(OBJ): | $(ODIR)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
#include "literal.h"
|
#include "literal.h"
|
||||||
#include "opcodes.h"
|
#include "opcodes.h"
|
||||||
#include "token_types.h"
|
#include "token_types.h"
|
||||||
@@ -153,7 +154,8 @@ union _node {
|
|||||||
NodeIndex index;
|
NodeIndex index;
|
||||||
};
|
};
|
||||||
|
|
||||||
void freeNode(Node* node);
|
TOY_API void freeNode(Node* node);
|
||||||
|
|
||||||
void emitNodeLiteral(Node** nodeHandle, Literal literal);
|
void emitNodeLiteral(Node** nodeHandle, Literal literal);
|
||||||
void emitNodeUnary(Node** nodeHandle, Opcode opcode, Node* child);
|
void emitNodeUnary(Node** nodeHandle, Opcode opcode, Node* child);
|
||||||
void emitNodeBinary(Node** nodeHandle, Node* rhs, Opcode opcode); //handled node becomes lhs
|
void emitNodeBinary(Node** nodeHandle, Node* rhs, Opcode opcode); //handled node becomes lhs
|
||||||
|
|||||||
@@ -59,9 +59,11 @@ static void consume(Parser* parser, TokenType tokenType, const char* msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void synchronize(Parser* parser) {
|
static void synchronize(Parser* parser) {
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
fprintf(stderr, ERROR "synchronizing\n" RESET);
|
fprintf(stderr, ERROR "synchronizing\n" RESET);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
while (parser->current.type != TOKEN_EOF) {
|
while (parser->current.type != TOKEN_EOF) {
|
||||||
switch(parser->current.type) {
|
switch(parser->current.type) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "parser.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
|
||||||
@@ -16,6 +15,6 @@ typedef struct {
|
|||||||
Token previous;
|
Token previous;
|
||||||
} Parser;
|
} Parser;
|
||||||
|
|
||||||
void initParser(Parser* parser, Lexer* lexer);
|
TOY_API void initParser(Parser* parser, Lexer* lexer);
|
||||||
void freeParser(Parser* parser);
|
TOY_API void freeParser(Parser* parser);
|
||||||
Node* scanParser(Parser* parser);
|
TOY_API Node* scanParser(Parser* parser);
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
|
|
||||||
#include "memory.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user