mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 06:44:07 +10:00
Script tests re-added, all tests can run under gdb
Also fixed a minor bug with printing, and removed the ability to configure the parser. Added and updated QUICKSTART.md as a quick way to get people started. There's some broken scripts under 'scripts/' that require functions to work properly.
This commit is contained in:
146
QUICKSTART.md
Normal file
146
QUICKSTART.md
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
# Toy v2 Quick-Start Guide
|
||||||
|
|
||||||
|
To help you start using Toy as fast as possible, here are the most useful elements of the language. Not everything available is listed, but this should let you start coding right away.
|
||||||
|
|
||||||
|
## Keyword 'print'
|
||||||
|
|
||||||
|
The `print` keyword takes one value as a parameter, which is sent to stdout by default, or can be redirected elsewhere using C.
|
||||||
|
|
||||||
|
```
|
||||||
|
print "Hello World!";
|
||||||
|
```
|
||||||
|
|
||||||
|
## Keyword 'assert'
|
||||||
|
|
||||||
|
The `assert` keyword takes two values as parameters, separated by a comma. If the first value is falsy or `null`, the optional second parameter is sent to stderr by default, or can be redirected elsewhere using C. If no second parameter is provided, a generic error message is used instead.
|
||||||
|
|
||||||
|
```
|
||||||
|
//nothing happens
|
||||||
|
assert 1 < 2;
|
||||||
|
|
||||||
|
//this assert will fail, and output the second parameter
|
||||||
|
assert null, "Hello world!";
|
||||||
|
```
|
||||||
|
|
||||||
|
## Variables and Types
|
||||||
|
|
||||||
|
Variables can be declared with the `var` keyword, and can be given an optional type from the list below. If no type is specified, `any` is used by default.
|
||||||
|
|
||||||
|
```
|
||||||
|
var answer = 42;
|
||||||
|
|
||||||
|
var question: string = "How many roads must a man walk down?";
|
||||||
|
```
|
||||||
|
|
||||||
|
To make a variable immutable, use the `const` keyword after the type declaration. In this case, it must be assigend a value.
|
||||||
|
|
||||||
|
```
|
||||||
|
var quote: string const = "War. War never changes.";
|
||||||
|
```
|
||||||
|
|
||||||
|
The types available in Toy are:
|
||||||
|
|
||||||
|
| type | name | description |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `bool` | boolean | Either `true` or `false`. |
|
||||||
|
| `int` | integer | Any whole number (32-bits). |
|
||||||
|
| `float` | float | A decimal number (32-bits), using floating-point arithmetic. |
|
||||||
|
| `string` | string | A series of characters used for text processing. |
|
||||||
|
| `array` | array | A series of values stored sequentially in memory. |
|
||||||
|
| `table` | table | A series key-value pairs stored in such a way that allows for fast lookups. Booleans, functions, opaques and `null` can't be used as keys. |
|
||||||
|
| `function` | function | A chunk of reusable code that takes zero or more parameters, and returns zero or more results. Functions are declared with the `fn` keyword. |
|
||||||
|
| `opaque` | opaque | This value is unusable in Toy, but allows you to pass data between C functions. |
|
||||||
|
| `any` | any | The default type when nothing is specified. Theis can hold any value. |
|
||||||
|
|
||||||
|
## Control Flow
|
||||||
|
|
||||||
|
Choosing an option, or repeating a chunk of code multiple times, is essential for any general purpose language.
|
||||||
|
|
||||||
|
Choosing between two options can be done with the `if-then-else` else statement. If the condition is truthy, the 'then-branch' will be executed. Otherwise, the optional 'else-branch' is executed instead.
|
||||||
|
|
||||||
|
```
|
||||||
|
var answer = 42;
|
||||||
|
|
||||||
|
if (answer < 56) {
|
||||||
|
print "Cod dang it!";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Something's fishy here...";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
var challenge = "hard";
|
||||||
|
|
||||||
|
if (challenge == "hard") {
|
||||||
|
print "I choose to build a scripting language, not because it's easy, but because it's hard!";
|
||||||
|
}
|
||||||
|
|
||||||
|
//the else-branch is optional
|
||||||
|
```
|
||||||
|
|
||||||
|
To repeat a certain action, use the `while-then` loop, which repeats the body as long as the condition is true at the beginning of each loop.
|
||||||
|
|
||||||
|
```
|
||||||
|
var loops = 0;
|
||||||
|
|
||||||
|
while (loops++ < 8) {
|
||||||
|
print "These episodes are endless.";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To break out of a loop, you can use the `break` keyword. Alternatively, to restart the loop early, use the `continue` keyword.
|
||||||
|
|
||||||
|
```
|
||||||
|
var loops = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (++loops < 15532) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break; //poor yuki ;_;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
*Note: The `for` loop is coming, eventually, but isn't vital right now.*
|
||||||
|
|
||||||
|
## Arrays and Tables
|
||||||
|
|
||||||
|
Arrays are defined with a pair of brackets, and can contain a list of comma-separated values.
|
||||||
|
|
||||||
|
```
|
||||||
|
//'array' is a reserved keyword, so it can't be used as a name
|
||||||
|
var a = [1,2,3];
|
||||||
|
|
||||||
|
//instead, it's used as a type
|
||||||
|
var b: array = [4,5,6];
|
||||||
|
|
||||||
|
//define an empty array like this
|
||||||
|
var c: array = [];
|
||||||
|
|
||||||
|
//arrays are zero-indexed
|
||||||
|
print a[0]; //'1'
|
||||||
|
```
|
||||||
|
|
||||||
|
Tables are also defined with brackets, and contain a comma-separated list of key-value pairs defined by colons:
|
||||||
|
|
||||||
|
```
|
||||||
|
//most types can be used as keys
|
||||||
|
var t = ["alpha": 1, "beta": 2, "gamma": 3];
|
||||||
|
|
||||||
|
//the 'table' keyword can define the type, and an empty table still has a colon
|
||||||
|
var u: table = [:];
|
||||||
|
|
||||||
|
//printing a table does NOT guarantee internal order, but the elements can be accessed with the keys.
|
||||||
|
print t["beta"];
|
||||||
|
```
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
Watch this space.
|
||||||
|
|
||||||
|
## External Libraries and Extending Toy
|
||||||
|
|
||||||
|
Watch this space.
|
||||||
|
|
||||||
11
repl/main.c
11
repl/main.c
@@ -116,21 +116,21 @@ static void printCallback(const char* msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void errorAndExitCallback(const char* msg) {
|
static void errorAndExitCallback(const char* msg) {
|
||||||
fprintf(stderr, TOY_CC_ERROR "Error: %s\n" TOY_CC_RESET, msg);
|
fprintf(stderr, TOY_CC_ERROR "Error: %s" TOY_CC_RESET "\n", msg);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void errorAndContinueCallback(const char* msg) {
|
static void errorAndContinueCallback(const char* msg) {
|
||||||
fprintf(stderr, TOY_CC_ERROR "Error: %s\n" TOY_CC_RESET, msg);
|
fprintf(stderr, TOY_CC_ERROR "Error: %s" TOY_CC_RESET "\n", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void assertFailureAndExitCallback(const char* msg) {
|
static void assertFailureAndExitCallback(const char* msg) {
|
||||||
fprintf(stderr, TOY_CC_ASSERT "Assert Failure: %s\n" TOY_CC_RESET, msg);
|
fprintf(stderr, TOY_CC_ASSERT "Assert Failure: %s" TOY_CC_RESET "\n", msg);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void assertFailureAndContinueCallback(const char* msg) {
|
static void assertFailureAndContinueCallback(const char* msg) {
|
||||||
fprintf(stderr, TOY_CC_ASSERT "Assert Failure: %s\n" TOY_CC_RESET, msg);
|
fprintf(stderr, TOY_CC_ASSERT "Assert Failure: %s" TOY_CC_RESET "\n", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void noOpCallback(const char* msg) {
|
static void noOpCallback(const char* msg) {
|
||||||
@@ -325,7 +325,6 @@ int repl(const char* filepath) {
|
|||||||
Toy_bindLexer(&lexer, inputBuffer);
|
Toy_bindLexer(&lexer, inputBuffer);
|
||||||
Toy_Parser parser;
|
Toy_Parser parser;
|
||||||
Toy_bindParser(&parser, &lexer);
|
Toy_bindParser(&parser, &lexer);
|
||||||
Toy_configureParser(&parser, false);
|
|
||||||
Toy_Ast* ast = Toy_scanParser(&bucket, &parser); //Ast is in the bucket, so it doesn't need to be freed
|
Toy_Ast* ast = Toy_scanParser(&bucket, &parser); //Ast is in the bucket, so it doesn't need to be freed
|
||||||
|
|
||||||
//parsing error, retry
|
//parsing error, retry
|
||||||
@@ -478,8 +477,6 @@ int main(int argc, const char* argv[]) {
|
|||||||
Toy_Parser parser;
|
Toy_Parser parser;
|
||||||
Toy_bindParser(&parser, &lexer);
|
Toy_bindParser(&parser, &lexer);
|
||||||
|
|
||||||
Toy_configureParser(&parser, cmd.removeAssert);
|
|
||||||
|
|
||||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||||
Toy_Ast* ast = Toy_scanParser(&bucket, &parser);
|
Toy_Ast* ast = Toy_scanParser(&bucket, &parser);
|
||||||
unsigned char* bytecode = Toy_compileToBytecode(ast);
|
unsigned char* bytecode = Toy_compileToBytecode(ast);
|
||||||
|
|||||||
17
scripts/benchpress.toy
Normal file
17
scripts/benchpress.toy
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//calculate the nth fibonacci number, and print it
|
||||||
|
|
||||||
|
var counter: int = 0;
|
||||||
|
|
||||||
|
var first: int = 1;
|
||||||
|
var second: int = 0;
|
||||||
|
|
||||||
|
//BUG: This causes a stack overflow
|
||||||
|
while (counter < 100_000) {
|
||||||
|
var third: int = first + second;
|
||||||
|
first = second;
|
||||||
|
second = third;
|
||||||
|
|
||||||
|
print third;
|
||||||
|
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
16
scripts/fib.toy
Normal file
16
scripts/fib.toy
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//BUG: Not yet functional
|
||||||
|
|
||||||
|
//example of the fibonacci sequence
|
||||||
|
fn fib(n: int) {
|
||||||
|
if (n < 2) return n;
|
||||||
|
return fib(n-1) + fib(n-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: type coercion syntax hasn't been decided on yet, but it will be needed
|
||||||
|
for (var i = 1; i <= 10; i++) {
|
||||||
|
print i .. ":" .. fib(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Note to my future self: yes, the base case in 'fib()' is 'n < 2', stop second guessing yourself!
|
||||||
|
//Note to my past self: don't tell me what to do!
|
||||||
|
//Note to both of you: keep it down you young whipper snappers!
|
||||||
24
scripts/fizzbuzz.toy
Normal file
24
scripts/fizzbuzz.toy
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
//standard example, using 'while' instead of 'for', because it's not ready yet
|
||||||
|
|
||||||
|
var counter: int = 0;
|
||||||
|
|
||||||
|
while (++counter <= 100) {
|
||||||
|
var result: string = "";
|
||||||
|
|
||||||
|
if (counter % 3 == 0) {
|
||||||
|
result = result .. "fizz";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counter % 5 == 0) {
|
||||||
|
result = result .. "buzz";
|
||||||
|
}
|
||||||
|
|
||||||
|
//finally
|
||||||
|
if (result != "") {
|
||||||
|
print result;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
20
scripts/funky.toy
Normal file
20
scripts/funky.toy
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//BUG: functions aren't working yet
|
||||||
|
fn makeCounter() {
|
||||||
|
var counter: int = 0;
|
||||||
|
|
||||||
|
fn increment() {
|
||||||
|
return ++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tally = makeCounter();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
var result = tally();
|
||||||
|
|
||||||
|
if (result >= 10_000_000) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
8
scripts/leapyear.toy
Normal file
8
scripts/leapyear.toy
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
//BUG: Not yet functional
|
||||||
|
|
||||||
|
//find the leap years
|
||||||
|
fn isLeapYear(n: int) {
|
||||||
|
if (n % 400 == 0) return true;
|
||||||
|
if (n % 100 == 0) return false;
|
||||||
|
return n % 4 == 0;
|
||||||
|
}
|
||||||
@@ -43,7 +43,7 @@ reference: https://stackoverflow.com/questions/4842424/list-of-ansi-color-escape
|
|||||||
#define TOY_CC_WARN "\033[" TOY_CC_FONT_YELLOW ";" TOY_CC_BACK_DEFAULT "m"
|
#define TOY_CC_WARN "\033[" TOY_CC_FONT_YELLOW ";" TOY_CC_BACK_DEFAULT "m"
|
||||||
#define TOY_CC_ERROR "\033[" TOY_CC_FONT_RED ";" TOY_CC_BACK_DEFAULT "m"
|
#define TOY_CC_ERROR "\033[" TOY_CC_FONT_RED ";" TOY_CC_BACK_DEFAULT "m"
|
||||||
#define TOY_CC_ASSERT "\033[" TOY_CC_FONT_BLACK ";" TOY_CC_BACK_MAGENTA "m"
|
#define TOY_CC_ASSERT "\033[" TOY_CC_FONT_BLACK ";" TOY_CC_BACK_MAGENTA "m"
|
||||||
#define TOY_CC_RESET "\033[" "0" "m"
|
#define TOY_CC_RESET "\033[" TOY_CC_FONT_DEFAULT ";" TOY_CC_BACK_DEFAULT "m"
|
||||||
|
|
||||||
//for unsupported platforms, these become no-ops
|
//for unsupported platforms, these become no-ops
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -818,18 +818,12 @@ static void makeAssertStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_As
|
|||||||
Toy_Ast* ast = NULL; //assert's emit function is a bit different
|
Toy_Ast* ast = NULL; //assert's emit function is a bit different
|
||||||
makeExpr(bucketHandle, parser, &ast);
|
makeExpr(bucketHandle, parser, &ast);
|
||||||
|
|
||||||
//if assert is disabled, don't emit the assert
|
//NOTE: if it's an aggregate node, then it's got a second arg
|
||||||
if (parser->removeAssert) {
|
if (ast->type == TOY_AST_AGGREGATE) {
|
||||||
Toy_private_emitAstPass(bucketHandle, rootHandle);
|
Toy_private_emitAstAssert(bucketHandle, rootHandle, ast->aggregate.left, ast->aggregate.right);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//NOTE: if it's an aggregate node, then it's got a second arg
|
Toy_private_emitAstAssert(bucketHandle, rootHandle, ast, NULL);
|
||||||
if (ast->type == TOY_AST_AGGREGATE) {
|
|
||||||
Toy_private_emitAstAssert(bucketHandle, rootHandle, ast->aggregate.left, ast->aggregate.right);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Toy_private_emitAstAssert(bucketHandle, rootHandle, ast, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
consume(parser, TOY_TOKEN_OPERATOR_SEMICOLON, "Expected ';' at the end of assert statement");
|
consume(parser, TOY_TOKEN_OPERATOR_SEMICOLON, "Expected ';' at the end of assert statement");
|
||||||
@@ -1159,10 +1153,4 @@ void Toy_resetParser(Toy_Parser* parser) {
|
|||||||
|
|
||||||
parser->error = false;
|
parser->error = false;
|
||||||
parser->panic = false;
|
parser->panic = false;
|
||||||
|
|
||||||
parser->removeAssert = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Toy_configureParser(Toy_Parser* parser, bool removeAssert) {
|
|
||||||
parser->removeAssert = removeAssert;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,8 @@ typedef struct Toy_Parser {
|
|||||||
|
|
||||||
bool error;
|
bool error;
|
||||||
bool panic; //currently processing an error
|
bool panic; //currently processing an error
|
||||||
|
|
||||||
//configs
|
|
||||||
bool removeAssert;
|
|
||||||
} Toy_Parser;
|
} Toy_Parser;
|
||||||
|
|
||||||
TOY_API void Toy_bindParser(Toy_Parser* parser, Toy_Lexer* lexer);
|
TOY_API void Toy_bindParser(Toy_Parser* parser, Toy_Lexer* lexer);
|
||||||
TOY_API Toy_Ast* Toy_scanParser(Toy_Bucket** bucketHandle, Toy_Parser* parser);
|
TOY_API Toy_Ast* Toy_scanParser(Toy_Bucket** bucketHandle, Toy_Parser* parser);
|
||||||
TOY_API void Toy_resetParser(Toy_Parser* parser);
|
TOY_API void Toy_resetParser(Toy_Parser* parser);
|
||||||
|
|
||||||
//configure certain options
|
|
||||||
TOY_API void Toy_configureParser(Toy_Parser* parser, bool removeAssert);
|
|
||||||
|
|||||||
@@ -838,11 +838,11 @@ static void processIndex(Toy_VM* vm) {
|
|||||||
//extract cstring, based on type
|
//extract cstring, based on type
|
||||||
if (str->info.type == TOY_STRING_LEAF) {
|
if (str->info.type == TOY_STRING_LEAF) {
|
||||||
const char* cstr = str->leaf.data;
|
const char* cstr = str->leaf.data;
|
||||||
result = Toy_toStringLength(&vm->memoryBucket, cstr + i, l);
|
result = Toy_createStringLength(&vm->memoryBucket, cstr + i, l);
|
||||||
}
|
}
|
||||||
else if (str->info.type == TOY_STRING_NODE) {
|
else if (str->info.type == TOY_STRING_NODE) {
|
||||||
char* cstr = Toy_getStringRaw(str);
|
char* cstr = Toy_getStringRaw(str);
|
||||||
result = Toy_toStringLength(&vm->memoryBucket, cstr + i, l);
|
result = Toy_createStringLength(&vm->memoryBucket, cstr + i, l);
|
||||||
free(cstr);
|
free(cstr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#bridge file
|
#bridge file
|
||||||
|
|
||||||
export CFLAGS+=-DTOY_CC_ENABLED
|
|
||||||
|
|
||||||
all:
|
all:
|
||||||
$(MAKE) -C units -k
|
$(MAKE) -C units -k
|
||||||
|
$(MAKE) -C scripts -k
|
||||||
|
|
||||||
gdb:
|
gdb:
|
||||||
$(MAKE) -C units -k gdb
|
$(MAKE) -C units -k gdb
|
||||||
|
$(MAKE) -C scripts -k gdb
|
||||||
|
|
||||||
|
#TODO: valgrind
|
||||||
2
tests/scripts/gdb_init
Normal file
2
tests/scripts/gdb_init
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
set breakpoint pending on
|
||||||
|
|
||||||
52
tests/scripts/makefile
Normal file
52
tests/scripts/makefile
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#compiler settings
|
||||||
|
CC=gcc
|
||||||
|
CFLAGS+=-std=c17 -g -Wall -Werror -Wextra -Wpedantic -Wformat=2 -Wno-newline-eof
|
||||||
|
LIBS+=-lm
|
||||||
|
LDFLAGS+=
|
||||||
|
|
||||||
|
ifeq ($(shell uname),Linux)
|
||||||
|
LDFLAGS=-Wl,--gc-sections
|
||||||
|
else ifeq ($(shell uname),NetBSD)
|
||||||
|
LDFLAGS=-Wl,--gc-sections
|
||||||
|
else ifeq ($(OS),Windows_NT)
|
||||||
|
LDFLAGS=-Wl,--gc-sections
|
||||||
|
else ifeq ($(shell uname),Darwin)
|
||||||
|
LDFLAGS=-Wl,-dead_strip
|
||||||
|
else
|
||||||
|
@echo "LDFLAGS set failed - what platform is this?"
|
||||||
|
endif
|
||||||
|
|
||||||
|
#directories
|
||||||
|
TEST_ROOTDIR=../..
|
||||||
|
TEST_SOURCEDIR=$(TEST_ROOTDIR)/$(TOY_SOURCEDIR)
|
||||||
|
TEST_REPLDIR=$(TEST_ROOTDIR)/$(TOY_REPLDIR)
|
||||||
|
TEST_SCRIPTDIR=.
|
||||||
|
|
||||||
|
#file names
|
||||||
|
TEST_SCRIPTFILES=$(wildcard $(TEST_SCRIPTDIR)/test_*.toy)
|
||||||
|
|
||||||
|
#build the source and repl, copy to the local dir, and run
|
||||||
|
all: source repl copy run
|
||||||
|
|
||||||
|
#compile the source and repl first
|
||||||
|
source:
|
||||||
|
$(MAKE) -C $(TEST_SOURCEDIR)
|
||||||
|
|
||||||
|
repl: source
|
||||||
|
$(MAKE) -C $(TEST_REPLDIR)
|
||||||
|
|
||||||
|
copy:
|
||||||
|
cp -r $(TEST_ROOTDIR)/$(TOY_OUTDIR) .
|
||||||
|
|
||||||
|
run: $(TEST_SCRIPTFILES:.toy=.toy-run)
|
||||||
|
|
||||||
|
%.toy-run: %.toy
|
||||||
|
find -name repl* -type f -exec {} -f ../$< --verbose \;
|
||||||
|
|
||||||
|
#using gdb
|
||||||
|
gdb: source repl copy run-gdb
|
||||||
|
|
||||||
|
run-gdb: $(TEST_SCRIPTFILES:.toy=.toy-run-gdb)
|
||||||
|
|
||||||
|
%.toy-run-gdb: %.toy
|
||||||
|
gdb $(TEST_OUTDIR)/$(TEST_REPLNAME) -ix gdb_init -ex=run --batch --return-child-result --args "out/repl.out" "-f" "../$<" "--verbose"
|
||||||
26
tests/scripts/test_arrays.toy
Normal file
26
tests/scripts/test_arrays.toy
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//1-D array
|
||||||
|
var arr = [1, 2, 3];
|
||||||
|
arr[1] = 6;
|
||||||
|
|
||||||
|
assert arr == [1, 6, 3], "1-D array failed";
|
||||||
|
|
||||||
|
//we need to go deeper
|
||||||
|
var barr = [
|
||||||
|
[1, 2, 3],
|
||||||
|
[4, 5, 6],
|
||||||
|
[7, 8, 9]
|
||||||
|
];
|
||||||
|
|
||||||
|
barr[1][1] = 99;
|
||||||
|
|
||||||
|
assert barr == [[1, 2, 3],[4,99,6],[7,8,9]], "2-D array failed";
|
||||||
|
|
||||||
|
//test trailing commas
|
||||||
|
var a = [1, 2, 3, ];
|
||||||
|
|
||||||
|
print a;
|
||||||
|
|
||||||
|
//test empty arrays
|
||||||
|
var b = [];
|
||||||
|
|
||||||
|
print b;
|
||||||
9
tests/scripts/test_control_flow.toy
Normal file
9
tests/scripts/test_control_flow.toy
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
//these are allowed
|
||||||
|
/* EMPTY */;
|
||||||
|
if (true) { }
|
||||||
|
if (true) pass;
|
||||||
|
|
||||||
|
|
||||||
|
//these are not allowed
|
||||||
|
// if (true) /* EMPTY */;
|
||||||
|
|
||||||
13
tests/scripts/test_keyword_assert.toy
Normal file
13
tests/scripts/test_keyword_assert.toy
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
//NOTE: these tests are all passing - failing tests can be found under the 'mustfails' directory
|
||||||
|
|
||||||
|
//basic assert statement
|
||||||
|
assert true;
|
||||||
|
|
||||||
|
//assert on a string (tests for it's truthiness)
|
||||||
|
assert "Hello world";
|
||||||
|
|
||||||
|
//assert on a condition
|
||||||
|
assert 1 < 2;
|
||||||
|
|
||||||
|
//assert with an optional message
|
||||||
|
assert true, "Assertion message";
|
||||||
65
tests/scripts/test_keyword_if_then_else.toy
Normal file
65
tests/scripts/test_keyword_if_then_else.toy
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
//literals
|
||||||
|
if (true) {
|
||||||
|
print "Success 1";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Failure 1";
|
||||||
|
}
|
||||||
|
|
||||||
|
//false literals
|
||||||
|
if (false) {
|
||||||
|
print "Failure 2";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Success 2";
|
||||||
|
}
|
||||||
|
|
||||||
|
//conditionals
|
||||||
|
if (1 < 2) {
|
||||||
|
print "Success 3";
|
||||||
|
}
|
||||||
|
if (1 > 2) {
|
||||||
|
print "Failure 3";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//variables
|
||||||
|
var a = 42;
|
||||||
|
|
||||||
|
if (a) {
|
||||||
|
print "Success 4";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Failure 4";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (a == 42) {
|
||||||
|
print "Success 5";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Failure 5";
|
||||||
|
}
|
||||||
|
|
||||||
|
//concatenated strings
|
||||||
|
if ("foo" .. "bar" == "foobar") {
|
||||||
|
print "Success 6";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Failure 6";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ("foobar" == "foo" .. "bar") {
|
||||||
|
print "Success 7";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Failure 7";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("fizz" .. "le" == "fi" .. "zzle") {
|
||||||
|
print "Success 8";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Failure 8";
|
||||||
|
}
|
||||||
46
tests/scripts/test_keyword_if_then_else_no_braces.toy
Normal file
46
tests/scripts/test_keyword_if_then_else_no_braces.toy
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
//literals
|
||||||
|
if (true)
|
||||||
|
print "Success 1";
|
||||||
|
else
|
||||||
|
print "Failure 1";
|
||||||
|
|
||||||
|
//false literals
|
||||||
|
if (false)
|
||||||
|
print "Failure 2";
|
||||||
|
else
|
||||||
|
print "Success 2";
|
||||||
|
|
||||||
|
//conditionals
|
||||||
|
if (1 < 2)
|
||||||
|
print "Success 3";
|
||||||
|
if (1 > 2)
|
||||||
|
print "Failure 3";
|
||||||
|
|
||||||
|
//variables
|
||||||
|
var a = 42;
|
||||||
|
|
||||||
|
if (a)
|
||||||
|
print "Success 4";
|
||||||
|
else
|
||||||
|
print "Failure 4";
|
||||||
|
|
||||||
|
if (a == 42)
|
||||||
|
print "Success 5";
|
||||||
|
else
|
||||||
|
print "Failure 5";
|
||||||
|
|
||||||
|
//concatenated strings
|
||||||
|
if ("foo" .. "bar" == "foobar")
|
||||||
|
print "Success 6";
|
||||||
|
else
|
||||||
|
print "Failure 6";
|
||||||
|
|
||||||
|
if ("foobar" == "foo" .. "bar")
|
||||||
|
print "Success 7";
|
||||||
|
else
|
||||||
|
print "Failure 7";
|
||||||
|
|
||||||
|
if ("fizz" .. "le" == "fi" .. "zzle")
|
||||||
|
print "Success 8";
|
||||||
|
else
|
||||||
|
print "Failure 8";
|
||||||
21
tests/scripts/test_keyword_print.toy
Normal file
21
tests/scripts/test_keyword_print.toy
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
//basic print statement
|
||||||
|
print 42;
|
||||||
|
|
||||||
|
//print compount expressions
|
||||||
|
print 3 * 5;
|
||||||
|
|
||||||
|
//print a string
|
||||||
|
print "Hello world!";
|
||||||
|
|
||||||
|
//print a concatenated string
|
||||||
|
print "Hello" .. "world!";
|
||||||
|
|
||||||
|
//print with escaped characters
|
||||||
|
print "\tHello\nworld!";
|
||||||
|
|
||||||
|
//print from a substring string
|
||||||
|
print "Hello world"[0,5];
|
||||||
|
|
||||||
|
//print from a substring, after a concat
|
||||||
|
print ("hello" .. "world")[2,6];
|
||||||
|
|
||||||
132
tests/scripts/test_keyword_while_break_continue.toy
Normal file
132
tests/scripts/test_keyword_while_break_continue.toy
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
//make sure it works with multiple repititions
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
//test break
|
||||||
|
while (true) {
|
||||||
|
break;
|
||||||
|
assert false, "break failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test continue
|
||||||
|
var flag1: bool = true;
|
||||||
|
while (flag1) {
|
||||||
|
flag1 = false;
|
||||||
|
continue;
|
||||||
|
assert false, "continue failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
//test break
|
||||||
|
while (true) {
|
||||||
|
break;
|
||||||
|
assert false, "break failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test continue
|
||||||
|
var flag2: bool = true;
|
||||||
|
while (flag2) {
|
||||||
|
flag2 = false;
|
||||||
|
continue;
|
||||||
|
assert false, "continue failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
//test break
|
||||||
|
while (true) {
|
||||||
|
break;
|
||||||
|
assert false, "break failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test continue
|
||||||
|
var flag3: bool = true;
|
||||||
|
while (flag3) {
|
||||||
|
flag3 = false;
|
||||||
|
continue;
|
||||||
|
assert false, "continue failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
{
|
||||||
|
//test break
|
||||||
|
while (true) {
|
||||||
|
break;
|
||||||
|
assert false, "break failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test continue
|
||||||
|
var flag4: bool = true;
|
||||||
|
while (flag4) {
|
||||||
|
flag4 = false;
|
||||||
|
continue;
|
||||||
|
assert false, "continue failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
{
|
||||||
|
//test break
|
||||||
|
while (true) {
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert false, "break failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test continue
|
||||||
|
var flag5: bool = true;
|
||||||
|
while (flag5) {
|
||||||
|
flag5 = false;
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert false, "continue failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
{
|
||||||
|
//iteration
|
||||||
|
var iteration = 0;
|
||||||
|
while(iteration < 10) {
|
||||||
|
print iteration;
|
||||||
|
iteration += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
//if and while work together
|
||||||
|
var count = 1;
|
||||||
|
while (count <= 10) {
|
||||||
|
if (count % 2 == 0) {
|
||||||
|
print "even";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "odd";
|
||||||
|
}
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
{
|
||||||
|
//make sure break and continue point to the correct locations
|
||||||
|
var loops = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (++loops < 15532) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert loops == 15532, "Yuki loop failed (break + continue)";
|
||||||
|
}
|
||||||
|
|
||||||
17
tests/scripts/test_scopes.toy
Normal file
17
tests/scripts/test_scopes.toy
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//shadowing
|
||||||
|
var answer = 42;
|
||||||
|
print answer; //42
|
||||||
|
{
|
||||||
|
var answer = 7;
|
||||||
|
print answer; //7
|
||||||
|
}
|
||||||
|
print answer; //42
|
||||||
|
|
||||||
|
//rebinding
|
||||||
|
var question = 42;
|
||||||
|
print question; //42
|
||||||
|
{
|
||||||
|
var question = question;
|
||||||
|
print question; //42
|
||||||
|
}
|
||||||
|
print question; //42
|
||||||
33
tests/scripts/test_tables.toy
Normal file
33
tests/scripts/test_tables.toy
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
//1-D table
|
||||||
|
var a = ["alpha": 1, "beta": 2, "gamma": 3];
|
||||||
|
a["beta"] = 6;
|
||||||
|
|
||||||
|
print a;
|
||||||
|
assert a == ["alpha": 1, "beta": 6, "gamma": 3], "1-D tables failed";
|
||||||
|
|
||||||
|
//nested
|
||||||
|
var b = [
|
||||||
|
"outer": ["inner": true],
|
||||||
|
"alpha": 1,
|
||||||
|
"beta": 2,
|
||||||
|
"gamma": 3
|
||||||
|
];
|
||||||
|
|
||||||
|
print b;
|
||||||
|
assert b == ["alpha": 1, "beta": 2, "gamma": 3, "outer": ["inner": true]], "nested tables failed";
|
||||||
|
|
||||||
|
//test empty tables
|
||||||
|
var empty = [:];
|
||||||
|
|
||||||
|
print empty;
|
||||||
|
assert empty == [:], "empty tables failed";
|
||||||
|
|
||||||
|
//test trailing commas
|
||||||
|
var trailing = [
|
||||||
|
"alpha":1,
|
||||||
|
"beta":2,
|
||||||
|
"gamma":3,
|
||||||
|
];
|
||||||
|
|
||||||
|
print trailing;
|
||||||
|
assert trailing == ["alpha": 1, "beta": 2, "gamma": 3], "trailing tables failed";
|
||||||
80
tests/scripts/test_truthiness.toy
Normal file
80
tests/scripts/test_truthiness.toy
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
//booleans
|
||||||
|
{
|
||||||
|
var value: bool = true;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
print "boolean";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert false, "boolean";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var value: bool = false;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
assert false, "boolean";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "boolean";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//integers
|
||||||
|
{
|
||||||
|
var value: int = 42;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
print "integer";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert false, "integer";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var value: int = 0;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
assert false, "integer";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "integer";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//floats
|
||||||
|
{
|
||||||
|
var value: float = 42.8891;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
print "float";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert false, "float";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var value: float = 0;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
assert false, "float";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "float";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//everything else
|
||||||
|
{
|
||||||
|
var value: string = "foobar";
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
print "string";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert false, "string";
|
||||||
|
}
|
||||||
|
}
|
||||||
160
tests/scripts/test_variables.toy
Normal file
160
tests/scripts/test_variables.toy
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
//declare a variable with an initial value
|
||||||
|
var answer = 42;
|
||||||
|
|
||||||
|
//declare a variable without an initial value
|
||||||
|
var empty;
|
||||||
|
|
||||||
|
//assign a previously existing variable
|
||||||
|
answer = 6 * 9;
|
||||||
|
|
||||||
|
//access a variable
|
||||||
|
answer = answer + 1;
|
||||||
|
|
||||||
|
//compound assignments
|
||||||
|
answer += 5;
|
||||||
|
answer -= 5;
|
||||||
|
answer *= 9;
|
||||||
|
answer /= 2;
|
||||||
|
answer %= 10;
|
||||||
|
|
||||||
|
//equality checks
|
||||||
|
print 1 == 1; //true
|
||||||
|
print 1 != 1; //false
|
||||||
|
|
||||||
|
//comparison checks
|
||||||
|
print 1 < 2; //true
|
||||||
|
|
||||||
|
print "foo" > "bar"; //true
|
||||||
|
|
||||||
|
print 1 < 2; //true
|
||||||
|
print 1 > 2; //false
|
||||||
|
|
||||||
|
print 2 <= 2; //true
|
||||||
|
print 2 >= 2; //true
|
||||||
|
|
||||||
|
print 1 <= 2; //true
|
||||||
|
print 1 >= 2; //false
|
||||||
|
|
||||||
|
//logical checks
|
||||||
|
print true && true; //true
|
||||||
|
print true && false; //false
|
||||||
|
print false && true; //false
|
||||||
|
print false && false; //false
|
||||||
|
|
||||||
|
print true || true; //true
|
||||||
|
print true || false; //true
|
||||||
|
print false || true; //true
|
||||||
|
print false || false; //false
|
||||||
|
|
||||||
|
print !true; //false
|
||||||
|
print !false; //true
|
||||||
|
|
||||||
|
//logical AND short-circuits and chained assignments
|
||||||
|
{
|
||||||
|
var a = 1;
|
||||||
|
var b = 2;
|
||||||
|
var c = a + 1 && b + 2;
|
||||||
|
|
||||||
|
assert a == 1, "short circuit 1.1";
|
||||||
|
assert b == 2, "short circuit 1.2";
|
||||||
|
assert c == 4, "short circuit 1.3";
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var a = 1;
|
||||||
|
var b = 2;
|
||||||
|
var c = a = (a + 1) && b + 2;
|
||||||
|
|
||||||
|
assert a == 4, "short circuit 2.1";
|
||||||
|
assert b == 2, "short circuit 2.2";
|
||||||
|
assert c == 4, "short circuit 2.3";
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var a = 1;
|
||||||
|
var b = 2;
|
||||||
|
var c = a = a + 1 && b + 2;
|
||||||
|
|
||||||
|
assert a == 4, "short circuit 3.1";
|
||||||
|
assert b == 2, "short circuit 3.2";
|
||||||
|
assert c == 4, "short circuit 3.3";
|
||||||
|
}
|
||||||
|
|
||||||
|
//logical OR short-circuits and chained assignments
|
||||||
|
{
|
||||||
|
var a = 1;
|
||||||
|
var b = 2;
|
||||||
|
var c = a + 1 || b + 2;
|
||||||
|
|
||||||
|
assert a == 1, "short circuit 4.1";
|
||||||
|
assert b == 2, "short circuit 4.2";
|
||||||
|
assert c == 2, "short circuit 4.3";
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var a = 1;
|
||||||
|
var b = 2;
|
||||||
|
var c = a = (a + 1) || b + 2;
|
||||||
|
|
||||||
|
assert a == 2, "short circuit 5.1";
|
||||||
|
assert b == 2, "short circuit 5.2";
|
||||||
|
assert c == 2, "short circuit 5.3";
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
var a = 1;
|
||||||
|
var b = 2;
|
||||||
|
var c = a = a + 1 || b + 2;
|
||||||
|
|
||||||
|
assert a == 2, "short circuit 6.1";
|
||||||
|
assert b == 2, "short circuit 6.2";
|
||||||
|
assert c == 2, "short circuit 6.3";
|
||||||
|
}
|
||||||
|
|
||||||
|
//types
|
||||||
|
{
|
||||||
|
var a: int;
|
||||||
|
var b: int = 42;
|
||||||
|
|
||||||
|
a = 69;
|
||||||
|
b = 8891;
|
||||||
|
|
||||||
|
print a;
|
||||||
|
print b;
|
||||||
|
}
|
||||||
|
|
||||||
|
//constants
|
||||||
|
{
|
||||||
|
var c: int const = 42;
|
||||||
|
print c;
|
||||||
|
}
|
||||||
|
|
||||||
|
//indexing
|
||||||
|
{
|
||||||
|
var s = "Hello" .. "world!";
|
||||||
|
print s[3, 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
//increment & decrement (prefix)
|
||||||
|
{
|
||||||
|
var a = 42;
|
||||||
|
assert a == 42, "prefix increment & decrement 1.1";
|
||||||
|
assert ++a == 43, "prefix increment & decrement 1.2";
|
||||||
|
assert a == 43, "prefix increment & decrement 1.3";
|
||||||
|
assert --a == 42, "prefix increment & decrement 1.4";
|
||||||
|
assert a == 42, "prefix increment & decrement 1.5";
|
||||||
|
}
|
||||||
|
|
||||||
|
//increment & decrement (postfix)
|
||||||
|
{
|
||||||
|
var a = 42;
|
||||||
|
assert a == 42, "postfix increment & decrement 1.1";
|
||||||
|
assert a++ == 42, "postfix increment & decrement 1.2";
|
||||||
|
assert a == 43, "postfix increment & decrement 1.3";
|
||||||
|
assert a-- == 43, "postfix increment & decrement 1.4";
|
||||||
|
assert a == 42, "postfix increment & decrement 1.5";
|
||||||
|
|
||||||
|
print a;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: type casting
|
||||||
@@ -19,30 +19,30 @@ endif
|
|||||||
#directories
|
#directories
|
||||||
TEST_ROOTDIR=../..
|
TEST_ROOTDIR=../..
|
||||||
TEST_SOURCEDIR=$(TEST_ROOTDIR)/$(TOY_SOURCEDIR)
|
TEST_SOURCEDIR=$(TEST_ROOTDIR)/$(TOY_SOURCEDIR)
|
||||||
TEST_CASESDIR=.
|
TEST_UNITSDIR=.
|
||||||
|
|
||||||
TEST_OUTDIR=out
|
TEST_OUTDIR=out
|
||||||
TEST_OBJDIR=obj
|
TEST_OBJDIR=obj
|
||||||
|
|
||||||
#file names
|
#file names
|
||||||
TEST_SOURCEFILES=$(wildcard $(TEST_SOURCEDIR)/*.c)
|
TEST_SOURCEFILES=$(wildcard $(TEST_SOURCEDIR)/*.c)
|
||||||
TEST_CASESFILES=$(wildcard $(TEST_CASESDIR)/test_*.c)
|
TEST_UNITSFILES=$(wildcard $(TEST_UNITSDIR)/test_*.c)
|
||||||
|
|
||||||
#build the object files, compile the test cases, and run
|
#build the object files, compile the tess, and run
|
||||||
all: build-source build-cases build-link build-run
|
all: build-source build-units build-link build-run
|
||||||
|
|
||||||
#targets for each step
|
#targets for each step
|
||||||
.PHONY: build-source
|
.PHONY: build-source
|
||||||
build-source: $(TEST_OUTDIR) $(TEST_OBJDIR) $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_SOURCEFILES:.c=.o)))
|
build-source: $(TEST_OUTDIR) $(TEST_OBJDIR) $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_SOURCEFILES:.c=.o)))
|
||||||
|
|
||||||
.PHONY: build-cases
|
.PHONY: build-units
|
||||||
build-cases: $(TEST_OUTDIR) $(TEST_OBJDIR) $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_CASESFILES:.c=.o)))
|
build-units: $(TEST_OUTDIR) $(TEST_OBJDIR) $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_UNITSFILES:.c=.o)))
|
||||||
|
|
||||||
.PHONY: build-link
|
.PHONY: build-link
|
||||||
build-link: $(TEST_OUTDIR) $(TEST_OBJDIR) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.exe)))
|
build-link: $(TEST_OUTDIR) $(TEST_OBJDIR) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_UNITSFILES:%.c=%.exe)))
|
||||||
|
|
||||||
.PHONY: build-run
|
.PHONY: build-run
|
||||||
build-run: $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.exe))) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.run)))
|
build-run: $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_UNITSFILES:%.c=%.exe))) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_UNITSFILES:%.c=%.run)))
|
||||||
|
|
||||||
#util targets
|
#util targets
|
||||||
$(TEST_OUTDIR):
|
$(TEST_OUTDIR):
|
||||||
@@ -55,8 +55,8 @@ $(TEST_OBJDIR):
|
|||||||
$(TEST_OBJDIR)/%.o: $(TEST_SOURCEDIR)/%.c
|
$(TEST_OBJDIR)/%.o: $(TEST_SOURCEDIR)/%.c
|
||||||
$(CC) -c -o $@ $< $(addprefix -I,$(TEST_SOURCEDIR)) $(CFLAGS) -fdata-sections -ffunction-sections
|
$(CC) -c -o $@ $< $(addprefix -I,$(TEST_SOURCEDIR)) $(CFLAGS) -fdata-sections -ffunction-sections
|
||||||
|
|
||||||
$(TEST_OBJDIR)/%.o: $(TEST_CASESDIR)/%.c
|
$(TEST_OBJDIR)/%.o: $(TEST_UNITSDIR)/%.c
|
||||||
$(CC) -c -o $@ $< $(addprefix -I,$(TEST_SOURCEDIR) $(TEST_CASESDIR)) $(CFLAGS) -fdata-sections -ffunction-sections
|
$(CC) -c -o $@ $< $(addprefix -I,$(TEST_SOURCEDIR) $(TEST_UNITSDIR)) $(CFLAGS) -fdata-sections -ffunction-sections
|
||||||
|
|
||||||
$(TEST_OUTDIR)/%.exe: $(TEST_OBJDIR)/%.o
|
$(TEST_OUTDIR)/%.exe: $(TEST_OBJDIR)/%.o
|
||||||
@$(CC) -o $@ $< $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_SOURCEFILES:.c=.o))) $(CFLAGS) $(LIBS) $(LDFLAGS)
|
@$(CC) -o $@ $< $(addprefix $(TEST_OBJDIR)/,$(notdir $(TEST_SOURCEFILES:.c=.o))) $(CFLAGS) $(LIBS) $(LDFLAGS)
|
||||||
@@ -66,20 +66,20 @@ $(TEST_OUTDIR)/%.run: $(TEST_OUTDIR)/%.exe
|
|||||||
$<
|
$<
|
||||||
|
|
||||||
#debugging targets
|
#debugging targets
|
||||||
gdb: build-source build-cases build-link build-run-gdb
|
gdb: build-source build-units build-link build-run-gdb
|
||||||
|
|
||||||
.PHONY: build-run-gdb
|
.PHONY: build-run-gdb
|
||||||
build-run-gdb: $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.exe))) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.run-gdb)))
|
build-run-gdb: $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_UNITSFILES:%.c=%.exe))) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_UNITSFILES:%.c=%.run-gdb)))
|
||||||
|
|
||||||
.PRECIOUS: $(TEST_OUTDIR)/%.run-gdb
|
.PRECIOUS: $(TEST_OUTDIR)/%.run-gdb
|
||||||
$(TEST_OUTDIR)/%.run-gdb: $(TEST_OUTDIR)/%.exe
|
$(TEST_OUTDIR)/%.run-gdb: $(TEST_OUTDIR)/%.exe
|
||||||
gdb $< -ix gdb_init -ex=run --batch --return-child-result --args "$<"
|
gdb $< -ix gdb_init -ex=run --batch --return-child-result --args "$<"
|
||||||
|
|
||||||
#valgrind targets
|
#valgrind targets
|
||||||
valgrind: build-source build-cases build-link build-run-valgrind
|
valgrind: build-source build-units build-link build-run-valgrind
|
||||||
|
|
||||||
.PHONY: build-run-valgrind
|
.PHONY: build-run-valgrind
|
||||||
build-run-valgrind: $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.exe))) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.run-valgrind)))
|
build-run-valgrind: $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_UNITSFILES:%.c=%.exe))) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_UNITSFILES:%.c=%.run-valgrind)))
|
||||||
|
|
||||||
.PRECIOUS: $(TEST_OUTDIR)/%.run-valgrind
|
.PRECIOUS: $(TEST_OUTDIR)/%.run-valgrind
|
||||||
$(TEST_OUTDIR)/%.run-valgrind: $(TEST_OUTDIR)/%.exe
|
$(TEST_OUTDIR)/%.run-valgrind: $(TEST_OUTDIR)/%.exe
|
||||||
|
|||||||
Reference in New Issue
Block a user