Compare commits

119 Commits

Author SHA1 Message Date
8d3e43d7dc Bump version in README.md. 2025-06-14 14:09:54 +00:00
d4293e87f3 Everything works. 2025-06-14 10:02:04 -04:00
abb8ff6b58 Finished garbage collector.
🎉
2025-06-14 09:23:49 -04:00
80122b6572 I try. 2025-05-31 19:13:26 -04:00
a4afd3b58a Fixed segfault on spacey input. 2025-05-31 18:25:11 -04:00
90c8c91410 Somethings working. 2025-05-31 18:19:04 -04:00
f5ab0e9cb0 Fixed memory leak. 2025-05-24 10:52:27 -04:00
0fb1f1d55f Began work on garbage collector. 2025-05-24 10:37:29 -04:00
1d83aa65a4 Well it mostly works now.
Fixed some memory leaks. Implemented some memory leaks.

May need to look into garbage collection in the future.
2025-05-17 11:01:20 -04:00
3f30662cde Fixed some memory bugs. 2025-05-10 10:43:36 -04:00
743d16f696 Fixed bad free on stack.
Still need to figure that one out.
2025-05-07 08:54:19 -04:00
7b99292547 Builtin functions now work with new scope. 2025-05-07 08:38:10 -04:00
4a516d8edb Updated builtin functions for scope. 2025-05-07 08:16:05 -04:00
5b0950cabb Finished linked env scope on user functions.
Doesn't work for builtin functions yet, so doesn't compile. TODO.
2025-04-26 11:04:21 -04:00
40051de9ae Fix deprecated version name.
Co-authored-by: bgiobbe-tcs <bgiobbe.tcs@gmail.com>
2025-04-26 10:58:09 -04:00
2d01b09ee9 Added scope structures.
Not yet used in exec.c.
2025-04-26 09:45:46 -04:00
ff68b756ef Updated for Scope. 2025-04-26 09:45:34 -04:00
c2f2658e9c Start removing old cursed stack frame scope code.
It never really worked anyway.
2025-04-23 13:12:03 -04:00
3e80f6430d Updated output formatting for scope. 2025-04-23 13:06:54 -04:00
5b50d423fa Updated README for new scoping system. 2025-04-14 09:07:28 -04:00
a04d318e45 Started implementing the linked env scope. 2025-04-14 08:58:41 -04:00
7258f162c9 Clean up build process and add more doc. 2025-04-12 14:36:43 -04:00
6e05f1334a Updated grammar rules for new scope system.
Need to implement scope fields still though.
2025-04-12 14:29:39 -04:00
4e66f7875a Added grammars for function definitions. 2025-04-12 09:47:34 -04:00
845a7f87b2 Updated exception execution.
Now represents a sort of traceback.
2025-03-30 17:05:29 -04:00
5b163b26dd Fixed static allocation of builting functions.
Co-authored-by: bgiobbe-tcs <bgiobbe.tcs@gmail.com>
2025-03-30 16:09:09 -04:00
f8ee7cc66e Oh boy do I love formatting. 2025-03-26 18:16:13 -04:00
d699f492fa Updated to use the builtin functions list.
Wow, the type declaration for builtin_fns[] is cursed.

Also, first commit from zed :D.
2025-03-26 18:06:17 -04:00
018404eea1 Wait why's that still there it's done already. 2025-03-25 15:07:22 -04:00
18c61d86dc Fixed crash on unknown var name. 2025-03-11 17:56:04 +09:00
eaf65697de Reformatted comments to be more consistent & clear. 2025-03-03 10:15:39 -05:00
ce6e558761 Updated README.md. 2025-02-28 13:10:19 -05:00
db6e591d77 Added back all the old functions. 2025-02-26 12:43:55 -05:00
58554e8727 Fixed some expression mishandling. 2025-02-25 08:17:17 -05:00
4b9f269938 Updated Unity. 2025-02-25 08:13:42 -05:00
3d0f534017 Plans. 2025-02-25 08:11:22 -05:00
38c6a9113c Added sub to the builtin functions. 2025-02-25 08:04:43 -05:00
109bcb3fa5 Fixed function calls on builtin.
Random pointer indirection.
2025-02-25 07:56:25 -05:00
79b60e4853 Fixed name error handling. 2025-02-25 07:52:02 -05:00
8cab531129 Fixed memory error in exception printing.
Conflation between char* & char**.
2025-02-25 07:47:08 -05:00
eb3fbca030 Some things are broken.
EVERYTHING IS BROKEN
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.
2025-02-15 11:03:51 -05:00
40b91b96bd Adds type infrastructure.
Only floats (nums) are available at the moment.
2025-02-08 11:01:56 -05:00
67f659e263 Merge branch 'master' into types. 2025-02-08 10:23:15 -05:00
b8ce193299 Scope works. 2025-02-08 10:21:22 -05:00
11401e75a7 Fixed. 2025-02-08 09:25:54 -05:00
a6be116a2d Adds test for integer arithmetic. 2025-02-07 17:33:18 -05:00
3678940537 Adds preliminary type enums. 2025-02-07 17:29:30 -05:00
cddf5eed76 Creates config.mk.
Moves a bunch of stuff clutter out of the Makefile.
2025-02-04 18:11:30 -05:00
c685d6e55f TODO.md. 2025-02-04 17:59:39 -05:00
6cbc28e092 Maybe fixed some memory leaks.
I don't know cauase lsan isn't working.
2025-02-04 17:55:47 -05:00
408a5a46c0 Can set and ref vars in main scope.
One can now assign and reference variables in the main scope, as it has
been put in a block through the parser.

Also added some tests for this purpose.
2025-02-04 17:28:06 -05:00
6903aeb383 Added Makefile rule to count LOC. 2025-02-04 17:03:55 -05:00
fbabf71d64 Variable references in blocks now work.
:D :D :D
2025-02-04 17:00:28 -05:00
78e31c3e27 Fixed block parsing for real this time.
I am such an idiot, ast_block_data_init() just ignored the given array
lol.
2025-02-04 16:50:04 -05:00
be3baee74e Fixed dlists.
Also added tests.
2025-02-04 16:40:58 -05:00
d5a07fae56 Started adding scope.
Doesn't really do anything yet as blocks aren't fully implemented.
2025-02-04 11:30:45 -05:00
4153903443 Added types example.
This is gonna be hard to implement...
2025-02-03 13:37:21 -05:00
77d58bd69e Updated STATUS.md. 2025-02-03 13:10:48 -05:00
47a3143752 Merge remote-tracking branch 'refs/remotes/origin/master' 2025-02-03 13:07:10 -05:00
4fb73b3c6f Fixed word accumulator. 2025-02-03 13:02:47 -05:00
e5c58d5fc5 Fixed tests.
Can't have spaces for some reason. Not a real fix.
2025-02-03 13:02:28 -05:00
5d81054cf6 Added variable definitions. 2025-02-03 11:28:47 -05:00
66c518fe43 Don't know why that last test is hanging.
Will fix later I guess.
2025-02-03 10:06:53 -05:00
5ecdf2d89a Sorted .gitignore again because that's important. 2025-02-01 21:38:45 -05:00
a5a86dc080 Basic blocks now work. 2025-02-01 18:40:43 -05:00
70393ef9ae Started work on blocks and the hash table. 2025-02-01 11:01:01 -05:00
efac7f7747 Added hashtable header. 2025-01-31 18:10:01 -05:00
3fcffc81ad Merge branch 'variables'. 2025-01-25 10:13:25 -05:00
27e61471a8 Fixed some things. 2025-01-25 10:12:15 -05:00
c94d7863a7 Fixed tests. 2025-01-25 09:22:31 -05:00
4dd1f2b5f1 Slightly broken. 2025-01-20 18:05:56 -05:00
1a2249a0da Fixed tests and Makefile for the last time. 2025-01-20 16:02:24 -05:00
8b01407374 Added initial support for variables.
They are now parsed correctly, though they cannot be defined manually
and all have a value of 42.42.
2025-01-20 14:47:58 -05:00
3ab2696705 Updated dstr sz. 2025-01-18 11:14:14 -05:00
0293c925d2 Fixed dstr test. 2025-01-18 11:12:07 -05:00
16d62f280f Fix Makefile assuming dirs. 2025-01-18 11:10:50 -05:00
0dbeff7077 Fix Makefile assuming dirs. 2025-01-18 11:07:46 -05:00
96038f4baa Updated README. 2025-01-18 11:05:58 -05:00
6d7ff5d43f Updated README. 2025-01-18 11:05:15 -05:00
868ee84aeb Updated README. 2025-01-18 11:01:56 -05:00
694eb43eab Bump version. 2025-01-18 10:47:10 -05:00
694d40124f Bump version. 2025-01-18 10:46:21 -05:00
39778ce08d Bump version. 2025-01-18 10:44:13 -05:00
cfd44621d5 Whoops a bit overzealous with search and replace. 2025-01-18 10:43:18 -05:00
4be71317b0 Fixed memory leaks. 2025-01-18 10:41:54 -05:00
49642553e1 Cleaned up Makefile. 2025-01-18 10:41:34 -05:00
1e11b5921d It all works! (except for mem leaks) 2025-01-18 09:42:28 -05:00
7343c3b9d9 Fixed some function parsing. 2025-01-17 11:49:51 -05:00
9e8410d4cf Parens. 2025-01-16 11:59:34 -05:00
bc0c4f33ad Cleaned up. 2025-01-14 15:11:20 -05:00
1098fa252f Added parenthesis.
Also updated some grammar rules for negatives to be more general.
2025-01-14 13:59:26 -05:00
0b1905429c Updated tests to include order of operations. 2025-01-12 20:47:24 -05:00
e7d3ea3697 Fixed testing recipe. 2025-01-12 20:47:06 -05:00
577bde6e57 Fixed list indentation. 2025-01-12 20:36:24 -05:00
60b9ed9eb2 Updated README and added STATUS. 2025-01-12 20:34:43 -05:00
d13bf883b5 Fixed some functions. 2025-01-11 11:05:26 -05:00
681e005a68 Generalized arithmetic functions
to arbitrary arguments.
2025-01-11 10:53:49 -05:00
2ce89fb39a Added arbitrary length functions. 2025-01-11 10:35:42 -05:00
907bc26264 Updated README.md. 2025-01-11 09:24:20 -05:00
e243e862ae Updated README.md. 2025-01-11 09:23:14 -05:00
5e930b9847 Updated README.
Why can't the link be in <pre>??
2025-01-09 11:43:49 -05:00
ed3ec885c0 Updated README.
OK so apparently I don't know how markdown links work...
2025-01-09 11:43:04 -05:00
835bcfe121 Updated README. 2025-01-09 11:42:25 -05:00
9432496875 Updated README. 2025-01-09 11:42:06 -05:00
0731e40e6a Fixed precedence. 2025-01-04 14:01:05 -05:00
35322de3ac Added validation tests to Makefile. 2025-01-04 10:48:01 -05:00
c3d8d6f8e5 Validation tests. 2025-01-04 10:45:34 -05:00
1f2bca5028 Not sure. 2025-01-04 10:45:11 -05:00
9a9e5cd3e0 Fixed parsing of negative numbers. 2025-01-04 09:53:39 -05:00
4d828500af Updated README. 2024-12-28 19:03:18 -05:00
deac5ca5b8 Updated README. 2024-12-28 19:02:36 -05:00
e05ebeef2a Added the ability to call infix function backend. 2024-12-28 18:59:04 -05:00
bdca40bae4 Made the infix ops call the normal functions. 2024-12-28 18:42:37 -05:00
b4cd46a1e7 Added division. 2024-12-28 18:39:33 -05:00
a57acc1176 Fixed stupid stupid GNU Make issue. 2024-12-28 12:18:36 -05:00
ffcf2fb013 Added tests for dstr. 2024-12-28 11:55:35 -05:00
c7a9c8215c Reorganized functions, consolidated. 2024-12-28 11:54:58 -05:00
ca4cf2cd68 Finished Unity test support.
Not really, it fails to build tests sometimes and I have no idea why.
2024-12-28 11:52:59 -05:00
e19fc8820a Added Unity in test. 2024-12-28 09:30:35 -05:00
52 changed files with 1994 additions and 4815 deletions

2
.gitignore vendored
View File

@@ -4,5 +4,5 @@ tags
*.out *.out
.cache .cache
build/* build/*
compile_commands.json
vgcore.* vgcore.*
compile_commands.json

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "test/Unity"]
path = test/Unity
url = https://github.com/ThrowTheSwitch/Unity

View File

@@ -1,32 +1,4 @@
NAME = scl include config.mk
TARGET = $(NAME).out
SRC_DIR = src
INC_DIR = $(SRC_DIR)/include
BUILD_DIR = build
OBJ_DIR = $(BUILD_DIR)/obj
GRAM_DIR = $(BUILD_DIR)/grammars
TEST_DIR = test
TEST_BUILD_DIR = $(BUILD_DIR)/test
TEST_OBJ_DIR = $(TEST_BUILD_DIR)/obj
CC = clang
LINK = clang
CFLAGS = -Wall -DDBG -ggdb
LDFLAGS = -lm
SRC_FILES = $(wildcard $(SRC_DIR)/*.c)
OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_FILES))
OBJ_FILES_NOMAIN = $(filter-out $(OBJ_DIR)/main.o, $(OBJ_FILES)) # Object files without main.c.
GRAM_FILES = $(GRAM_DIR)/grammar.tab.c $(GRAM_DIR)/grammar.tab.h
UNITY_C = $(TEST_DIR)/unity/unity.c
TEST_SRC_FILES = $(wildcard $(TEST_DIR)/*.c)
TEST_OBJ_FILES = $(patsubst $(TEST_DIR)/%.c, $(TEST_OBJ_DIR)/%.o, $(TEST_SRC_FILES))
RESETCOLOR = \033[0m
WHITE = $(RESETCOLOR)\033[37m
WHITE_BOLD = $(RESETCOLOR)\033[37;1m
all: $(TARGET) all: $(TARGET)
@@ -34,51 +6,72 @@ release: clean
release: CFLAGS = -Wall -O2 release: CFLAGS = -Wall -O2
release: $(TARGET) release: $(TARGET)
# Run the target.
run: $(TARGET) run: $(TARGET)
@ echo -e "$(WHITE_BOLD)Running... $(RESETCOLOR)./$(TARGET)" ./$(TARGET)
@ ./$(TARGET)
# Generate grammars with bison. # Generate grammars with bison.
$(GRAM_FILES): $(SRC_DIR)/grammar.y $(GRAM_FILES): $(SRC_DIR)/grammar.y
@ mkdir -p $(GRAM_DIR) @ mkdir -p $(GRAM_DIR)
@ echo -e "$(WHITE_BOLD)Generating grammars...$(RESETCOLOR) bison $< -o$(GRAM_DIR)/grammar.tab.c -H$(GRAM_DIR)/grammar.tab.h" @ $(PRINT) "$(WHITE_BOLD)Generating grammars...$(RESETCOLOR)"
@ bison $< -o$(GRAM_DIR)/grammar.tab.c -H$(GRAM_DIR)/grammar.tab.h $(BISON) $< -o$(GRAM_DIR)/grammar.tab.c -H$(GRAM_DIR)/grammar.tab.h
# Compile grammars. # Compile grammars.
$(OBJ_DIR)/grammar.o: $(GRAM_DIR)/grammar.tab.c $(GRAM_DIR)/grammar.tab.h $(OBJ_DIR)/lexer.o $(OBJ_DIR)/grammar.o: $(GRAM_DIR)/grammar.tab.c $(GRAM_DIR)/grammar.tab.h $(OBJ_DIR)/lexer.o
@ $(PRINT) "$(WHITE_BOLD)Compiling grammars...$(RESETCOLOR)"
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
# Lexer depends on grammars. # Lexer depends on grammars.
$(OBJ_DIR)/lexer.o: $(SRC_DIR)/lexer.c $(GRAM_FILES) $(OBJ_DIR)/lexer.o: $(SRC_DIR)/lexer.c $(GRAM_FILES)
@ mkdir -p $(OBJ_DIR) @ mkdir -p $(OBJ_DIR)
@ $(PRINT) "$(WHITE_BOLD)Compiling source object $(WHITE)$@$(WHITE_BOLD)... $(RESETCOLOR)"
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
# Compile project sources. # Compile project source objects.
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(INC_DIR)/%.h $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(INC_DIR)/%.h
@ mkdir -p $(OBJ_DIR) @ mkdir -p $(OBJ_DIR)
@ echo -e "$(WHITE_BOLD)Compiling $(WHITE)$<$(WHITE_BOLD)... $(RESETCOLOR)$(CC) $(CFLAGS) -c $< -o $@" @ $(PRINT) "$(WHITE_BOLD)Compiling source object $(WHITE)$@$(WHITE_BOLD)... $(RESETCOLOR)"
@ $(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
# Link to final binary. # Link to final binary.
$(TARGET): $(OBJ_DIR)/grammar.o $(OBJ_FILES) $(TARGET): $(OBJ_DIR)/grammar.o $(OBJ_FILES)
@ echo -e "$(WHITE_BOLD)Linking $(WHITE)$(TARGET)$(WHITE_BOLD)...$(RESETCOLOR) $(CC) -o $(TARGET) $(OBJ_FILES) $(LDFLAGS)" @ $(PRINT) "$(WHITE_BOLD)Linking $(WHITE)$@$(WHITE_BOLD)...$(RESETCOLOR)"
@ $(LINK) -o $(TARGET) $(OBJ_FILES) $(OBJ_DIR)/grammar.o $(LDFLAGS) $(LINK) -o $(TARGET) $(OBJ_FILES) $(OBJ_DIR)/grammar.o $(LDFLAGS)
# Compile test sources. # Compile Unity object.
$(TEST_OBJ_DIR)/%.o: $(TEST_DIR)/%.c $(UNITY_OBJ): $(UNITY_C) $(UNITY_H)
@ $(PRINT) "$(WHITE_BOLD)Compiling Unity...$(RESETCOLOR)"
$(CC) $(CFLAGS) -D UNITY_OUTPUT_COLOR -c $< -o $@
# Compile test object.
$(TEST_OBJ_DIR)/test_%.o: $(TEST_DIR)/test_%.c
@ mkdir -p $(TEST_OBJ_DIR) @ mkdir -p $(TEST_OBJ_DIR)
@ echo -e "$(WHITE_BOLD)Compiling Test $(WHITE)$<$(WHITE_BOLD)... $(WHITE)$(CC) $(CFLAGS) -I$(SRC_DIR)/include -c $< -o $@$(RESETCOLOR)" @ $(PRINT) "$(WHITE_BOLD)Compiling test object $(WHITE)$@$(WHITE_BOLD)...$(RESETCOLOR)"
@ $(CC) $(CFLAGS) -I$(SRC_DIR)/include -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
# Link the test executable. # Link final test binary.
test: $(TEST_OBJ_FILES) $(OBJ_FILES_NOMAIN) $(UNITY_C) $(TEST_BUILD_DIR)/test_%.out: $(TEST_OBJ_DIR)/test_%.o $(OBJ_DIR)/grammar.o $(OBJ_FILES_NOMAIN) $(UNITY_OBJ)
@ echo -e "$(WHITE_BOLD)Linking test binary$(WHITE)...$(RESETCOLOR)" @ mkdir -p $(TEST_BUILD_DIR)
@ $(LINK) -DUNITY_OUTPUT_COLOR $(TEST_OBJ_FILES) $(OBJ_FILES_NOMAIN) $(UNITY_C) -o $(TEST_BUILD_DIR)/test.out @ $(PRINT) "$(WHITE_BOLD)Linking test binary $(WHITE)$@$(WHITE_BOLD)...$(RESETCOLOR)"
@ echo -e "$(WHITE_BOLD)Running tests$(WHITE)...$(RESETCOLOR)" $(LINK) -o $@ $? $(LDFLAGS)
@ ./$(TEST_BUILD_DIR)/test.out
# Run the test files.
test: $(TARGET) $(TEST_BIN_FILES)
@ $(PRINT) "$(WHITE_BOLD)Running unit tests...$(RESETCOLOR)"
for test in $(TEST_BIN_FILES); do ./$${test} || echo -e "$(RED_BOLD) BAD EXIT ON $${test} $(RESETCOLOR)"; done
@ $(PRINT) "$(WHITE_BOLD)Running validation tests...$(RESETCOLOR)"
$(BATS) $(TEST_VAL_DIR)
# Clean out objects, binaries, and built artifacts.
clean: clean:
@ echo -e "$(WHITE_BOLD)Cleaning up...$(WHITE) $(OBJ_DIR)/*.o $(TEST_OBJ_DIR)/*.o $(TEST_BUILD_DIR)/test.out $(TARGET) $(GRAM_DIR)/* $(RESETCOLOR)" @ $(PRINT) "$(WHITE_BOLD)Cleaning up...$(RESETCOLOR)"
@ rm -rf $(OBJ_DIR)/*.o $(TEST_OBJ_DIR)/*.o $(TEST_BUILD_DIR)/test.out $(TARGET) $(GRAM_DIR)/* rm -rf $(OBJ_DIR)/*.o $(TEST_OBJ_DIR)/*.o $(TEST_BUILD_DIR)/test.out $(TARGET) $(GRAM_DIR)/* $(UNITY_OBJ)
.PHONY: all clean test nocolor release run # Get LOC.
lines:
@ wc -l $(SRC_FILES) $(INC_FILES) $(GRAM_SRC)
.PHONY: all clean test nocolor release run lines
# Run this intermediary even though make thinks it's useless.
.PRECIOUS: $(TEST_OBJ_FILES)

View File

@@ -1,15 +1,36 @@
# SCL: Simple CAS Language # SCL: Simple CAS Language
## Current State Version v1.0-beta
The following things are possible: SCL aims to be a human-friendly Computer Algebra System (CAS) inspired by
1. Floating-point numbers [maxima](https://maxima.sourceforge.io/) that feels like writing on paper. In
2. Negative numbers its current state, SCL can be used as a basic 4-function calculator with order
3. Addition of operations and local variables. The codebase is about 1,400 lines of C,
4. Subtraction including a parser, interpreter, and runtime. It uses a linked environment
5. Multiplication scoping model.
## Syntax (Planned) ## Usage
To download and run:
```bash
git clone https://git.signorovitch.org/jacob/scl -b stable && cd scl
make release
./scl.out
```
### For Development
```bash
git clone git@signorovitch.org:jacob/scl --recurse-submodules && cd scl
make all test
./scl.out
```
If you wish to run tests, make sure to run `git clone --recurse-submodules` to
include the [Unity](https://github.com/ThrowTheSwitch/Unity) test framework.
## Syntax
As one would expect, you can evaluate simple infix expressions: As one would expect, you can evaluate simple infix expressions:
@@ -18,12 +39,30 @@ As one would expect, you can evaluate simple infix expressions:
= 2 = 2
``` ```
You can also define your own functions: You can also define your own functions and variables:
```scl ```scl
> f(x) = 2x > f(x) = 2x
> f(2) > n = 3
> f(n)
= 6
```
As SCL uses a linked environment model for scope, arguments are passed by
reference by default. If you would like to pass by value (i.e., a copy) you may
use the syntax:
```scl
> f(x) = x = 1
> n = 4
> f($n) # Pass a copy of n.
= 1
> n
= 4 = 4
> f(n) # Pass a reference to n.
= 1
> n
> 1
``` ```
Symbolic algebra is done in the following manner: Symbolic algebra is done in the following manner:
@@ -38,9 +77,13 @@ SCL will dynamically decide on types, but you can state them explicitly as
well: well:
```scl ```scl
> f(x:int) = 2x > f(x: int): int = 2x
> f(2.2) > f(3)
! f(x:int): x must be of type int. = 6
> f(3.1)
! Traceback:
! In call to `f(x: int): int`:
! TypeError (58): Argument `x` must be of type `int`.
``` ```
Variables can be defined, with several attributes: Variables can be defined, with several attributes:

55
STATUS.md Normal file
View File

@@ -0,0 +1,55 @@
# SCL Design Status
- [x] Data definitions
- [x] Token Definitions
- [x] AST Definitions
- [ ] Parser
- [x] Parse numbers
- [x] Parse floats
- [x] Parse negative numbers
- [x] Parse infix operators
- [x] Order of operations
- [x] Parse function application
- [x] Parse order of operations with parenthesis
- [ ] Parse variable invocation
- [x] Parse variable definition
- [ ] Parse types
- [ ] Parse function definition
- [ ] Parse lists/arrays/vectors
- [x] Parse blocks
- [ ] Parse control flow
- [ ] Parse `if` statements
- [ ] Parse `loop`s
- [ ] Parse `for` loops
- [ ] Parse `while` loops
- [ ] Parse `case` statements
- [ ] Parse `goto` statements
- [ ] Parse lambda function definition
- [ ] Parse function calling with positional arguments
- [ ] Parse variadic functions
- [ ] Parse infix function definition
- [ ] Executer
- [x] Exec function calls
- [ ] Exec variable use
- [ ] Exec variable definition
- [ ] Exec function definition
- [ ] Exec symbolic variables
- [ ] Exec control flow statements
- [ ] Exec variadic functions
- [ ] Exec lambda functions
- [ ] Exec lists
- [ ] Exec arrays
- [ ] Exec vectors
- [ ] Interface
- [ ] Interactive interpreter
- [ ] Use GNU readline
- [ ] Multi-line input
- [ ] Syntax highlighting
- [ ] Autocompletion/suggestion
- [ ] Command line interface
- [ ] Pass in a file
- [ ] Save AST to a file
- [ ] Run from AST file

7
TODO.md Normal file
View File

@@ -0,0 +1,7 @@
0. Create file to describe properties of terminology used; param, arg, var, &c.
1. Differenciate parameters and arguments -- params for function definitions,
arguments for function calls
2. Add scope field to all ASTs, and new scope layer for those that need it.
Change editor to GNU Readline.
Make variables persist through lines in the editor.

40
config.mk Normal file
View File

@@ -0,0 +1,40 @@
NAME = scl
TARGET = $(NAME).out
SRC_DIR = src
INC_DIR = $(SRC_DIR)/include
BUILD_DIR = build
OBJ_DIR = $(BUILD_DIR)/obj
GRAM_DIR = $(BUILD_DIR)/grammars
TEST_DIR = test
TEST_BUILD_DIR = $(BUILD_DIR)/test
TEST_OBJ_DIR = $(TEST_BUILD_DIR)/obj
CC = clang -std=c23
LINK = clang
CFLAGS = -Wall -DDBG -ggdb -fsanitize=leak
LDFLAGS = -lm
BATS = bats
BISON = bison
PRINT = echo -e
SRC_FILES = $(wildcard $(SRC_DIR)/*.c)
INC_FILES = $(wildcard $(INC_DIR)/*.h)
OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_FILES))
OBJ_FILES_NOMAIN = $(filter-out $(OBJ_DIR)/main.o, $(OBJ_FILES)) # Object files without main.c.
GRAM_SRC = $(SRC_DIR)/grammar.y
GRAM_FILES = $(GRAM_DIR)/grammar.tab.c $(GRAM_DIR)/grammar.tab.h
UNITY_DIR = $(TEST_DIR)/Unity
UNITY_C = $(UNITY_DIR)/src/unity.c
UNITY_H = $(UNITY_DIR)/src/unity.h
UNITY_OBJ = $(TEST_BUILD_DIR)/unity.o
TEST_SRC_FILES = $(wildcard $(TEST_DIR)/*.c)
TEST_OBJ_FILES = $(patsubst $(TEST_DIR)/%.c, $(TEST_OBJ_DIR)/%.o, $(TEST_SRC_FILES))
TEST_BIN_FILES = $(patsubst $(TEST_DIR)/%.c, $(TEST_BUILD_DIR)/%.out, $(TEST_SRC_FILES))
TEST_VAL_DIR = $(TEST_DIR)/val
RESETCOLOR = \033[0m
WHITE = $(RESETCOLOR)\033[37m
WHITE_BOLD = $(RESETCOLOR)\033[37;1m
RED_BOLD = $(RESETCOLOR)\033[31;1m

3
examples/function.scl Normal file
View File

@@ -0,0 +1,3 @@
f(n) = 2 * n
f(5)

48
examples/types.scl Normal file
View File

@@ -0,0 +1,48 @@
# Vectors
# - Must have fixed size and type
# Lists
# - Variable size, variable type
# Define a variable of type int:
n: int = 3
# Define v as a 3-dimensional vector of integers:
v: int<3> = <4, 5, 6>
# Define l as list of length 3:
l: [3] = [1, 2, "These can be any type at all"]
# This would also work, as length values for lists are optional (and mutable),
# unlike vectors:
l: [] = [1, 2, "whatever"]
# This is also the same, being more explicit about the any type:
l: any[] = [1, 2, "whatever"]
# This must be a list of integers, however:
l: int[] = [1, 2, 3]
# Define a list of either integers or strings:
l: union(int, str)[] = ["hello", 4, "world"]
# union() is a complex type generator; "returns" a union of the int and str types.
# Use vectors wherever possible, as they are much faster than lists.
# Matrix
# - Must have a fixed size and type (just like vectors)
m: int<2, 2> = <<0, 1>, <2, 3>>
# Can also be written as
m: int<2, 2> = <<0, 1, 2, 3>>
# When using this syntax, will fill remaining space with default value of type
# to make data rectangular. E.g., to fill a 2 x 2 matrix with 0:
m: int<2, 2> = <<>>
# To define custom data types, e.g. structs:
typedef(Vec2, struct( a: int, b: int ))
vector_two: Vec2 = Vec2(2, 3)
typedef(IntOrStr, union(str, int))
one: IntOrStr = 1
alsoOne: IntOrStr = "one"
# To define custom data types with type arguments:
typedef(Vec1Of(T), T<1>)
hello: Vec1Of(str) = <"Hello">

279
src/ast.c
View File

@@ -1,21 +1,48 @@
#include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include "include/ast.h" #include "include/ast.h"
#include "include/dstr.h" #include "include/dstr.h"
#include "include/gc.h"
#include "include/scope.h"
#include "include/util.h" #include "include/util.h"
extern AST* root; extern AST* root;
static char* asttype_names[] = { static char* asttype_names[] = {
[AST_TYPE_CALL] = "CALL", [AST_TYPE_CALL] = "FUNC CALL",
[AST_TYPE_NUM] = "NUMBER", [AST_TYPE_NUM] = "NUMBER",
[AST_TYPE_VREF] = "VAR REFERENCE",
[AST_TYPE_VDEF] = "VAR DEFINITION",
[AST_TYPE_BLOCK] = "BLOCK",
[AST_TYPE_EXC] = "EXCEPTION",
[AST_TYPE_FDEF] = "FUNCTION DEFINITION",
[AST_TYPE_ARG] = "DEFINITION ARGUMENT"
}; };
AST* ast_init(ASTType type, void* data) { AST* ast_init(ASTType type, void* data) {
AST* ast = gc_alloc(sizeof(AST), GC_TYPE_AST);
ast->type = type;
ast->data = data;
ast->scope = NULL;
if (ast->type > AST_TYPE_MAX) {
log_dbgf(
"Attempted to create invalid AST (%i > %i) to GC: ast:%p",
ast->type, AST_TYPE_MAX, ast
);
}
return ast;
}
AST* ast_init_scope(ASTType type, void* data, Scope* scope) {
AST* ast = malloc(sizeof(AST)); AST* ast = malloc(sizeof(AST));
ast->type = type; ast->type = type;
ast->data = data; ast->data = data;
ast->scope = scope;
return ast; return ast;
} }
@@ -24,27 +51,67 @@ void ast_destroy(AST* ast) {
if (!ast) return; if (!ast) return;
switch (ast->type) { switch (ast->type) {
case AST_TYPE_NUM: ast_num_data_destroy(ast->data); break; case AST_TYPE_NUM: ast_num_data_destroy(ast->data); break;
case AST_TYPE_CALL: ast_call_data_destroy(ast->data); break; case AST_TYPE_CALL: ast_call_data_destroy(ast->data); break;
case AST_TYPE_VREF: ast_vref_data_destroy(ast->data); break;
case AST_TYPE_VDEF: ast_vdef_data_destroy(ast->data); break;
case AST_TYPE_BLOCK: ast_block_data_destroy(ast->data); break;
case AST_TYPE_FDEF: ast_fdef_data_destroy(ast->data); break;
case AST_TYPE_ARG: ast_arg_data_destroy(ast->data); break;
default: default:
log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX); log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX);
} }
// If there're no more `AST`s linked to the scope, free.
if (ast->scope && !--ast->scope->uses) scope_destroy_psv(ast->scope);
free(ast);
} }
void ast_print(AST* ast) { ast_print_i(ast, 0); } void ast_destroy_psv(AST* ast) {
if (!ast) return;
switch (ast->type) {
case AST_TYPE_NUM: ast_num_data_destroy(ast->data); break;
case AST_TYPE_CALL: ast_call_data_destroy_psv(ast->data); break;
case AST_TYPE_VREF: ast_vref_data_destroy(ast->data); break;
case AST_TYPE_VDEF: ast_vdef_data_destroy_psv(ast->data); break;
case AST_TYPE_BLOCK: ast_block_data_destroy_psv(ast->data); break;
case AST_TYPE_FDEF: ast_fdef_data_destroy_psv(ast->data); break;
case AST_TYPE_ARG: ast_arg_data_destroy(ast->data); break;
case AST_TYPE_BIF: ast_bif_data_destroy(ast->data); break;
case AST_TYPE_EXC: ast_exc_data_destroy(ast->data); break;
default:
log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX);
}
free(ast);
}
void ast_print(AST* ast) {
if (!ast) return;
ast_print_i(ast, 0);
}
void ast_print_i(AST* ast, int i) { void ast_print_i(AST* ast, int i) {
INDENT_BEGIN(i); INDENT_BEGIN(i);
INDENT_TITLE("AST", ast); INDENT_TITLE("AST", ast);
INDENT_FIELD("type", "%s", asttype_names[ast->type]); INDENT_FIELD("type", "%s", asttype_names[ast->type]);
INDENT_FIELD("scope", "%p", ast->scope);
INDENT_FIELD_EXT_NONL_START("data"); INDENT_FIELD_EXT_NONL_START("data");
switch (ast->type) { switch (ast->type) {
case AST_TYPE_NUM: case AST_TYPE_NUM:
printf("%s %lf\n", INDENT_spacing->buf, *(ASTNumData*)ast->data); printf("%s %lf\n", INDENT_spacing->buf, *(ASTNumData*)ast->data);
break; break;
case AST_TYPE_CALL: ast_call_print(ast->data, i + 2); break; case AST_TYPE_CALL: ast_call_print(ast->data, i + 2); break;
default: exit(1); case AST_TYPE_EXC: ast_exc_print(ast->data, i + 2); break;
case AST_TYPE_VREF: ast_vref_print(ast->data, i + 2); break;
case AST_TYPE_VDEF: ast_vdef_print(ast->data, i + 2); break;
case AST_TYPE_BLOCK: ast_block_print(ast->data, i + 2); break;
case AST_TYPE_FDEF: ast_fdef_print(ast->data, i + 2); break;
case AST_TYPE_ARG: ast_arg_print(ast->data, i + 2); break;
default: exit(1);
} }
INDENT_FIELD_NONL_END; INDENT_FIELD_NONL_END;
INDENT_END; INDENT_END;
@@ -53,16 +120,12 @@ void ast_print_i(AST* ast, int i) {
ASTNumData* ast_num_data_init(double val) { ASTNumData* ast_num_data_init(double val) {
talloc(ASTNumData, num); talloc(ASTNumData, num);
log_dbgf("val: %lf", val);
*num = val; *num = val;
return num; return num;
} }
void ast_num_data_destroy(ASTNumData* num) { void ast_num_data_destroy(ASTNumData* num) { free(num); }
if (!num) return free(num);
}
void ast_num_print(ASTNumData* data, int i) { void ast_num_print(ASTNumData* data, int i) {
INDENT_BEGIN(i); INDENT_BEGIN(i);
@@ -72,6 +135,39 @@ void ast_num_print(ASTNumData* data, int i) {
INDENT_END; INDENT_END;
} }
ASTExcData* ast_exc_data_init(const char* msg, AST* trace) {
ASTExcData* data = malloc(sizeof(ASTExcData));
data->msg = msg;
data->trace = trace;
return data;
}
void ast_exc_data_destroy(ASTExcData* exc) {
// `msg` is static, and `trace` will get freed in GC.
free(exc);
}
void ast_exc_print(ASTExcData* data, int i) {
INDENT_BEGIN(i);
INDENT_TITLE("ASTExcData", data);
INDENT_FIELD("msg", "\"%s\"", data->msg);
if (data->trace == NULL) {
INDENT_FIELD("trace", "%p", NULL)
} else {
INDENT_FIELD_EXT_NONL_START("trace");
ast_print_i(data->trace, i + 1);
INDENT_FIELD_NONL_END;
}
INDENT_END;
}
ASTBIFData* ast_bif_data_init(AST* fn(size_t, AST**, Scope*)) {
return (ASTBIFData*)fn;
}
void ast_bif_data_destroy(ASTBIFData* bif) { return; }
ASTCallData* ast_call_data_init(char* to, size_t argc, AST** argv) { ASTCallData* ast_call_data_init(char* to, size_t argc, AST** argv) {
talloc(ASTCallData, call); talloc(ASTCallData, call);
@@ -85,8 +181,19 @@ ASTCallData* ast_call_data_init(char* to, size_t argc, AST** argv) {
} }
void ast_call_data_destroy(ASTCallData* call) { void ast_call_data_destroy(ASTCallData* call) {
if (!call) return free(call->to); if (!call) return;
for (size_t i = 0; i < call->argc; i++) free(call->argv[i]); free(call->to);
for (size_t i = 0; i < call->argc; i++) ast_destroy(call->argv[i]);
free(call->argv);
free(call);
}
void ast_call_data_destroy_psv(ASTCallData* call) {
if (!call) return;
free(call->to);
call->to = NULL;
free(call->argv);
call->argv = NULL;
free(call); free(call);
} }
@@ -100,3 +207,149 @@ void ast_call_print(ASTCallData* data, int i) {
INDENT_END; INDENT_END;
} }
ASTVDefData* ast_vdef_data_init(char* name, AST* val) {
talloc(ASTVDefData, vdef);
vdef->name = name;
vdef->val = val;
return vdef;
}
void ast_vdef_data_destroy(ASTVDefData* vdef) {
ast_destroy(vdef->val);
free(vdef->name);
free(vdef);
}
void ast_vdef_data_destroy_psv(ASTVDefData* vdef) {
free(vdef->name);
free(vdef);
}
void ast_vdef_print(ASTVDefData* vdef, int depth) {
INDENT_BEGIN(depth);
INDENT_TITLE("ASTVDefData", vdef);
INDENT_FIELD("name", "%s", vdef->name);
INDENT_FIELD_EXT_NONL_START("val");
ast_print_i(vdef->val, depth + 2); // 2 because already indented.
INDENT_FIELD_NONL_END;
INDENT_END;
}
ASTVrefData* ast_vref_data_init(char* to) {
talloc(ASTVrefData, vref);
vref->to = to;
return vref;
}
void ast_vref_data_destroy(ASTVrefData* vref) {
free(vref->to);
free(vref);
}
void ast_vref_print(ASTVrefData* data, int i) {
INDENT_BEGIN(i);
INDENT_TITLE("ASTVrefData", data);
INDENT_FIELD("to", "%s", data->to);
INDENT_END;
}
ASTBlockData* ast_block_data_init(AST** inside, size_t ln) {
ASTBlockData* block = malloc(sizeof(ASTBlockData));
block->inside = inside;
block->ln = ln;
return block;
}
void ast_block_data_destroy(ASTBlockData* block) {
for (size_t i = 0; i < block->ln; i++) { ast_destroy(block->inside[i]); }
free(block->inside);
free(block);
}
void ast_block_data_destroy_psv(ASTBlockData* block) {
free(block->inside);
free(block);
}
void ast_block_print(ASTBlockData* data, int depth) {
INDENT_BEGIN(depth);
INDENT_TITLE("ASTBlockData", data);
INDENT_FIELD("ln", "%ld", data->ln);
INDENT_FIELD_LIST("inside", data->inside, data->ln, ast_print_i);
INDENT_END;
}
ASTFDefData*
ast_fdef_data_init(char* name, size_t argc, AST** argv, AST* body) {
ASTFDefData* fdef = malloc(sizeof(ASTFDefData));
fdef->name = name;
fdef->argc = argc;
fdef->argv = argv;
fdef->body = body;
return fdef;
}
void ast_fdef_data_destroy(ASTFDefData* fdef) {
free(fdef->name);
for (int i = 0; i < fdef->argc; ast_destroy(fdef->argv[i++]));
ast_destroy(fdef->body);
}
void ast_fdef_data_destroy_psv(ASTFDefData* fdef) {
free(fdef->name);
free(fdef->argv);
free(fdef);
}
void ast_fdef_print(ASTFDefData* fdef, int i) {
INDENT_BEGIN(i)
INDENT_TITLE("ASTFDefData", fdef);
INDENT_FIELD("name", "%s", fdef->name);
INDENT_FIELD("argc", "%ld", fdef->argc);
INDENT_FIELD_LIST("argv", fdef->argv, fdef->argc, ast_print_i);
INDENT_FIELD_EXT_NONL_START("body");
ast_print_i(fdef->body, i + 2);
INDENT_FIELD_NONL_END;
INDENT_END;
}
ASTArgData* ast_arg_data_init(char* name) {
ASTArgData* arg = malloc(sizeof(ASTArgData));
arg->name = name;
return arg;
}
void ast_arg_data_destroy(ASTArgData* arg) { free(arg->name); }
void ast_arg_print(ASTArgData* arg, int i) {
INDENT_BEGIN(i);
INDENT_TITLE("ASTArgData", arg);
INDENT_FIELD("name", "%s", arg->name);
INDENT_END;
}
AST* ast_find(Scope* scope, char* name) {
while (scope) {
AST* gotten = htab_get(scope->here, name);
if (gotten) return gotten;
else scope = scope->inherit;
}
return NULL;
}

133
src/builtin.c Normal file
View File

@@ -0,0 +1,133 @@
#include "include/builtin.h"
#include "include/ast.h"
#include "include/exec.h"
#include "include/util.h"
#include <stdarg.h>
#include <stdio.h>
AST* builtin_sum(size_t argc, AST** argv, Scope* parent) {
ASTNumData total = 0;
for (int i = 0; i < argc; i++) {
AST* arg = exec_exp(argv[i], parent);
if (arg->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`sum` encountered an exception.", arg)
);
if (arg->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("Sum can't sum some non-num arguments.", NULL)
);
total += *(ASTNumData*)arg->data;
}
return ast_init(AST_TYPE_NUM, ast_num_data_init(total));
}
AST* builtin_sub(size_t argc, AST** argv, Scope* parent) {
log_dbg("Got here");
AST* first = exec_exp(*argv, parent);
if (first->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`sub` encountered an exception.", first)
);
if (first->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("Can't subtract non-num arguments.", NULL)
);
ASTNumData total = *(ASTNumData*)first->data;
for (int i = 1; i < argc; i++) {
AST* arg = exec_exp(argv[i], parent);
if (arg->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`sub` encountered an exception.", arg)
);
if (arg->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("Can't subtract non-num arguments.", NULL)
);
total -= *(ASTNumData*)arg->data;
}
return ast_init(AST_TYPE_NUM, ast_num_data_init(total));
}
AST* builtin_mul(size_t argc, AST** argv, Scope* parent) {
log_dbg("Got here");
AST* first = exec_exp(*argv, parent);
if (first->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`mul` encountered an expection.", first)
);
if (first->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("Can't multiply non-num arguments.", NULL)
);
ASTNumData total = *(ASTNumData*)first->data;
for (int i = 1; i < argc; i++) {
AST* arg = exec_exp(argv[i], parent);
if (arg->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`mul` encountered an execption.", arg)
);
if (arg->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("Can't multiply non-num arguments.", NULL)
);
total *= *(ASTNumData*)arg->data;
}
return ast_init(AST_TYPE_NUM, ast_num_data_init(total));
}
AST* builtin_div(size_t argc, AST** argv, Scope* parent) {
log_dbg("Got here");
AST* first = exec_exp(*argv, parent);
if (first->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`div` encountered an exception.", first)
);
if (first->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("Can't divide non-num arguments.", NULL)
);
ASTNumData total = *(ASTNumData*)first->data;
for (int i = 1; i < argc; i++) {
AST* arg = exec_exp(argv[i], parent);
if (arg->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("`div` encountered an exception.", arg)
);
if (arg->type != AST_TYPE_NUM)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("Can't divide non-num arguments.", NULL)
);
total /= *(ASTNumData*)arg->data;
}
return ast_init(AST_TYPE_NUM, ast_num_data_init(total));
}

44
src/dlist.c Normal file
View File

@@ -0,0 +1,44 @@
#include "include/dlist.h"
#include "include/util.h"
#include <stddef.h>
#include <stdio.h>
DList* dlist_init(void) {
DList* dlist = malloc(sizeof(DList));
dlist->sz = DLIST_INITSZ;
dlist->buf = malloc(DLIST_INITSZ);
dlist->ln = 0;
return dlist;
}
void dlist_destroy(DList* dlist) {
free(dlist->buf);
free(dlist);
}
void dlist_destroypsv(DList* dlist) { free(dlist); }
// Check whether the buffer is about to overflow and resize it if necessary.
void dlist_check_resz(DList* dlist) {
while ((dlist->ln + 1) * sizeof(void*) >= dlist->sz) {
// Double the buffer size when overflown.
dlist->sz *= 2;
dlist->buf = realloc(dlist->buf, dlist->sz);
log_dbgf(
"dlist @ %p doubled from %ld to %ld", dlist, dlist->sz / 2,
dlist->sz
);
}
}
void dlist_append(DList* dest, void* src) {
dlist_check_resz(dest);
log_dbgf("added %p to dlist@%p", src, dest);
dest->buf[dest->ln] = src;
dest->ln++;
}

View File

@@ -1,13 +1,14 @@
#include "include/dstr.h" #include "include/dstr.h"
#include "include/util.h" #include "include/util.h"
#include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
Dstr* dstr_init(void) { Dstr* dstr_init(void) {
Dstr* dstr = malloc(sizeof(Dstr)); Dstr* dstr = malloc(sizeof(Dstr));
dstr->bufsz = DSTR_INITSZ; dstr->sz = DSTR_INITSZ;
dstr->buf = malloc(DSTR_INITSZ); dstr->buf = malloc(DSTR_INITSZ);
*dstr->buf = '\0'; *dstr->buf = '\0';
dstr->ln = 0; dstr->ln = 0;
@@ -20,16 +21,22 @@ void dstr_destroy(Dstr* dstr) {
free(dstr); free(dstr);
} }
void dstr_append(Dstr* dest, char* src, size_t ln) { void dstr_destroypsv(Dstr* dstr) { free(dstr); }
while (dest->ln + ln + 1 > dest->bufsz) {
// Check whether the buffer is overflowing and resize it if necessary.
void dstr_check_resz(Dstr* dstr, size_t ln) {
while (dstr->ln + ln + 1 > dstr->sz) {
// Double the buffer size when overflown. // Double the buffer size when overflown.
dest->bufsz *= 2; dstr->sz *= 2;
dest->buf = realloc(dest->buf, dest->bufsz); dstr->buf = realloc(dstr->buf, dstr->sz);
log_dbgf( log_dbgf(
"dstr @ %p doubled from %ld to %ld", dest, dest->bufsz / 2, "dstr @ %p doubled from %ld to %ld", dstr, dstr->sz / 2, dstr->sz
dest->bufsz
); );
} }
}
void dstr_append(Dstr* dest, char* src, size_t ln) {
dstr_check_resz(dest, ln);
// Overwrites the \0 at the end of the string, keeps the null from the given // Overwrites the \0 at the end of the string, keeps the null from the given
// string. // string.
@@ -38,15 +45,7 @@ void dstr_append(Dstr* dest, char* src, size_t ln) {
} }
void dstr_appendch(Dstr* dest, char ch) { void dstr_appendch(Dstr* dest, char ch) {
if (dest->ln + 1 + 1 > dest->bufsz) { dstr_check_resz(dest, 1);
// Double the buffer size when overflown.
dest->bufsz *= 2;
dest->buf = realloc(dest->buf, dest->bufsz);
log_dbgf(
"dstr @ %p doubled from %ld to %ld", dest, dest->bufsz / 2,
dest->bufsz
);
}
// Overwrites the preexisting null terminator, and adds one of its own. // Overwrites the preexisting null terminator, and adds one of its own.
dest->buf[dest->ln] = ch; dest->buf[dest->ln] = ch;

View File

@@ -1,44 +1,158 @@
#include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "include/ast.h" #include "include/ast.h"
#include "include/builtin.h"
#include "include/dlist.h"
#include "include/exec.h" #include "include/exec.h"
#include "include/htab.h"
#include "include/scope.h"
#include "include/util.h" #include "include/util.h"
extern AST* root; AST* exec_start(AST* ast) {
ASTNumData exec_expr(AST* ast) {
// ast_print(ast);
log_dbg("Started execution."); log_dbg("Started execution.");
if (!ast) return ast;
Scope* global = scope_init(NULL);
global->uses = 1;
for (int i = 0; i < BUILTIN_FNS_LN; i++)
htab_ins(
global->here, BUILTIN_FNS[i].name,
ast_init(AST_TYPE_BIF, ast_bif_data_init(BUILTIN_FNS[i].fn))
);
log_dbg("Completed startup sequence.");
AST* res = exec_exp(ast, global);
return res;
}
AST* exec_exp(AST* ast, Scope* parent) {
switch (ast->type) { switch (ast->type) {
case AST_TYPE_CALL: return exec_call(ast); case AST_TYPE_BLOCK: return exec_block(ast, parent);
case AST_TYPE_NUM: return *(ASTNumData*)ast->data; case AST_TYPE_CALL: return exec_call(ast, parent);
default: printf("what\n"); case AST_TYPE_NUM:
return ast_init(
AST_TYPE_NUM, ast_num_data_init(*(ASTNumData*)ast->data)
);
case AST_TYPE_VREF: return exec_vref(ast, parent);
case AST_TYPE_VDEF: return exec_vdef(ast, parent);
case AST_TYPE_FDEF: return exec_fdef(ast, parent);
default: printf("what\n"); exit(1);
} }
} }
ASTNumData exec_call(AST* ast) { AST* exec_block(AST* ast, Scope* parent) {
ASTBlockData* block = (ASTBlockData*)ast->data;
exec_new_scope(ast, parent);
// Loop through all but last ast.
for (int i = 0; i < block->ln - 1; i++)
exec_exp(block->inside[i], ast->scope);
AST* last = exec_exp(block->inside[block->ln - 1], ast->scope);
return last;
}
AST* exec_call(AST* ast, Scope* parent) {
log_dbg("Started call execution."); log_dbg("Started call execution.");
fflush(stdout); ASTCallData* data = (ASTCallData*)ast->data;
ASTCallData* calldata = (ASTCallData*)ast->data; size_t argc = data->argc;
if (!strcmp(calldata->to, "+") && calldata->argc == 2) { AST** argv = data->argv;
char* fname = data->to;
ASTNumData n1 = exec_expr(calldata->argv[0]); ast->scope = parent;
ASTNumData n2 = exec_expr(calldata->argv[1]);
return n1 + n2; AST* fdef = ast_find(ast->scope, fname);
} else if (!strcmp(calldata->to, "-") && calldata->argc == 2) {
ASTNumData n1 = exec_expr(calldata->argv[0]);
ASTNumData n2 = exec_expr(calldata->argv[1]);
return n1 - n2; if (fdef == NULL)
} else if (!strcmp(calldata->to, "*") && calldata->argc == 2) { return ast_init(
ASTNumData n1 = exec_expr(calldata->argv[0]); AST_TYPE_EXC, ast_exc_data_init("No such function found.", NULL)
ASTNumData n2 = exec_expr(calldata->argv[1]); );
return n1 * n2; switch (fdef->type) {
case AST_TYPE_BIF:
ASTBIFData bifdata = fdef->data;
return bifdata(argc, argv, parent);
case AST_TYPE_FDEF: return exec_cf(fdef, argc, argv);
default:
return ast_init(AST_TYPE_EXC, ast_exc_data_init("Good job!", NULL));
} }
return -1000; }
AST* exec_cf(AST* ast, size_t argc, AST** argv) {
Scope* callscope = scope_init(ast->scope);
ASTFDefData* fdef = (ASTFDefData*)ast->data;
for (int i = 0; i < argc; i++) {
char* key = ((ASTArgData*)fdef->argv[i]->data)->name;
AST* val = argv[i];
scope_add(callscope, key, val);
}
return exec_exp(fdef->body, callscope);
}
AST* exec_vdef(AST* ast, Scope* parent) {
// Use parent's scope.
exec_inherit_scope(ast, parent);
ASTVDefData* data = (ASTVDefData*)ast->data;
AST* val = data->val;
char* key = data->name;
scope_add(parent, key, val); // Add variable definition to parent scope.
return exec_exp(val, parent);
}
AST* exec_vref(AST* ast, Scope* parent) {
// Use parent's scope.
exec_inherit_scope(ast, parent);
log_dbg("attempting to reference var");
ASTVrefData* vref = (ASTVrefData*)ast->data;
AST* found = ast_find(parent, vref->to);
if (found == NULL) {
// TODO: Better memory management here.
static char msg[256];
snprintf(
msg, sizeof(msg), "Could not find value in scope for `%s`.",
vref->to
);
return ast_init(AST_TYPE_EXC, ast_exc_data_init(msg, NULL));
}
return exec_exp(found, ast->scope);
}
AST* exec_fdef(AST* ast, Scope* parent) {
ast->scope = scope_init(parent);
ASTFDefData* fdef = (ASTFDefData*)ast->data;
log_dbgf("IS THIS SUSPICIOUS??? %i", fdef->body->type);
AST* val = ast;
char* key = fdef->name;
scope_add(parent, key, val);
// TODO: Create lambda functions.
return fdef->body; // Function definitions return function body.
} }
void exec_print(double n) { printf("= %lf\n", n); } void exec_print(double n) { printf("= %lf\n", n); }
inline void exec_new_scope(AST* ast, Scope* inherit) {
Scope* scope = scope_init(inherit);
ast->scope = scope;
// Update linked status.
scope->uses++;
}
inline void exec_inherit_scope(AST* ast, Scope* inherit) {
ast->scope = inherit;
// Update uses.
inherit->uses++;
}

14
src/fnv1a.c Normal file
View File

@@ -0,0 +1,14 @@
#include "include/fnv1a.h"
#include <stdlib.h>
uint64_t fnv1a_hash(char* key, size_t ln) {
uint64_t hash = FNV1A_BASIS_64;
for (size_t i = 0; i < ln; i++) {
hash ^= (unsigned char)key[i];
hash *= FNV1A_PRIME_64;
}
return hash;
}

57
src/gc.c Normal file
View File

@@ -0,0 +1,57 @@
#include "include/gc.h"
#include "include/ast.h"
#include "include/scope.h"
#include "include/util.h"
#include <assert.h>
#include <stdio.h>
#include <stddef.h>
GC* gclist = NULL;
void gc_destroy(GC* gc) { free(gc); }
void f() {}
void* gc_alloc(size_t sz, GCType type) {
assert(type <= GC_TYPE_MAX);
void* mem = malloc(sz);
GC* gc = malloc(sizeof(GC));
gc->p = mem;
gc->type = type;
gc->marked = false;
gc->nxt = gclist;
gclist = gc;
if (type == GC_TYPE_AST) {
log_dbgf("Alloc'd AST for GC: %p", mem);
} else if (type == GC_TYPE_SCOPE) {
log_dbgf("Alloc'd scope for GC: %p", mem);
}
return mem;
}
void gc_hack_free() {
while (gclist) {
GC* gc = gclist;
gclist = gclist->nxt;
switch (gc->type) {
case GC_TYPE_AST:
f();
if (((AST*)gc->p)->type > AST_TYPE_MAX) {
log_dbgf(
"Attempted to free invalid AST (%i > %i) to GC: gc:%p "
"ast:%p",
((AST*)gc->p)->type, AST_TYPE_MAX, gc, gc->p
);
}
ast_destroy_psv(gc->p);
break;
case GC_TYPE_SCOPE: scope_destroy_psv(gc->p); break;
}
gc_destroy(gc);
}
}

6
src/global.c Normal file
View File

@@ -0,0 +1,6 @@
#include "include/global.h"
#include <stdlib.h>
// Global input text.
char* inp = NULL;

View File

@@ -1,7 +1,9 @@
%{ %{
#include <string.h>
#include <stdio.h> #include <stdio.h>
#include "../../src/include/ast.h" #include "../../src/include/ast.h"
#include "../../src/include/lexer.h" #include "../../src/include/lexer.h"
#include "../../src/include/dlist.h"
int yylex(void); int yylex(void);
void yyerror(char const*); void yyerror(char const*);
@@ -11,84 +13,190 @@
%code requires { %code requires {
#include "../../src/include/ast.h" #include "../../src/include/ast.h"
#include "../../src/include/dlist.h"
} }
%union { %union {
double fval; double fval;
char* strval; char* strval;
AST* ast; AST* ast;
ArgArr* argarr;
DList* exps;
} }
%define parse.error verbose %define parse.error verbose
%token<strval> CALL %token BLOCKS // Block start {.
%token<fval> NUM %token BLOCKE // Block end }.
%token NEG %token GROUPS // Group start (.
%token PLUS %token GROUPE // Group end ).
%token MULT %token SEP // Seperator ,.
%token NL %token EQ // Equals =.
%type<ast> exp
%token EXPSEP // Expression seperator ;.
%token<strval> WORD // Word, i.e. keyword.
%token<fval> NUM // Number.
%token SUB // Subtract -.
%token ADD // Addition *.
%token MUL // Multiplication *.
%token DIV // Division /.
%token NL // Newline.
%left ADD SUB
%left MUL DIV
%precedence NEG
%type<ast> exp;
%type<argarr> arg;
%type<argarr> argstart;
%type<exps> blockstart;
%type<exps> block;
%type<exps> inputstart
%type<exps> input
%start inputend // This makes no sense but w/e.
%% %%
inputstart:
exp {
DList* exps = dlist_init();
dlist_append(exps, $1);
$$ = exps;
}
;
input: input:
inputstart {
$$ = $1;
}
| input EXPSEP exp {
dlist_append($1, $3);
$$ = $1;
}
;
inputend:
%empty %empty
| exp { root = $1; } | input {
root = ast_init(AST_TYPE_BLOCK, ast_block_data_init((AST**) $1->buf, $1->ln));
dlist_destroypsv($1);
}
;
argstart:
exp {
ArgArr* argarr = argarr_init();
argarr_add(argarr, $1);
$$ = argarr;
}
;
arg:
argstart { $$ = $1; }
| arg SEP exp {
argarr_add($1, $3);
$$ = $1;
}
;
blockstart:
exp {
DList* exps = dlist_init(); // List of expressions.
dlist_append(exps, $1);
$$ = exps;
}
;
block:
blockstart { $$ = $1; }
| block EXPSEP exp {
dlist_append($1, $3);
$$ = $1;
}
; ;
exp: exp:
NUM { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); } NUM { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); }
| NEG NUM { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init(-$2)); }
| NUM PLUS NUM { // Function definitions.
AST** argv = calloc(2, sizeof(AST*)); | WORD GROUPS arg GROUPE EQ exp {
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); size_t argc = $3->ln;
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($3)); AST** argv = $3->buf;
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("+", 2, argv)); argarr_destroypsv($3);
} $$ = ast_init(AST_TYPE_FDEF, ast_fdef_data_init($1, argc, argv, $6));
| NEG NUM PLUS NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$2));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($4));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("+", 2, argv));
}
| NUM NEG NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init($1));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($3));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("-", 2, argv));
}
| NEG NUM NEG NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$2));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($4));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("-", 2, argv));
} }
| NUM MULT NUM { | BLOCKS block BLOCKE {
AST** argv = calloc(2, sizeof(AST*)); $$ = ast_init(AST_TYPE_BLOCK, ast_block_data_init((AST**) $2->buf, $2->ln));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init($1));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($3));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("*", 2, argv));
}
| NEG NUM MULT NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$2));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init($4));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("*", 2, argv));
}
| NEG NUM MULT NEG NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$2));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$5));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("*", 2, argv));
}
| NUM MULT NEG NUM {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init($1));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init(-$4));
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init("*", 2, argv));
} }
| SUB exp {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-1));
argv[1] = $2;
char* to = malloc(4);
strcpy(to, "mul");
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init(to, 2, argv));
}
| GROUPS exp GROUPE { $$ = $2; }
// Variable definition.
| WORD EQ exp {
$$ = ast_init(AST_TYPE_VDEF, ast_vdef_data_init($1, $3));
}
// Variable reference.
| WORD {
$$ = ast_init(AST_TYPE_VREF, ast_vref_data_init($1));
}
| WORD GROUPS arg GROUPE {
size_t argc = $3->ln;
AST** argv = $3->buf;
argarr_destroypsv($3);
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init($1, argc, argv));
}
| exp ADD exp {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = $1;
argv[1] = $3;
char* to = malloc(4);
strcpy(to, "sum");
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init(to, 2, argv));
}
| exp SUB exp {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = $1;
argv[1] = $3;
char* to = malloc(4);
strcpy(to, "sub");
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init(to, 2, argv));
}
| exp MUL exp {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = $1;
argv[1] = $3;
char* to = malloc(4);
strcpy(to, "mul");
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init(to, 2, argv));
}
| exp DIV exp {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = $1;
argv[1] = $3;
char* to = malloc(4);
strcpy(to, "div");
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init(to, 2, argv));
}
%% %%

36
src/htab.c Normal file
View File

@@ -0,0 +1,36 @@
#include "include/htab.h"
#include "include/fnv1a.h"
#include "include/util.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
HTab* htab_init() {
HTab* htab = calloc(1, sizeof(HTab));
log_dbgf("HTAB %p", htab);
return htab;
}
void htab_destroy(HTab* htab) { free(htab); }
// Get the index of a key.
size_t geti(char* key) {
uint64_t hash = fnv1a_hash(key, strlen(key));
size_t i = hash & (HTAB_SPACE - 1); // Magic.
return i;
}
void* htab_get(HTab* htab, char* key) {
size_t i = geti(key);
log_dbgf("Getting something from hash table @ index %lu", i);
return (*htab)[i];
}
void htab_ins(HTab* htab, char* key, void* data) {
size_t i = geti(key);
(*htab)[i] = data;
log_dbgf("Inserted something to hash table @ index %lu", i);
}

View File

@@ -1,38 +1,169 @@
#ifndef AST_H #ifndef AST_H
#define AST_H #define AST_H
#include "scope.h"
#include <stdlib.h> #include <stdlib.h>
// The type of an `AST`.
typedef enum { typedef enum {
AST_TYPE_NUM, // Primitive types.
AST_TYPE_CALL, AST_TYPE_NUM, // A number (float).
AST_TYPE_MAX = AST_TYPE_CALL AST_TYPE_STR, // A string
AST_TYPE_INT, // An integer.
AST_TYPE_SYM, // A symbol.
AST_TYPE_EXC, // Exception.
// Collection types:
AST_TYPE_VEC, // A vector (fixed size, fixed type).
AST_TYPE_LIST, // A list (variable size, variable type).
// Misc. types.
AST_TYPE_BIF, // Built-in function.
AST_TYPE_CALL, // A function call.
AST_TYPE_VDEF, // A variable definition.
AST_TYPE_VREF, // A variable reference.
AST_TYPE_BLOCK, // A block of code (scope).
AST_TYPE_FDEF, // A function definition.
AST_TYPE_ARG, // A definition argument.
AST_TYPE_MAX = AST_TYPE_ARG,
} ASTType; } ASTType;
// An Abstract Syntax Tree.
typedef struct { typedef struct {
ASTType type; ASTType type; // The type of the `AST`.
void* data; void* data; // The data of the `AST`.
Scope* scope; // The scope of the `AST`.
} AST; } AST;
// Create a new `AST`.
AST* ast_init(ASTType type, void* data); AST* ast_init(ASTType type, void* data);
// Create a new `AST` with a specified scope.
AST* ast_init_scope(ASTType type, void* data, Scope* scope);
// Destroy an `AST`, recursively.
void ast_destroy(AST* ast); void ast_destroy(AST* ast);
// Destroy an `AST`.
void ast_destroy_psv(AST* ast);
// Print an `AST`, recursively.
void ast_print(AST* ast); void ast_print(AST* ast);
// Helper function to `ast_print()`, where `i` is indentation level.
void ast_print_i(AST* ast, int i); void ast_print_i(AST* ast, int i);
// A number.
typedef double ASTNumData; typedef double ASTNumData;
// Create a new `ASTNumData`.
ASTNumData* ast_num_data_init(double val); ASTNumData* ast_num_data_init(double val);
// Destroy an `ASTNumData`.
void ast_num_data_destroy(ASTNumData* num); void ast_num_data_destroy(ASTNumData* num);
// Print an `ASTNumData`.
void ast_num_print(ASTNumData*, int i); void ast_num_print(ASTNumData*, int i);
// An exception.
typedef struct ASTEXCDATA {
const char* msg; // The exception message.
AST* trace; // The previous exception.
} ASTExcData;
// Create a new `ASTExecData. `msg` should be static.
ASTExcData* ast_exc_data_init(const char* msg, AST* trace);
// Destroy an `ASTExecData`.
void ast_exc_data_destroy(ASTExcData* exc);
// Print an `ASTExecData`.
void ast_exc_print(ASTExcData*, int i);
// A built-in function.
typedef AST* (*ASTBIFData)(size_t argc, AST** argv, Scope* scope);
// Create a built-in function.
ASTBIFData* ast_bif_data_init(AST* fn(size_t, AST**, Scope*));
// Destroy an `ASTBIFData`.
void ast_bif_data_destroy(ASTBIFData* bif);
// A call (to a function).
typedef struct { typedef struct {
char* to; // What the call's to. char* to; // What the call's to.
size_t argc; // Argument count. size_t argc; // Argument count.
AST** argv; // Argument vector. AST** argv; // Argument vector.
} ASTCallData; } ASTCallData;
// Create a new `ASTCallData`.
ASTCallData* ast_call_data_init(char* to, size_t argc, AST** argv); ASTCallData* ast_call_data_init(char* to, size_t argc, AST** argv);
// Destroy an `ASTCallData` recursively.
void ast_call_data_destroy(ASTCallData* call); void ast_call_data_destroy(ASTCallData* call);
// Destroy an `ASTCallData`.
void ast_call_data_destroy_psv(ASTCallData *call);
// Print an `ASTCallData`.
void ast_call_print(ASTCallData*, int i); void ast_call_print(ASTCallData*, int i);
// A variable definition's data.
typedef struct {
char* name;
AST* val;
} ASTVDefData;
// Create a new `ASTVDefData`.
ASTVDefData* ast_vdef_data_init(char* name, AST* val);
// Destroys the `ASTVDefData`, `ASTVDefData->name`, and `ASTVDefData->val`.
void ast_vdef_data_destroy(ASTVDefData* vdef);
// Destroy an `ASTVDefData`.
void ast_vdef_data_destroy_psv(ASTVDefData* vdef);
// Print an `ASTVDefData`.
void ast_vdef_print(ASTVDefData*, int depth);
// A variable reference's data.
typedef struct {
char* to; // What the reference's to.
} ASTVrefData;
// Create a new `ASTVRefData`.
ASTVrefData* ast_vref_data_init(char* to);
// Destroy an `ASTVRefData`.
void ast_vref_data_destroy(ASTVrefData* call);
// Print an `ASTVRefData`.
void ast_vref_print(ASTVrefData*, int i);
// A code block.
typedef struct {
AST** inside; // What's inside the block.
size_t ln; // How many ASTs are in the block.
} ASTBlockData;
// Create a new `ASTBlockData`.
ASTBlockData* ast_block_data_init(AST** inside, size_t ln);
// Destroy an `ASTBlockData`, recursively.
void ast_block_data_destroy(ASTBlockData* block);
// Destroy an `ASTBlockData`.
void ast_block_data_destroy_psv(ASTBlockData *block);
// Print an `ASTBlockData`.
void ast_block_print(ASTBlockData*, int i);
typedef struct {
char* name; // Function name.
size_t argc; // Argument count.
AST** argv; // Argument vector.
AST* body; // Function body.
} ASTFDefData;
// Create a new `ASTFDefData`.
ASTFDefData* ast_fdef_data_init(char* name, size_t argc, AST** argv, AST* body);
// Destroy an `ASTFDefData`, recursively.
void ast_fdef_data_destroy(ASTFDefData* fdef);
// Destroy an `ASTFDefData`.
void ast_fdef_data_destroy_psv(ASTFDefData* fdef);
// Print an `ASTFDefData`.
void ast_fdef_print(ASTFDefData* fdef, int i);
typedef struct {
char* name; // Argument name.
} ASTArgData;
// Create a new `ASTArgData`.
ASTArgData* ast_arg_data_init(char* name);
// Destroy an `ASTArgData`.
void ast_arg_data_destroy(ASTArgData* arg);
// Print an `ASTArgData`.
void ast_arg_print(ASTArgData* arg, int i);
// Find a name in the scope.
AST* ast_find(Scope* scope, char* name);
#endif #endif

31
src/include/builtin.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef BUILTIN_H
#define BUILTIN_H
#include "ast.h"
// Sum some nums.
AST* builtin_sum(size_t argc, AST** argv, Scope* parent);
// Subtract nums.
AST* builtin_sub(size_t argc, AST** argv, Scope* parent);
// Multiply nums.
AST* builtin_mul(size_t argc, AST** argv, Scope* parent);
// Divide nums.
AST* builtin_div(size_t argc, AST** argv, Scope* parent);
struct builtin_data {
char* name;
AST* (*fn)(size_t argc, AST** argv, Scope* parent);
};
static struct builtin_data BUILTIN_FNS[] = {
{ "sum", builtin_sum },
{ "sub", builtin_sub },
{ "mul", builtin_mul },
{ "div", builtin_div },
};
#define BUILTIN_FNS_LN (arrln(BUILTIN_FNS))
#endif

24
src/include/dlist.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef DLIST_H
#define DLIST_H
#include <stdlib.h>
#define DLIST_INITSZ 128 * sizeof(void*)
typedef struct {
void** buf; // The buffer containing the list.
size_t sz; // The size of the buffer.
size_t ln; // The number of elements in the list.
} DList;
// Create a new `DList`.
DList* dlist_init(void);
// Destroy a `DList`.
void dlist_destroy(DList* dstr);
// Destroy `DList` structure but preserve `->buf`.
void dlist_destroypsv(DList* dstr);
// Append `src` to `dest`.
void dlist_append(DList* dest, void* src);
#endif

View File

@@ -6,18 +6,22 @@
#define DSTR_INITSZ 128 #define DSTR_INITSZ 128
typedef struct { typedef struct {
char* buf; // The buffer containing the string. char* buf; // The buffer containing the string.
size_t bufsz; // The size of the buffer. size_t sz; // The size of the buffer.
size_t ln; // The number of characters in the buffer. size_t ln; // The number of characters in the buffer.
} Dstr; } Dstr;
// Initialize a `DStr`.
Dstr* dstr_init(void); Dstr* dstr_init(void);
// Destroy a `DStr`.
void dstr_destroy(Dstr* dstr); void dstr_destroy(Dstr* dstr);
// Destroy `DStr` structure but preserve `DStr->buf`.
void dstr_destroypsv(Dstr* dstr);
// Append ln characters of src to dest. // Append `ln` characters of `src` to `dest`.
void dstr_append(Dstr* dest, char* src, size_t ln); void dstr_append(Dstr* dest, char* src, size_t ln);
// Append ch to dest. // Append `ch` to `dest`.
void dstr_appendch(Dstr* dest, char ch); void dstr_appendch(Dstr* dest, char ch);
#endif #endif

View File

@@ -2,9 +2,31 @@
#define EXEC_H #define EXEC_H
#include "ast.h" #include "ast.h"
#include "scope.h"
ASTNumData exec_expr(AST* ast); // Start executing at the root of the AST. Initialize the `scope`.
ASTNumData exec_call(AST* ast); AST* exec_start(AST* ast);
// Execute an expression. Delegates to the other executor functions.
AST* exec_exp(AST* ast, Scope* parent);
// Execute the expressions of a block.
AST* exec_block(AST* ast, Scope* parent);
// Execute a call.
AST* exec_call(AST* ast, Scope* parent);
// Execute a custom function call.
AST* exec_cf(AST* ast, size_t argc, AST** argv);
// Execute a variable definition.
AST* exec_vdef(AST* ast, Scope* parent);
// Execute a variable reference.
AST* exec_vref(AST* ast, Scope* parent);
// Execute a function definition.
AST* exec_fdef(AST* ast, Scope* parent);
// Print the result of an execution.
void exec_print(double n); void exec_print(double n);
// Create a new scope and mark it as linked. Also update inherited scope.
void exec_new_scope(AST* ast, Scope* inherit);
// Inherit from another scope and mark it as linked.
void exec_inherit_scope(AST* ast, Scope* inherit);
#endif #endif

18
src/include/fnv1a.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef FNV1A_H
#define FNV1A_H
// Implements the FNV-1a hash algorithm.
#include <stdint.h>
#include <stdlib.h>
// FNV prime.
#define FNV1A_PRIME_64 0x00000100000001b3u
// Offset basis.
#define FNV1A_BASIS_64 0xcbf29ce484222325u
// Hash a string `str` of length `ln`.
uint64_t fnv1a_hash(char* str, size_t ln);
#endif

31
src/include/gc.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef GC_H
#define GC_H
#include <stdlib.h>
// The type a GC can refer to.
typedef enum {
GC_TYPE_AST,
GC_TYPE_SCOPE,
GC_TYPE_MAX = GC_TYPE_SCOPE
} GCType;
// Added to each AST and Scope; keep track of what's actually still accessible.
typedef struct GC_STRUCT {
void* p; // Pointer to the data.
struct GC_STRUCT* nxt; // The next GC in the linked list.
GCType type; // What type of data.
bool marked; // Whether the data is still accessible.
} GC;
GC* gc_init(void* p, GCType type, GC*);
// Does not free ->p or ->nxt.
void gc_destroy(GC* gc);
// Allocate for an object in the heap, and keep track of it in the GC.
void* gc_alloc(size_t sz, GCType type);
// Free everything, immediately.
void gc_hack_free();
#endif

4
src/include/global.h Normal file
View File

@@ -0,0 +1,4 @@
#ifndef GLOBAL_H
#define GLOBAL_H
#endif

29
src/include/htab.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef HTAB_H
#define HTAB_H
#include <stddef.h>
#include <stdint.h>
#define HTAB_FN fnv1a_hash // Function used for hashing.
#define HTAB_SPACE \
1024 // Number of entries possible in the hash table; must be
// power of 2.
// Hash Table.
typedef void* HTab[HTAB_SPACE];
// Create a new hash table.
HTab* htab_init();
// Destroy a hash table, but not its elements.
void htab_destroy(HTab* htab);
// Get element at `hash`. Return its contents, or NULL if nothing found.
void* htab_get(HTab* htab, char* str);
// Insert `data` at index `hash`.
void htab_ins(HTab* htab, char* key, void* data);
// Gets the length of the hash table.
size_t htab_ln(HTab* htab);
#endif

View File

@@ -2,20 +2,29 @@
#define LEXER_H #define LEXER_H
#include <assert.h> #include <assert.h>
#include <stddef.h>
#include "ast.h"
#define ARLN 8
extern char* inp;
typedef struct {
size_t sz;
size_t ln;
AST** buf;
} ArgArr;
ArgArr* argarr_init();
void argarr_destroy(ArgArr* argarr);
// Destroy ArgArr structure but preserve -> buf.
void argarr_destroypsv(ArgArr* argarr);
void argarr_add(ArgArr* argarr, AST* arg);
#ifdef __has_include
#if __has_include("../../build/grammars/grammar.tab.h")
#include "../../build/grammars/grammar.tab.h" #include "../../build/grammars/grammar.tab.h"
#else
#warn "Build resources not present!"
#endif
#else
#warn "Not sure whether build-time resources are present."
#include "../../build/grammars/grammar.tab.h"
#endif
extern YYSTYPE yylval; extern YYSTYPE yylval;
extern char* inp;
// Accumulate an integer. // Accumulate an integer.
int acc_int(int c); int acc_int(int c);

22
src/include/scope.h Normal file
View File

@@ -0,0 +1,22 @@
#ifndef SCOPE_H
#define SCOPE_H
#include "htab.h"
// Represents the reverse linked tree of scope.
typedef struct SCOPE_T {
HTab* here; // This scope's hash table.
struct SCOPE_T* inherit; // The scope to inherit from.
int uses; // How many `AST`s are linked to this scope. // TODO: REMOVE.
} Scope;
// Create a new `Scope`. Creates new empty `HTab` for current scope.
Scope* scope_init(Scope* inherit);
// Destroy all linked `Scope`s this inherits from.
void scope_destroy(Scope* scope);
// Destroy the current `Scope` only.
void scope_destroy_psv(Scope *scope);
// Insert a key/val pair into the `HTab` of a `Scope`.
void scope_add(Scope* scope, char* key, void* val);
#endif

View File

@@ -6,18 +6,19 @@
#define STACK_MAX 64 #define STACK_MAX 64
typedef struct { typedef struct {
size_t i; // Current index in the stack. size_t ln; // The length of the stack (i.e., how many elements).
void* val[STACK_MAX]; // The stack itself. void* buf[STACK_MAX]; // The stack itself.
} Stack; } Stack;
// Create a `Stack`.
Stack* stack_init(); Stack* stack_init();
// Destroy a stack. // Destroy a `Stack`.
// Note that `stack->i` must be `0`. // Note that `->i` must be `0`, i.e. the `Stack` must be empty.
void stack_destroy(Stack* stack); void stack_destroy(Stack* stack);
// Push a value to the stack. // Push a value to the `Stack`.
void stack_push(Stack* stack, void* val); void stack_push(Stack* stack, void* val);
// Pop a value from the stack. // Pop a value from the `Stack`.
void* stack_pop(Stack* stack); void* stack_pop(Stack* stack);
#endif #endif

View File

@@ -1,17 +1,30 @@
#ifndef UTIL_H #ifndef UTIL_H
#define UTIL_H #define UTIL_H
// Most of this file is cursed printing macros for `ast_print()`. Do not attempt
// to comprehend.
// Allocate a pointer with a type.
#define talloc(T, X) T* X = malloc(sizeof(T));
// Get the length of an array.
#define arrln(A) (sizeof(A)/sizeof(*A))
#ifdef DBG // Debug macros #ifdef DBG // Debug macros
// Log a message. // Log a message.
#define log_dbg(msg) \ #define log_dbg(msg) \
printf("\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n", \ printf( \
__func__); "\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n", \
__func__ \
);
// Log a message with formatting. // Log a message with formatting.
#define log_dbgf(msg, ...) \ #define log_dbgf(msg, ...) \
printf("\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n", \ printf( \
__func__, __VA_ARGS__); "\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n", \
__func__, __VA_ARGS__ \
);
#else // ifdef DBG #else // ifdef DBG
#define log_dbg(msg) #define log_dbg(msg)
@@ -50,23 +63,30 @@
// Print & indent the title of a section. // Print & indent the title of a section.
#define INDENT_TITLE(THING, WHERE) \ #define INDENT_TITLE(THING, WHERE) \
printf("%s" COL_BCYA THING COL_RESET " @" COL_MAG " %p\n" COL_RESET, INDENT_spacing->buf, WHERE); printf( \
"%s" COL_BCYA THING COL_RESET " @" COL_MAG " %p\n" COL_RESET, \
INDENT_spacing->buf, WHERE \
);
// Print & indent a thing. // Print & indent a thing.
#define INDENT_FIELD(FIELD, VAL, ...) \ #define INDENT_FIELD(FIELD, VAL, ...) \
printf("%s " COL_BWHI FIELD ": " COL_RESET COL_WHI VAL COL_RESET "\n", \ printf( \
INDENT_spacing->buf, __VA_ARGS__); "%s " COL_BWHI FIELD ": " COL_RESET COL_WHI VAL COL_RESET "\n", \
INDENT_spacing->buf, __VA_ARGS__ \
);
// Print & indent a thing with a newline before the val. // Print & indent a thing with a newline before the val.
#define INDENT_FIELD_NL(FIELD, VAL, ...) \ #define INDENT_FIELD_NL(FIELD, VAL, ...) \
printf("%s " COL_BWHI FIELD ":" COL_RESET "\n %s " COL_WHI VAL COL_RESET \ printf( \
"\n", \ "%s " COL_BWHI FIELD ":" COL_RESET "\n %s " COL_WHI VAL COL_RESET \
INDENT_spacing->buf, INDENT_spacing->buf, __VA_ARGS__); "\n", \
INDENT_spacing->buf, INDENT_spacing->buf, __VA_ARGS__ \
);
// Print & indent a thing without any newline. // Print & indent a thing without any newline.
#define INDENT_FIELD_EXT_NONL_START(FIELD) \ #define INDENT_FIELD_EXT_NONL_START(FIELD) \
printf("%s " COL_BWHI FIELD ":\n" COL_RESET COL_WHI, INDENT_spacing->buf); printf("%s " COL_BWHI FIELD ":\n" COL_RESET COL_WHI, INDENT_spacing->buf);
#define INDENT_FIELD_NONL_END printf( "\n" COL_RESET); #define INDENT_FIELD_NONL_END printf("\n" COL_RESET);
// Print an array A of N things, by calling the function F. // Print an array A of N things, by calling the function F.
#define INDENT_FIELD_LIST(FIELD, A, N, F) \ #define INDENT_FIELD_LIST(FIELD, A, N, F) \
@@ -77,9 +97,14 @@
printf(COL_BWHI "%s ]\n" COL_RESET, INDENT_spacing->buf); printf(COL_BWHI "%s ]\n" COL_RESET, INDENT_spacing->buf);
// End an indent block. // End an indent block.
#define INDENT_END printf(COL_RESET); dstr_destroy(INDENT_spacing); #define INDENT_END \
printf(COL_RESET); \
dstr_destroy(INDENT_spacing);
// Allocate a pointer with a type. #define INDENT_FIELD_LIST_OPEN(FIELD) \
#define talloc(T, X) T* X = malloc(sizeof(T)); printf("%s " COL_BWHI FIELD ": [\n" COL_RESET, INDENT_spacing->buf);
#define INDENT_FIELD_LIST_CLOSE \
printf(COL_BWHI "%s ]\n" COL_RESET, INDENT_spacing->buf);
#endif #endif

View File

@@ -1,9 +1,42 @@
#include <complex.h>
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include "include/dstr.h"
#include "include/lexer.h" #include "include/lexer.h"
#include "include/util.h"
ArgArr* argarr_init() {
ArgArr* argarr = malloc(sizeof(ArgArr));
argarr->sz = ARLN * sizeof(AST*);
argarr->ln = 0;
argarr->buf = malloc(argarr->sz);
return argarr;
}
void argarr_destroy(ArgArr* argarr) {
free(argarr->buf);
free(argarr);
}
void argarr_destroypsv(ArgArr* argarr) { free(argarr); }
void argarr_add(ArgArr* argarr, AST* arg) {
if ((argarr->ln + 1) * sizeof(AST*) > argarr->sz) {
argarr->sz *= 2;
argarr->buf = realloc(argarr->buf, argarr->sz);
log_dbgf(
"ArgArr @ %p doubled from %ld to %ld", argarr, argarr->sz / 2,
argarr->sz
);
}
argarr->buf[argarr->ln++] = arg;
}
int acc_int(int c) { int acc_int(int c) {
int value = c - '0'; int value = c - '0';
@@ -28,30 +61,33 @@ double acc_float(int c) {
inp++; inp++;
while (isdigit(*inp)) { while (isdigit(*inp)) {
// TODO:
// Accumulate as int, divide once at end.
// value = value + (((double)(*inp - '0'))/pow(10.0l,
// (double)(inp-oinp))); // Accumulate value.
value = value * 10 + (*inp - '0'); // Accumulate value. value = value * 10 + (*inp - '0'); // Accumulate value.
dplaces++; dplaces++;
inp++; inp++;
} }
value = value / pow(10, dplaces); value = value / pow(10, dplaces);
} }
// > 1.20000
// = 1.0 + 2/10
// > 1.23
// = 1.2 + 3/100
return value; return value;
} }
char* acc_word(int c) {
Dstr* val = dstr_init();
while (isalpha(*inp)) {
dstr_appendch(val, *(inp - 1));
inp++;
}
dstr_appendch(val, *(inp - 1));
char* ret = val->buf;
dstr_destroypsv(val);
return ret;
}
int yylex() { int yylex() {
if (*inp == '\0') return YYEOF; if (*inp == '\0') return YYEOF;
// Skip all whitespace. // Skip all whitespace.
while (*inp == ' ' || *inp == '\t') { inp++; } while (*inp == ' ' || *inp == '\t') inp++;
// Assign & consume current character. // Assign & consume current character.
int c = *inp++; int c = *inp++;
@@ -62,15 +98,26 @@ int yylex() {
return NUM; return NUM;
} }
switch (c) { if (isalpha(c)) {
case '+': return PLUS; yylval.strval = acc_word(c);
case '\n': return NL; return WORD;
case '-': return NEG;
case '*': return MULT;
default: return CALL;
} }
fprintf(stderr, "Unexpected character: %c\n", c); switch (c) {
case '+': return ADD;
case '\n': return NL;
case '-': return SUB;
case '*': return MUL;
case '/': return DIV;
case '(': return GROUPS;
case ')': return GROUPE;
case ',': return SEP;
case ';': return EXPSEP;
case '{': return BLOCKS;
case '}': return BLOCKE;
case '=': return EQ;
default: fprintf(stderr, "Unexpected character: %c\n", c);
}
return 0; return 0;
} }

View File

@@ -1,8 +1,10 @@
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "include/ast.h" #include "include/ast.h"
#include "include/dstr.h" #include "include/dstr.h"
#include "include/exec.h" #include "include/exec.h"
#include "include/gc.h"
#include "include/lexer.h" #include "include/lexer.h"
#include "include/util.h" #include "include/util.h"
@@ -10,14 +12,22 @@
// Global Abstract Syntax Tree. // Global Abstract Syntax Tree.
extern AST* root; extern AST* root;
extern char* inp;
// Global input text.
char* inp = NULL;
extern int yyparse(); extern int yyparse();
int main(int argc, char** argv) { int main(int argc, char** argv) {
if (argc - 1 && strlen(argv[1]) > 0 && (inp = argv[1]) && !yyparse()) {
log_dbg("Parsed successfully!\n");
ast_print(root);
AST* eval = exec_start(root);
ast_print(eval);
// ast_destroy(eval);
// ast_destroy(root);
gc_hack_free();
exit(0);
}
while (1) { while (1) {
Dstr* ln = dstr_init(); Dstr* ln = dstr_init();
char c; char c;
@@ -31,7 +41,7 @@ int main(int argc, char** argv) {
switch (c) { switch (c) {
case EOF: dstr_destroy(ln); goto lnskip; case EOF: dstr_destroy(ln); goto lnskip;
case '\n': goto lnend; case '\n': goto lnend;
default: dstr_appendch(ln, c); log_dbgf("cchar: %c", c); default: dstr_appendch(ln, c);
} }
} while (1); } while (1);
@@ -45,13 +55,18 @@ int main(int argc, char** argv) {
log_dbg("Parsed successfully!\n"); log_dbg("Parsed successfully!\n");
} else printf("Parse error.\n"); } else printf("Parse error.\n");
exec_print(exec_expr(root));
#ifdef DBG #ifdef DBG
ast_print(root); ast_print(root);
#endif #endif
AST* eval = exec_start(root);
ast_print(eval);
gc_hack_free();
} }
dstr_destroy(ln); dstr_destroy(ln);
} }
lnskip:; lnskip:;
return 0;
} }

37
src/scope.c Normal file
View File

@@ -0,0 +1,37 @@
#include "include/scope.h"
#include "include/gc.h"
#include "include/htab.h"
#include "include/util.h"
#include <stdio.h>
#include <stdlib.h>
Scope* scope_init(Scope* inherit) {
Scope* scope = gc_alloc(sizeof(Scope), GC_TYPE_SCOPE);
scope->here = htab_init();
scope->inherit = inherit;
scope->uses = 0;
log_dbgf("%p: new scope, inherits from %p", scope, inherit);
return scope;
}
void scope_destroy(Scope* scope) {
if (!scope) return;
htab_destroy(scope->here);
if (scope->inherit != NULL) scope_destroy(scope->inherit);
free(scope);
}
void scope_destroy_psv(Scope* scope) {
if (!scope) return;
log_dbgf("%p: destroying", scope);
htab_destroy(scope->here);
scope->inherit = NULL;
free(scope);
}
inline void scope_add(Scope* scope, char* key, void* val) {
htab_ins(scope->here, key, val);
}

View File

@@ -8,33 +8,34 @@
Stack* stack_init() { Stack* stack_init() {
talloc(Stack, stack); talloc(Stack, stack);
memset(stack->val, 0, sizeof(void*) * STACK_MAX); memset(stack->buf, 0, sizeof(void*) * STACK_MAX);
stack->i = 0; stack->ln = 0;
return stack; return stack;
} }
void stack_destroy(Stack* stack) { void stack_destroy(Stack* stack) {
// Can only free an empty stack. // Can only free an empty stack.
assert(stack->i == 0); assert(stack->ln == 0);
free(stack); free(stack);
} }
void stack_push(Stack* stack, void* val) { void stack_push(Stack* stack, void* val) {
if (stack->i >= STACK_MAX) { if (stack->ln >= STACK_MAX) {
log_dbgf("Ran out of stack (max: %d)", STACK_MAX); log_dbgf("Ran out of stack (max: %d)", STACK_MAX);
return; return;
} }
stack->val[stack->i] = val; stack->buf[stack->ln] = val;
stack->i++; stack->ln++;
log_dbgf("pushed to stack, inc ln to %ld", stack->ln);
} }
void* stack_pop(Stack* stack) { void* stack_pop(Stack* stack) {
if (stack->i <= 0) { if (stack->ln <= 0) {
log_dbg("Can't pop empty stack."); log_dbg("Can't pop empty stack.");
return (void*)-1; return (void*)-1;
} }
return stack->val[--stack->i]; return stack->buf[--stack->ln];
} }

1
test/Unity Submodule

Submodule test/Unity added at 73237c5d22

View File

@@ -1,39 +0,0 @@
#include "../src/include/dstr.h"
#include "unity/unity.h"
#include "registry.h"
void test_dstr_init() {
Dstr* dstr = dstr_init();
TEST_ASSERT_EQUAL_INT(DSTR_INITSZ, dstr->bufsz);
TEST_ASSERT_EQUAL_STRING(malloc(DSTR_INITSZ), dstr->buf);
TEST_ASSERT_EQUAL_size_t(0, dstr->ln);
}
void test_dstr_append() {
char* str1 = malloc(2);
str1[0] = 'h';
str1[1] = '\0';
char* str2 = malloc(DSTR_INITSZ);
str2[0] = 'h';
str2[1] = '\0';
Dstr* dstr = dstr_init();
dstr_append(dstr, str1, 1);
TEST_ASSERT_EQUAL_STRING(str2, dstr->buf);
}
int test_dstr() {
UNITY_BEGIN();
RUN_TEST(test_dstr_init);
RUN_TEST(test_dstr_append);
UNITY_END();
return 0;
}
__attribute__((constructor)) void register_dstr() {
register_test(test_dstr);
}

View File

@@ -1,52 +0,0 @@
#include "../src/include/lexer.h"
#include "unity/unity.h"
#include "registry.h"
void test_lexer_init() {
char* src = malloc(sizeof("a1b2"));
src = "a1b2";
Lexer* lexer = lexer_init(src);
TEST_ASSERT_EQUAL_STRING(src, lexer->src);
TEST_ASSERT_EQUAL_INT(4, lexer->srcl);
TEST_ASSERT_EQUAL_CHAR(src[0], *lexer->cchar);
TEST_ASSERT_EQUAL_INT(LEXER_STATE_CONFUSED, lexer->state);
// Hope that token arr. is right size :).
TEST_ASSERT_EQUAL_INT(0, lexer->ntokens);
}
void test_lexer_lex_callnum() {
char* src = malloc(sizeof("a1b2"));
src = "a1b2";
Lexer* lexer = lexer_init(src);
Token* tokens[4] = {
token_init(TOKEN_TYPE_CALL, "a"),
token_init(TOKEN_TYPE_NUMBER, "1"),
token_init(TOKEN_TYPE_CALL, "b"),
token_init(TOKEN_TYPE_NUMBER, "2"),
};
lexer_lex(lexer);
TEST_ASSERT_EQUAL_INT(4, lexer->ntokens);
for (int i = 0; i < 4; i++) {
printf("h");
fflush(stdout);
TEST_ASSERT_EQUAL_INT(tokens[i]->type, lexer->tokens[i]->type);
TEST_ASSERT_EQUAL_STRING(tokens[i]->val, lexer->tokens[i]->val);
}
}
int test_lexer() {
UNITY_BEGIN();
RUN_TEST(test_lexer_init);
RUN_TEST(test_lexer_lex_callnum);
UNITY_END();
return 0;
}
__attribute__((constructor)) void register_lexer() {
register_test(test_lexer);
}

View File

@@ -1,12 +0,0 @@
#include "registry.h"
#include "unity/unity.h"
void (*tests[30])();
void setUp() {}
void tearDown() {}
int main() {
run_all_tests();
return 0;
}

View File

@@ -1,20 +0,0 @@
#include "registry.h"
#include "unity/unity_internals.h"
#define TESTS_MAX 128
static Test tests[TESTS_MAX];
static int test_count = 0;
void register_test(Test t) {
if (test_count < TESTS_MAX) {
tests[test_count] = t;
test_count++;
} else printf("Maximum number of tests (%d) exceeded.\n", TESTS_MAX);
}
void run_all_tests() {
for (int i = 0; i < test_count; i++) {
int res = tests[i]();
}
}

View File

@@ -1,15 +0,0 @@
#ifndef REGISTRY_H
#define REGISTRY_H
#include <stdio.h>
#include "unity/unity.h"
typedef int (*Test)(void);
// Register a new test function.
void register_test(Test);
// Run all registered tests.
void run_all_tests();
#endif

59
test/test_ast.c Normal file
View File

@@ -0,0 +1,59 @@
#include "../src/include/ast.h"
#include "Unity/src/unity.h"
#include "Unity/src/unity_internals.h"
#include <string.h>
void setUp() {}
void tearDown() {}
void test_ast_num() {
ASTNumData* num = ast_num_data_init(12.0);
AST* ast = ast_init(AST_TYPE_NUM, num);
TEST_ASSERT_EQUAL(AST_TYPE_NUM, ast->type);
TEST_ASSERT_EQUAL(12.0, *(ASTNumData*)ast->data);
ast_destroy(ast);
}
void test_ast_call() {
AST** argv = malloc(2*sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(1.0));
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init(2.0));
char* name = malloc(2);
strcpy(name, "f");
ASTCallData* call = ast_call_data_init(name, 2, argv);
AST* ast = ast_init(AST_TYPE_CALL, call);
TEST_ASSERT_EQUAL(AST_TYPE_CALL, ast->type);
TEST_ASSERT_EQUAL(name, ((ASTCallData*)ast->data)->to);
TEST_ASSERT_EQUAL(2, ((ASTCallData*)ast->data)->argc);
TEST_ASSERT_EQUAL(1.0, ((ASTCallData*)ast->data)->argv[0]);
TEST_ASSERT_EQUAL(2.0, ((ASTCallData*)ast->data)->argv[1]);
ast_destroy(ast);
}
void test_ast_vref() {
char* s = malloc(2);
strcpy(s, "x");
ASTVrefData* vref = ast_vref_data_init(s);
AST* ast = ast_init(AST_TYPE_VREF, vref);
TEST_ASSERT_EQUAL(AST_TYPE_VREF, ast->type);
ASTVrefData data = *(ASTVrefData*)ast->data;
TEST_ASSERT_EQUAL_STRING("x", data.to);
//ast_destroy(ast);
}
int main() {
UNITY_BEGIN();
RUN_TEST(test_ast_num);
//RUN_TEST(test_ast_call);
//RUN_TEST(test_ast_vref);
return UNITY_END();
}

41
test/test_dlist.c Normal file
View File

@@ -0,0 +1,41 @@
#include "../src/include/dlist.h"
#include "Unity/src/unity.h"
void setUp() {};
void tearDown() {};
void test_dlist_init() {
DList* dlist = dlist_init();
TEST_ASSERT_EQUAL(0, dlist->ln);
TEST_ASSERT_EQUAL(DLIST_INITSZ, dlist->sz);
}
void test_dlist_append() {
DList* dlist;
// Test simple appending.
dlist = dlist_init();
int* n = malloc(sizeof(int));
*n = 1;
dlist_append(dlist, n);
TEST_ASSERT_EQUAL(n, dlist->buf[0]);
TEST_ASSERT_EQUAL(1, dlist->ln);
dlist_destroy(dlist);
// Test buffer doubling.
dlist = dlist_init();
for (int i = 0; i < 129; i++) dlist_append(dlist, &i);
TEST_ASSERT_EQUAL(129, dlist->ln);
TEST_ASSERT_EQUAL(DLIST_INITSZ*2, dlist->sz);
}
int main() {
UNITY_BEGIN();
RUN_TEST(test_dlist_init);
RUN_TEST(test_dlist_append);
return UNITY_END();
}

78
test/test_dstr.c Normal file
View File

@@ -0,0 +1,78 @@
#include "../src/include/dstr.h"
#include "Unity/src/unity.h"
#include <string.h>
void setUp() {};
void tearDown() {};
void test_dstr_init() {
Dstr* dstr = dstr_init();
TEST_ASSERT_EQUAL(0, strlen(dstr->buf));
TEST_ASSERT_EQUAL(0, dstr->ln);
TEST_ASSERT_EQUAL(DSTR_INITSZ, dstr->sz);
}
void test_dstr_append() {
Dstr* dstr;
// Test simple appending.
dstr = dstr_init();
char* hello_world = "Hello, world!";
dstr_append(dstr, hello_world, strlen(hello_world));
TEST_ASSERT_EQUAL_STRING(hello_world, dstr->buf);
TEST_ASSERT_EQUAL(strlen(hello_world), dstr->ln);
TEST_ASSERT_EQUAL(DSTR_INITSZ, dstr->sz);
dstr_destroy(dstr);
// Test buffer doubling.
dstr = dstr_init();
char h[DSTR_INITSZ + 20];
memset(h, 'h', DSTR_INITSZ + 19);
h[DSTR_INITSZ + 19] = '\0';
dstr_append(dstr, h, strlen(h));
TEST_ASSERT_EQUAL_STRING(h, dstr->buf);
TEST_ASSERT_EQUAL(strlen(h), dstr->ln);
TEST_ASSERT_EQUAL(DSTR_INITSZ * 2, dstr->sz);
}
void test_dstr_appendch() {
Dstr* dstr;
// Test simple character appending.
dstr = dstr_init();
char c = 'c';
char* c_str = "c";
dstr_appendch(dstr, c);
TEST_ASSERT_EQUAL_STRING(c_str, dstr->buf);
TEST_ASSERT_EQUAL(strlen(c_str), dstr->ln);
TEST_ASSERT_EQUAL(DSTR_INITSZ, dstr->sz);
dstr_destroy(dstr);
// Test buffer doubling.
dstr = dstr_init();
// Test against this string.
char h[DSTR_INITSZ + 20];
memset(h, 'h', DSTR_INITSZ + 19);
h[DSTR_INITSZ + 19] = '\0';
for (int i = 0; i < DSTR_INITSZ + 19; i++) dstr_appendch(dstr, 'h');
TEST_ASSERT_EQUAL_STRING(h, dstr->buf);
TEST_ASSERT_EQUAL(strlen(h), dstr->ln);
TEST_ASSERT_EQUAL(DSTR_INITSZ * 2, dstr->sz);
}
int main() {
UNITY_BEGIN();
RUN_TEST(test_dstr_init);
RUN_TEST(test_dstr_append);
RUN_TEST(test_dstr_appendch);
return UNITY_END();
}

27
test/test_htab.c Normal file
View File

@@ -0,0 +1,27 @@
#include "../src/include/htab.h"
#include "Unity/src/unity.h"
#include "Unity/src/unity_internals.h"
#include <string.h>
void setUp() {}
void tearDown() {}
void test_htab() {
char* key = "hello";
char* data = "world";
HTab* htab = htab_init();
htab_ins(htab, key, data);
TEST_ASSERT_EQUAL_STRING(data, htab_get(htab, key));
TEST_ASSERT_NOT_EQUAL(data, htab_get(htab, "h"));
}
int main() {
UNITY_BEGIN();
RUN_TEST(test_htab);
return UNITY_END();
}

View File

@@ -1,24 +0,0 @@
#include "unity/unity.h"
#include <stdlib.h>
#include "../src/include/token.h"
#include "registry.h"
#include "unity/unity_internals.h"
void test_token_init() {
char* s = malloc(sizeof("Hello, world!"));
s = "Hello, world!";
Token* t = token_init(TOKEN_TYPE_CALL, s);
TEST_ASSERT_EQUAL(TOKEN_TYPE_CALL, t->type);
TEST_ASSERT_EQUAL_STRING("Hello, world!", t->val);
}
int test_token() {
UNITY_BEGIN();
RUN_TEST(test_token_init);
return UNITY_END();
}
__attribute__((constructor)) void register_token() {
register_test(test_token);
}

View File

@@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2007-24 Mike Karlesky, Mark VanderVoord, Greg Williams
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -1,698 +0,0 @@
/* =========================================================================
Unity - A Test Framework for C
ThrowTheSwitch.org
Copyright (c) 2007-24 Mike Karlesky, Mark VanderVoord, & Greg Williams
SPDX-License-Identifier: MIT
========================================================================= */
#ifndef UNITY_FRAMEWORK_H
#define UNITY_FRAMEWORK_H
#define UNITY
#define UNITY_VERSION_MAJOR 2
#define UNITY_VERSION_MINOR 6
#define UNITY_VERSION_BUILD 0
#define UNITY_VERSION ((UNITY_VERSION_MAJOR << 16) | (UNITY_VERSION_MINOR << 8) | UNITY_VERSION_BUILD)
#ifdef __cplusplus
extern "C"
{
#endif
#include "unity_internals.h"
/*-------------------------------------------------------
* Test Setup / Teardown
*-------------------------------------------------------*/
/* These functions are intended to be called before and after each test.
* If using unity directly, these will need to be provided for each test
* executable built. If you are using the test runner generator and/or
* Ceedling, these are optional. */
void setUp(void);
void tearDown(void);
/* These functions are intended to be called at the beginning and end of an
* entire test suite. suiteTearDown() is passed the number of tests that
* failed, and its return value becomes the exit code of main(). If using
* Unity directly, you're in charge of calling these if they are desired.
* If using Ceedling or the test runner generator, these will be called
* automatically if they exist. */
void suiteSetUp(void);
int suiteTearDown(int num_failures);
/*-------------------------------------------------------
* Test Reset and Verify
*-------------------------------------------------------*/
/* These functions are intended to be called before during tests in order
* to support complex test loops, etc. Both are NOT built into Unity. Instead
* the test runner generator will create them. resetTest will run teardown and
* setup again, verifying any end-of-test needs between. verifyTest will only
* run the verification. */
void resetTest(void);
void verifyTest(void);
/*-------------------------------------------------------
* Configuration Options
*-------------------------------------------------------
* All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above.
* Integers/longs/pointers
* - Unity attempts to automatically discover your integer sizes
* - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in <stdint.h>
* - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in <limits.h>
* - If you cannot use the automatic methods above, you can force Unity by using these options:
* - define UNITY_SUPPORT_64
* - set UNITY_INT_WIDTH
* - set UNITY_LONG_WIDTH
* - set UNITY_POINTER_WIDTH
* Floats
* - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons
* - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT
* - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats
* - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons
* - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default)
* - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE
* - define UNITY_DOUBLE_TYPE to specify something other than double
* - define UNITY_EXCLUDE_FLOAT_PRINT to trim binary size, won't print floating point values in errors
* Output
* - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired
* - define UNITY_DIFFERENTIATE_FINAL_FAIL to print FAILED (vs. FAIL) at test end summary - for automated search for failure
* Optimization
* - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge
* - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests.
* Test Cases
* - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script
* Parameterized Tests
* - you'll want to create a define of TEST_CASE(...), TEST_RANGE(...) and/or TEST_MATRIX(...) which basically evaluates to nothing
* Tests with Arguments
* - you'll want to define UNITY_USE_COMMAND_LINE_ARGS if you have the test runner passing arguments to Unity
*-------------------------------------------------------
* Basic Fail and Ignore
*-------------------------------------------------------*/
#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, (message))
#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL)
#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, (message))
#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL)
#define TEST_MESSAGE(message) UnityMessage((message), __LINE__)
#define TEST_ONLY()
#ifdef UNITY_INCLUDE_PRINT_FORMATTED
#define TEST_PRINTF(message, ...) UnityPrintF(__LINE__, (message), ##__VA_ARGS__)
#endif
/* It is not necessary for you to call PASS. A PASS condition is assumed if nothing fails.
* This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */
#define TEST_PASS() TEST_ABORT()
#define TEST_PASS_MESSAGE(message) do { UnityMessage((message), __LINE__); TEST_ABORT(); } while (0)
/*-------------------------------------------------------
* Build Directives
*-------------------------------------------------------
* These macros do nothing, but they are useful for additional build context.
* Tools (like Ceedling) can scan for these directives and make use of them for
* per-test-executable #include search paths and linking. */
/* Add source files to a test executable's compilation and linking. Ex: TEST_SOURCE_FILE("sandwiches.c") */
#define TEST_SOURCE_FILE(a)
/* Customize #include search paths for a test executable's compilation. Ex: TEST_INCLUDE_PATH("src/module_a/inc") */
#define TEST_INCLUDE_PATH(a)
/*-------------------------------------------------------
* Test Asserts (simple)
*-------------------------------------------------------*/
/* Boolean */
#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE")
#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE")
#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE")
#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE")
#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL")
#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL")
#define TEST_ASSERT_EMPTY(pointer) UNITY_TEST_ASSERT_EMPTY( (pointer), __LINE__, " Expected Empty")
#define TEST_ASSERT_NOT_EMPTY(pointer) UNITY_TEST_ASSERT_NOT_EMPTY((pointer), __LINE__, " Expected Non-Empty")
/* Integers (of all sizes) */
#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_size_t(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_CHAR(expected, actual) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT)(-1), (actual), __LINE__, NULL)
#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT)(0), (actual), __LINE__, NULL)
#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT)1 << (bit)), (UNITY_UINT)(-1), (actual), __LINE__, NULL)
#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT)1 << (bit)), (UNITY_UINT)(0), (actual), __LINE__, NULL)
/* Integer Not Equal To (of all sizes) */
#define TEST_ASSERT_NOT_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_CHAR((threshold), (actual), __LINE__, NULL)
/* Integer Greater Than/ Less Than (of all sizes) */
#define TEST_ASSERT_GREATER_THAN(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL)
/* Integer Ranges (of all sizes) */
#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_size_t_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_CHAR_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, NULL)
/* Integer Array Ranges (of all sizes) */
#define TEST_ASSERT_INT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_INT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_INT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_INT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_size_t_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_CHAR_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
/* Structs and Strings */
#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, NULL)
/* Arrays */
#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_size_t_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_CHAR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
/* Arrays Compared To Single Value */
#define TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_size_t(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_CHAR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (num_elements), __LINE__, NULL)
/* Floating Point (If Enabled) */
#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_NOT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_NOT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_NOT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_FLOAT_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_FLOAT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_FLOAT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_FLOAT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_FLOAT(threshold, actual) UNITY_TEST_ASSERT_LESS_THAN_FLOAT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_FLOAT(threshold, actual) UNITY_TEST_ASSERT_LESS_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, NULL)
/* Double (If Enabled) */
#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_NOT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_NOT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_NOT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_DOUBLE_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_DOUBLE((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_LESS_THAN_DOUBLE((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_LESS_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, NULL)
/* Shorthand */
#ifdef UNITY_SHORTHAND_AS_OLD
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal")
#endif
#ifdef UNITY_SHORTHAND_AS_INT
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
#ifdef UNITY_SHORTHAND_AS_MEM
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
#ifdef UNITY_SHORTHAND_AS_RAW
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, " Expected Equal")
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal")
#endif
#ifdef UNITY_SHORTHAND_AS_NONE
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
/*-------------------------------------------------------
* Test Asserts (with additional messages)
*-------------------------------------------------------*/
/* Boolean */
#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message))
#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message))
#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message))
#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message))
#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, (message))
#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, (message))
#define TEST_ASSERT_EMPTY_MESSAGE(pointer, message) UNITY_TEST_ASSERT_EMPTY( (pointer), __LINE__, (message))
#define TEST_ASSERT_NOT_EMPTY_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_EMPTY((pointer), __LINE__, (message))
/* Integers (of all sizes) */
#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_size_t_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(-1), (actual), __LINE__, (message))
#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, (message))
#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, (message))
#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_CHAR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, (message))
/* Integer Not Equal To (of all sizes) */
#define TEST_ASSERT_NOT_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_CHAR((threshold), (actual), __LINE__, (message))
/* Integer Greater Than/ Less Than (of all sizes) */
#define TEST_ASSERT_GREATER_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message))
/* Integer Ranges (of all sizes) */
#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_size_t_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_CHAR_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, (message))
/* Integer Array Ranges (of all sizes) */
#define TEST_ASSERT_INT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_INT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_INT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_INT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_INT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_size_t_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_CHAR_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
/* Structs and Strings */
#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, (message))
#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, (message))
/* Arrays */
#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_size_t_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_CHAR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
/* Arrays Compared To Single Value*/
#define TEST_ASSERT_EACH_EQUAL_INT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_INT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_INT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_INT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_INT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_size_t_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_PTR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_STRING_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_MEMORY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_CHAR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (num_elements), __LINE__, (message))
/* Floating Point (If Enabled) */
#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_FLOAT((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_FLOAT_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_FLOAT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_FLOAT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_THAN_FLOAT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, (message))
/* Double (If Enabled) */
#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_DOUBLE_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_DOUBLE_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_DOUBLE((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_THAN_DOUBLE((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, (message))
/* Shorthand */
#ifdef UNITY_SHORTHAND_AS_OLD
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, (message))
#endif
#ifdef UNITY_SHORTHAND_AS_INT
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message)
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
#ifdef UNITY_SHORTHAND_AS_MEM
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, message)
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
#ifdef UNITY_SHORTHAND_AS_RAW
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, message)
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, message)
#endif
#ifdef UNITY_SHORTHAND_AS_NONE
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
/* end of UNITY_FRAMEWORK_H */
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

131
test/val/test.bats Normal file
View File

@@ -0,0 +1,131 @@
#!/usr/bin/env bats
bin() { ./scl.out $1 | tail -n1; }
@test "simple addition" {
run bin "1+1"
[ "$output" = "= 2.000000" ]
run bin "-1+1"
echo $output
[ "$output" = "= 0.000000" ]
run bin "1+-1"
[ "$output" = "= 0.000000" ]
run bin "-1+-1"
[ "$output" = "= -2.000000" ]
}
@test "simple subtraction" {
run bin "1-1"
[ "$output" = "= 0.000000" ]
run bin "-1-1"
[ "$output" = "= -2.000000" ]
run bin "1--1"
[ "$output" = "= 2.000000" ]
run bin "-1--1"
[ "$output" = "= 0.000000" ]
}
@test "simple multiplication" {
run bin "1*2"
[ "$output" = "= 2.000000" ]
run bin "-1*2"
[ "$output" = "= -2.000000" ]
run bin "1*-1"
[ "$output" = "= -1.000000" ]
run bin "-1*-1"
[ "$output" = "= 1.000000" ]
}
@test "simple division" {
run bin "1/2"
[ "$output" = "= 0.500000" ]
run bin "-1/2"
[ "$output" = "= -0.500000" ]
run bin "1/-1"
[ "$output" = "= -1.000000" ]
run bin "-1/-1"
[ "$output" = "= 1.000000" ]
}
@test "order of operations" {
run bin "1+2*3"
[ "$output" = "= 7.000000" ]
run bin "2*3+1"
[ "$output" = "= 7.000000" ]
run bin "6/2-1"
[ "$output" = "= 2.000000" ]
run bin "1-6/2"
[ "$output" = "= -2.000000" ]
}
@test "order of operations with parenthesis" {
run bin "(1+2)*3"
[ "$output" = "= 9.000000" ]
run bin "-(1+2*3)"
[ "$output" = "= -7.000000" ]
run bin "-(-(1+2)*3)"
[ "$output" = "= 9.000000" ]
}
@test "basic blocks" {
run bin "{1}"
[ "$output" = "= 1.000000" ]
run bin "2+{3;4}"
[ "$output" = "= 6.000000" ]
run bin "5*{1+1;5*2}"
echo $output
[ "$output" = "= 50.000000" ]
}
@test "variable definition" {
run bin "x=1"
[ "$output" = "= 1.000000" ]
run bin "x=1;x+1"
[ "$output" = "= 2.000000" ]
run bin "h=7;j=2;k=8;l=4;h*h-l+j*k"
echo $output
[ "$output" = "= 61.000000" ]
}
#@test "function definition" {
# run bin "f(n)=2*n; f(2)"
# [ "$output" = "= 4.000000" ]
#}
@test "type stuff" {
run bin "x:int=1"
[ "$output" = "= 1" ]
run bin "x=1.5; type(x)"
[ "$output" = "= num"]
run bin "x:int=1.5; type(x)"
[ "$output" = "= int" ]
run bin "x:int=1.5"
[ "$output" = "= 1" ]
run bin "print(\"Hello, world!\")"
[ "$output" = "= Hello, world!" ]
}