Compare commits

180 Commits

Author SHA1 Message Date
14ddf51f3c Bump version in README.md.
NOTE: changed versioning system slightly.
2025-08-27 12:30:28 -04:00
ac1d76361f Updated README.md. 2025-08-27 01:14:49 -04:00
b789193484 Recursion works.
FINALLY YESSSS 🎉🎉🎉
2025-08-27 01:10:58 -04:00
ab97f78fab Work on conditionals and equalities. 2025-08-27 00:41:48 -04:00
7c0b212ab4 Added a bit of familiar sugar to conditionals. 2025-08-26 23:50:06 -04:00
80c8038374 Added basic conditionals. 2025-08-26 23:47:15 -04:00
e3cd78e1b4 Added basic implementation of booleans. 2025-08-26 22:58:58 -04:00
b7b90f528b Created an awful hack for a clean exit on die(). 2025-08-26 18:30:08 -04:00
0ef44be808 Fixed some builtin arithmetic logic. 2025-08-26 18:24:28 -04:00
8924818ec4 Updated README.md. 2025-08-26 16:37:48 -04:00
73efa7e136 Cleaned up a bit. 2025-08-26 16:37:38 -04:00
4e8d7131d6 Merge branch 'lambda' 2025-08-26 16:26:06 -04:00
bfce18ab81 Completed lambda implementation of functions.
Hooray! 🎉
2025-08-26 16:25:20 -04:00
7b648c4bd7 Fixed negative expressions. 2025-08-26 16:17:54 -04:00
4ec5d1c075 Fixed everything.
- Cleaned up call stack
- Fixed builtin function execution
- Fixed lambda execution
- Fixed call parsing
2025-08-23 10:53:12 -04:00
5ba070ced7 Things are still in motion. Last thing worked on: call execution. 2025-07-05 11:00:11 -04:00
8256643c0b Updated example. 2025-06-30 01:24:26 -04:00
29a217928e Things are in motion. 2025-06-30 01:22:39 -04:00
482f2b4877 Big refactor to unclutter ast.h.
Moves all print functions to own file for sanity.

Also, just hit 2,000 lines; nice.
2025-06-28 12:25:10 -04:00
36fd838a8f Done with some things, saving here. 2025-06-28 12:05:07 -04:00
289243de38 Added lambda parsing. 2025-06-28 11:15:21 -04:00
67aafb3ead Updated syntax to abbreviate functions defs. 2025-06-28 10:55:15 -04:00
3b5bee0695 Added trap for GDB &c. 2025-06-18 17:21:45 -04:00
970fc39198 Cleaned up types with anonymous structs. 2025-06-14 11:22:07 -04:00
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
ee3f2919c6 Update README.md. Updated main.c. 2024-12-21 11:10:01 -05:00
653736622f Add multiplication.
Supports negative numbers too.
2024-12-21 10:45:43 -05:00
e3afe52ab7 Added negative numbers. 2024-12-21 10:33:36 -05:00
905acacd07 Fixed float addition.
One can now add floats, will also print the AST.
2024-12-21 10:12:30 -05:00
8763fa35dd Updated README.md 2024-12-14 20:35:36 -05:00
feae5d560a Trimmed grammars. 2024-12-07 11:02:22 -05:00
ec268f6047 Nothing works. 2024-12-07 11:01:00 -05:00
6fff5e5cc8 Without token.c. 2024-12-07 10:33:30 -05:00
7b19e553f2 With token.c. 2024-12-07 10:33:16 -05:00
64ef797727 Things. 2024-12-07 09:16:17 -05:00
85e17ede84 Addition with floats is now entirely possible. 2024-11-30 11:15:18 -05:00
8e5b39a6e4 Can now do integer addition (with floats! :D). 2024-11-30 10:44:21 -05:00
4514d94be9 Basic addition with integers is now available. 2024-11-30 10:24:31 -05:00
4080d1a80a Cleaned up. 2024-11-23 10:21:34 -05:00
a36ae22d52 Added exec, grammar files. 2024-11-23 09:30:35 -05:00
ad8ac61b98 Parse. 2024-11-16 10:42:50 -05:00
e5bb4dfd96 Now compiles without warning. 2024-11-16 10:15:30 -05:00
363188d7d6 The. 2024-11-16 10:00:40 -05:00
139d6fcb22 Things. 2024-11-09 11:09:57 -05:00
92d9da14c2 Grammars are broken. 2024-11-09 10:27:03 -05:00
b43fd46260 Changes were made. 2024-11-09 04:37:56 -05:00
a6dc46149c README.md 2024-11-07 19:55:54 -05:00
120038ea8f Global lexer. 2024-11-07 19:41:14 -05:00
8cf09e43c9 Worked on yylex(). 2024-11-02 11:02:18 -04:00
ecc12f6f3b Begin bison-based parsing. 2024-11-02 10:31:55 -04:00
a1f210fee1 Something. 2024-10-31 16:44:17 -04:00
2662f54c51 Fixed more print formatting. 2024-10-31 16:05:04 -04:00
950c25bace Fixed print formatting. 2024-10-31 12:52:39 -04:00
1c0dd7aa0b Added stacks to parser. 2024-10-26 11:02:42 -04:00
5b345e6bf5 Added stack. 2024-10-26 10:56:11 -04:00
891d8bf7ef Finished initial AST structures.
Call and ints (nums).
2024-10-26 10:07:33 -04:00
68fc644ea6 Added more AST stuff. 2024-10-25 11:23:03 -04:00
ca9d2aabe4 Fixed more printing, added basic ast. 2024-10-25 11:20:07 -04:00
7a04ccfd9f Fixed some printing errors, introduced many more. 2024-10-19 10:59:05 -04:00
4df9808859 Fixed blinking functions.
Heh.
2024-10-19 09:15:03 -04:00
933418895e Something. 2024-10-19 09:09:37 -04:00
3c56290448 Numbers work. Calls do not work. 2024-10-16 08:13:32 -04:00
61 changed files with 2805 additions and 4869 deletions

View File

@@ -1,12 +1,13 @@
---
BasedOnStyle: LLVM
AlignConsecutiveShortCaseStatements:
Enabled: true
AcrossEmptyLines: true
AcrossComments: true
IndentCaseLabels: true
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLoopsOnASingleLine: true
IndentWidth: 4
PointerAlignment: Left
AlignAfterOpenBracket: BlockIndent

2
.clangd Normal file
View File

@@ -0,0 +1,2 @@
CompileFlags:
Add: [-xc]

2
.gitignore vendored
View File

@@ -3,4 +3,6 @@
tags
*.out
.cache
build/*
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

109
Makefile
View File

@@ -1,30 +1,4 @@
NAME = scl
TARGET = $(NAME).out
SRC_DIR = src
BUILD_DIR = build
OBJ_DIR = $(BUILD_DIR)/obj
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 =
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.
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))
# Stupid things.
RESETCOLOR = \x1b[0m
WHITE = $(RESETCOLOR)\x1b[37m
WHITE_BOLD = $(RESETCOLOR)\x1b[37;1m
include config.mk
all: $(TARGET)
@@ -32,37 +6,72 @@ release: clean
release: CFLAGS = -Wall -O2
release: $(TARGET)
# Run the target.
run: $(TARGET)
@ echo -e "$(WHITE_BOLD)Running... $(RESETCOLOR)./$(TARGET)"
@ ./$(TARGET)
./$(TARGET)
# Generate grammars with bison.
$(GRAM_FILES): $(SRC_DIR)/grammar.y
@ mkdir -p $(GRAM_DIR)
@ $(PRINT) "$(WHITE_BOLD)Generating grammars...$(RESETCOLOR)"
$(BISON) $< -o$(GRAM_DIR)/grammar.tab.c -H$(GRAM_DIR)/grammar.tab.h
# Compile grammars.
$(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 $@
# Lexer depends on grammars.
$(OBJ_DIR)/lexer.o: $(SRC_DIR)/lexer.c $(GRAM_FILES)
@ mkdir -p $(OBJ_DIR)
@ $(PRINT) "$(WHITE_BOLD)Compiling source object $(WHITE)$@$(WHITE_BOLD)... $(RESETCOLOR)"
$(CC) $(CFLAGS) -c $< -o $@
# Compile project source objects.
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(INC_DIR)/%.h
@ mkdir -p $(OBJ_DIR)
@ $(PRINT) "$(WHITE_BOLD)Compiling source object $(WHITE)$@$(WHITE_BOLD)... $(RESETCOLOR)"
$(CC) $(CFLAGS) -c $< -o $@
# Link to final binary.
$(TARGET): $(OBJ_FILES)
@ echo -e "$(WHITE_BOLD)Linking $(WHITE)$(TARGET)$(WHITE_BOLD)...$(RESETCOLOR) $(CC) -o $(TARGET) $(OBJ_FILES) $(LDFLAGS)"
@ $(LINK) -o $(TARGET) $(OBJ_FILES) $(LDFLAGS)
$(TARGET): $(OBJ_DIR)/grammar.o $(OBJ_FILES)
@ $(PRINT) "$(WHITE_BOLD)Linking $(WHITE)$@$(WHITE_BOLD)...$(RESETCOLOR)"
$(LINK) -o $(TARGET) $(OBJ_FILES) $(OBJ_DIR)/grammar.o $(LDFLAGS)
# Compile project sources.
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(SRC_DIR)/include/%.h
@ mkdir -p $(OBJ_DIR)
@ echo -e "$(WHITE_BOLD)Compiling $(WHITE)$<$(WHITE_BOLD)... $(RESETCOLOR)$(CC) $(CFLAGS) -c $< -o $@"
@ $(CC) $(CFLAGS) -c $< -o $@
# Compile Unity object.
$(UNITY_OBJ): $(UNITY_C) $(UNITY_H)
@ $(PRINT) "$(WHITE_BOLD)Compiling Unity...$(RESETCOLOR)"
$(CC) $(CFLAGS) -D UNITY_OUTPUT_COLOR -c $< -o $@
# Compile test sources.
$(TEST_OBJ_DIR)/%.o: $(TEST_DIR)/%.c
# Compile test object.
$(TEST_OBJ_DIR)/test_%.o: $(TEST_DIR)/test_%.c
@ mkdir -p $(TEST_OBJ_DIR)
@ echo -e "$(WHITE_BOLD)Compiling Test $(WHITE)$<$(WHITE_BOLD)... $(WHITE)$(CC) $(CFLAGS) -I$(SRC_DIR)/include -c $< -o $@$(RESETCOLOR)"
@ $(CC) $(CFLAGS) -I$(SRC_DIR)/include -c $< -o $@
@ $(PRINT) "$(WHITE_BOLD)Compiling test object $(WHITE)$@$(WHITE_BOLD)...$(RESETCOLOR)"
$(CC) $(CFLAGS) -c $< -o $@
# Link the test executable.
test: $(TEST_OBJ_FILES) $(OBJ_FILES_NOMAIN) $(UNITY_C)
@ echo -e "$(WHITE_BOLD)Linking test binary$(WHITE)...$(RESETCOLOR)"
@ $(LINK) -DUNITY_OUTPUT_COLOR $(TEST_OBJ_FILES) $(OBJ_FILES_NOMAIN) $(UNITY_C) -o $(TEST_BUILD_DIR)/test.out
@ echo -e "$(WHITE_BOLD)Running tests$(WHITE)...$(RESETCOLOR)"
@ ./$(TEST_BUILD_DIR)/test.out
# Link final test binary.
$(TEST_BUILD_DIR)/test_%.out: $(TEST_OBJ_DIR)/test_%.o $(OBJ_DIR)/grammar.o $(OBJ_FILES_NOMAIN) $(UNITY_OBJ)
@ mkdir -p $(TEST_BUILD_DIR)
@ $(PRINT) "$(WHITE_BOLD)Linking test binary $(WHITE)$@$(WHITE_BOLD)...$(RESETCOLOR)"
$(LINK) -o $@ $? $(LDFLAGS)
# 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:
@ echo -e "$(WHITE_BOLD)Cleaning up...$(WHITE) $(OBJ_DIR)/*.o $(TEST_OBJ_DIR)/*.o $(TEST_BUILD_DIR)/test.out $(TARGET)$(RESETCOLOR)"
@ rm -rf $(OBJ_DIR)/*.o $(TEST_OBJ_DIR)/*.o $(TEST_BUILD_DIR)/test.out $(TARGET)
@ $(PRINT) "$(WHITE_BOLD)Cleaning up...$(RESETCOLOR)"
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,3 +1,74 @@
# SCL: Simple Calculator Language
# SCL: Simple CAS Language
A spiritual successor to halk.
Version v0.3
SCL aims to be a human-friendly Computer Algebra System (CAS) inspired by
[maxima](https://maxima.sourceforge.io/) that feels like writing on paper. In
its current state, SCL can be used as a functional programming language capable
of performing simple arithmetic. The codebase is about 2,000 lines of C,
including a parser, interpreter, and runtime. It uses a linked environment
scoping model.
## 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:
```scl
> 1 + 1
= 2
```
You can also define your own functions and variables:
```scl
> f(x) 2 * x
> n = 3
> f(n)
= 6
```
Being a functional programming language at heart, one can of course use lambda functions:
```scl
> (\(x) 2 * x)(5)
= 10
> f(g) g(2)
> f(\(x) 2 * x)
= 4
```
Here's a simple factorial function:
```scl
> factorial(n) {
> if (n == 0) { 1 }
> else { n * factorial(n - 1) }
> }
```
Or, using SCL's more concise syntax:
```scl
> factorial(n) ? n == 0 1 n * factorial(n - 1)
```

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
- [x] Parse variable invocation
- [x] Parse variable definition
- [ ] Parse types
- [x] 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
- [x] Exec variable use
- [x] Exec variable definition
- [x] 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

9
TODO.md Normal file
View File

@@ -0,0 +1,9 @@
EXCEPTION HANDLING: exception ast type should have as data a giant enum of
possible types, rather than a char* message. A description of each type could be
handled under the exception type and print logic. For now, executor checks
message for special exceptions e.g. exit().
Change editor to GNU Readline.
Make variables persist through lines in the editor.
Return syntax errors as exceptions.

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

25
definitions.md Normal file
View File

@@ -0,0 +1,25 @@
f = \(x) 2 * x
g = \(h) \(x) h(h(x))
f(2) => 4
g(f)(2) => 8
CALL
argc: 1
argv: [ 2 ]
to:
CALL
argc: 1
argv: [
VREF
name: f
]
to:
VREF
name: g
fname: NULL
expression + arguments = call = expression
expression + parameters = lambda = expression
expression + name = variable = expression

2
examples/function.scl Normal file
View File

@@ -0,0 +1,2 @@
apply(f, x) f(x)
apply(\(x) x + 1, 2)

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">

225
src/ast.c Normal file
View File

@@ -0,0 +1,225 @@
#include <inttypes.h>
#include <stdio.h>
#include "include/ast.h"
#include "include/gc.h"
#include "include/scope.h"
#include "include/util.h"
extern AST* root;
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->type = type;
ast->data = data;
ast->scope = scope;
return ast;
}
void ast_destroy(AST* ast) {
if (!ast) return;
switch (ast->type) {
case AST_TYPE_NUM: ast_num_data_destroy(ast->data); break;
case AST_TYPE_BOOL: ast_bool_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_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;
case AST_TYPE_LAMBDA: ast_lambda_data_destroy(ast->data); break;
default:
log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX);
}
free(ast);
}
ASTNumData* ast_num_data_init(double val) {
talloc(ASTNumData, num);
*num = val;
return num;
}
void ast_num_data_destroy(ASTNumData* num) { free(num); }
ASTBoolData* ast_bool_data_init(int val) {
talloc(ASTBoolData, bol);
*bol = val;
return bol;
}
void ast_bool_data_destroy(ASTBoolData* bol) { free(bol); }
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);
}
ASTBIFData* ast_bif_data_init(AST* fn(size_t, AST**, Scope*)) {
return (ASTBIFData*)fn;
}
void ast_bif_data_destroy(ASTBIFData* bif) { return; }
// Lambda.
ASTLambdaData* ast_lambda_data_init(size_t parc, AST** parv, AST* body) {
talloc(ASTLambdaData, lambda);
lambda->parc = parc;
lambda->parv = parv;
lambda->body = body;
return lambda;
}
void ast_lambda_data_destroy(ASTLambdaData* lambda) {
free(lambda->parv);
free(lambda);
}
// Call.
ASTCallData* ast_call_data_init(size_t argc, AST** argv, AST* exp) {
talloc(ASTCallData, call);
call->exp = exp;
call->argc = argc;
call->argv = argv;
return call;
}
void ast_call_data_destroy(ASTCallData* call) {
if (!call) return;
free(call->argv);
free(call);
}
// VDef.
ASTVDefData* ast_vdef_data_init(char* name, AST* exp) {
talloc(ASTVDefData, vdef);
vdef->name = name;
vdef->exp = exp;
return vdef;
}
void ast_vdef_data_destroy(ASTVDefData* vdef) {
free(vdef->name);
free(vdef);
}
// VRef.
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);
}
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);
}
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);
}
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); }
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;
}

175
src/ast_print.c Normal file
View File

@@ -0,0 +1,175 @@
#include "include/ast_print.h"
#include "include/ast.h"
#include "include/builtin.h"
#include "include/dstr.h"
#include "include/util.h"
#include <stdio.h>
static char* asttype_names[] = {
[AST_TYPE_CALL] = "FUNC CALL",
[AST_TYPE_NUM] = "NUMBER",
[AST_TYPE_BOOL] = "BOOLEAN",
[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_TYPE_LAMBDA] = "LAMBDA EXPRESSION",
[AST_TYPE_BIF] = "BUILTIN FUNCTION"
};
void ast_print(AST* ast) {
if (!ast) return;
ast_print_i(ast, 0);
}
void ast_print_i(AST* ast, int i) {
INDENT_BEGIN(i);
INDENT_TITLE("AST", ast);
INDENT_FIELD("type", "%s", asttype_names[ast->type]);
INDENT_FIELD_EXT_NONL_START("data");
switch (ast->type) {
case AST_TYPE_NUM:
printf("%s %lf\n", INDENT_spacing->buf, *(ASTNumData*)ast->data);
break;
case AST_TYPE_BOOL:
printf(
"%s %s\n", INDENT_spacing->buf,
*(ASTBoolData*)ast->data ? "true" : "false"
);
break;
case AST_TYPE_CALL: ast_call_print(ast->data, i + 2); break;
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;
case AST_TYPE_LAMBDA: ast_lambda_print(ast->data, i + 2); break;
case AST_TYPE_BIF: ast_bif_print(ast->data, i + 2); break;
default: exit(1);
}
INDENT_FIELD_NONL_END;
INDENT_END;
}
void ast_num_print(ASTNumData* data, int i) {
INDENT_BEGIN(i);
INDENT_FIELD("data", "%lf", *data);
INDENT_END;
}
void ast_bool_print(ASTBoolData* data, int i) {
INDENT_BEGIN(i);
INDENT_FIELD("data", "%s", *data ? "true" : "false");
INDENT_END;
}
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;
}
void ast_call_print(ASTCallData* data, int i) {
INDENT_BEGIN(i);
INDENT_TITLE("ASTCallData", data);
INDENT_FIELD("argc", "%ld", data->argc);
INDENT_FIELD_LIST("argv", data->argv, data->argc, ast_print_i);
INDENT_FIELD_EXT_NONL_START("exp");
ast_print_i(data->exp, i + 2);
INDENT_FIELD_NONL_END;
INDENT_END;
}
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("exp");
ast_print_i(vdef->exp, depth + 2); // 2 because already indented.
INDENT_FIELD_NONL_END;
INDENT_END;
}
void ast_vref_print(ASTVrefData* data, int i) {
INDENT_BEGIN(i);
INDENT_TITLE("ASTVrefData", data);
INDENT_FIELD("to", "%s", data->to);
INDENT_END;
}
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;
}
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;
}
void ast_arg_print(ASTArgData* arg, int i) {
INDENT_BEGIN(i);
INDENT_TITLE("ASTArgData", arg);
INDENT_FIELD("name", "%s", arg->name);
INDENT_END;
}
void ast_lambda_print(ASTLambdaData* lambda, int i) {
INDENT_BEGIN(i)
INDENT_TITLE("ASTLambdaData", lambda);
INDENT_FIELD("parc", "%ld", lambda->parc);
INDENT_FIELD_LIST("parv", lambda->parv, lambda->parc, ast_print_i);
INDENT_FIELD_EXT_NONL_START("body");
ast_print_i(lambda->body, i + 2);
INDENT_FIELD_NONL_END;
INDENT_END;
}
void ast_bif_print(ASTBIFData* bif, int i) {
INDENT_BEGIN(i);
INDENT_TITLE("ASTBIFData", bif);
char* name = "unknown";
for (int i = 0; i < BUILTIN_FNS_LN; i++)
if ((void*)BUILTIN_FNS[i].fn == bif) {
name = BUILTIN_FNS[i].name;
break;
}
INDENT_FIELD("name", "%s", name);
INDENT_END;
}

211
src/builtin.c Normal file
View File

@@ -0,0 +1,211 @@
#include <stdarg.h>
#include <stdio.h>
#include "include/ast.h"
#include "include/ast_print.h"
#include "include/builtin.h"
#include "include/exec.h"
#include "include/util.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) {
if (argc <= 0) return ast_init(AST_TYPE_NUM, ast_num_data_init(0));
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) {
if (argc <= 0) return ast_init(AST_TYPE_NUM, ast_num_data_init(0));
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) {
if (argc <= 0) return ast_init(AST_TYPE_NUM, ast_num_data_init(0));
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));
}
AST* builtin_die(size_t argc, AST** argv, Scope* parent) {
return ast_init(AST_TYPE_EXC, ast_exc_data_init("8", NULL));
}
AST* builtin_if(size_t argc, AST** argv, Scope* parent) {
if (argc != 3)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("If invoked with too few args.", NULL)
);
AST* pred = exec_exp(argv[0], parent);
AST* body = argv[1];
AST* alt = argv[2];
if (pred->type != AST_TYPE_BOOL) {
if (pred->type == AST_TYPE_EXC) {
return ast_init(
AST_TYPE_EXC, ast_exc_data_init("if touched an error", pred)
);
} else {
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("if works on booleans idiot", NULL)
);
}
}
if (*(ASTBoolData*)pred->data) return exec_exp(body, parent);
else return exec_exp(alt, parent);
}
AST* builtin_eq(size_t argc, AST** argv, Scope* parent) {
if (argc < 1) return ast_init(AST_TYPE_EXC, ast_exc_data_init("bad", NULL));
else if (argc == 1) return ast_init(AST_TYPE_BOOL, ast_bool_data_init(1));
AST* first = exec_exp(argv[0], parent);
ASTType type = first->type;
AST* second = exec_exp(argv[1], parent);
if (first->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC, ast_exc_data_init("first was bad", first)
);
if (second->type == AST_TYPE_EXC)
return ast_init(
AST_TYPE_EXC, ast_exc_data_init("second was bad", second)
);
if (second->type != type)
return ast_init(
AST_TYPE_EXC,
ast_exc_data_init("apples and oranges or something idk", NULL)
);
// Later when I put together an anctual type system I'll have this
// delegated to each type. For now this works.
switch (type) {
case AST_TYPE_NUM:
if (*(ASTNumData*)first->data == *(ASTNumData*)second->data)
return ast_init(AST_TYPE_BOOL, ast_bool_data_init(1));
else return ast_init(AST_TYPE_BOOL, ast_bool_data_init(0));
case AST_TYPE_BOOL:
if (*(ASTNumData*)first->data == *(ASTNumData*)second->data)
return ast_init(AST_TYPE_BOOL, ast_bool_data_init(1));
else return ast_init(AST_TYPE_BOOL, ast_bool_data_init(0));
default:
return ast_init(
AST_TYPE_BOOL, ast_bool_data_init(0)
); // Can't equate nonprimatives. I think. Maybe.
}
}

44
src/dlist.c Normal file
View File

@@ -0,0 +1,44 @@
#include <stddef.h>
#include <stdio.h> // IWYU pragma: keep. Req by util macros.
#include "include/dlist.h"
#include "include/util.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/util.h"
#include <string.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
Dstr* dstr_init(void) {
Dstr* dstr = malloc(sizeof(Dstr));
dstr->bufsz = DSTR_INITSZ;
dstr->sz = DSTR_INITSZ;
dstr->buf = malloc(DSTR_INITSZ);
*dstr->buf = '\0';
dstr->ln = 0;
@@ -20,13 +21,22 @@ void dstr_destroy(Dstr* dstr) {
free(dstr);
}
void dstr_append(Dstr* dest, char* src, size_t ln) {
while (dest->ln + ln + 1 > dest->bufsz) {
void dstr_destroypsv(Dstr* dstr) { free(dstr); }
// 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.
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);
dstr->sz *= 2;
dstr->buf = realloc(dstr->buf, dstr->sz);
log_dbgf(
"dstr @ %p doubled from %ld to %ld", dstr, dstr->sz / 2, dstr->sz
);
}
}
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
// string.
@@ -34,16 +44,11 @@ void dstr_append(Dstr* dest, char* src, size_t ln) {
dest->ln += ln;
}
void dstr_appendch(Dstr *dest, char ch) {
if (dest->ln + 1 + 1 > dest->bufsz) {
// 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);
}
void dstr_appendch(Dstr* dest, char ch) {
dstr_check_resz(dest, 1);
// Overwrites the preexisting null terminator, and adds one of its own.
dest->buf[dest->ln] = ch;
dest->buf[dest->ln+1] = '\0';
dest->buf[dest->ln + 1] = '\0';
dest->ln += 1;
}

154
src/exec.c Normal file
View File

@@ -0,0 +1,154 @@
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "include/ast.h"
#include "include/builtin.h"
#include "include/exec.h"
#include "include/htab.h"
#include "include/scope.h"
#include "include/util.h"
AST* exec_start(AST* ast) {
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) {
case AST_TYPE_BLOCK: return exec_block(ast, parent);
case AST_TYPE_CALL: return exec_call(ast, parent);
case AST_TYPE_NUM:
return ast_init(
AST_TYPE_NUM, ast_num_data_init(*(ASTNumData*)ast->data)
);
case AST_TYPE_BOOL:
return ast_init(
AST_TYPE_BOOL, ast_bool_data_init(*(ASTBoolData*)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);
case AST_TYPE_BIF:
case AST_TYPE_LAMBDA: return ast;
default: printf("what\n"); exit(1);
}
}
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) {
ASTCallData* calldata = (ASTCallData*)ast->data;
AST* exp = exec_exp(calldata->exp, parent);
switch (exp->type) {
case AST_TYPE_BIF:
ASTBIFData bifdata = exp->data;
return bifdata(calldata->argc, calldata->argv, parent);
case AST_TYPE_LAMBDA:
return exec_lambda(calldata->argc, calldata->argv, exp, parent);
default:
return ast_init(
AST_TYPE_EXC, ast_exc_data_init("Uncallable.", NULL)
);
}
}
AST* exec_vdef(AST* ast, Scope* parent) {
// Use parent's scope.
exec_inherit_scope(ast, parent);
ASTVDefData* data = (ASTVDefData*)ast->data;
AST* val = data->exp;
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);
return found;
}
AST* exec_fdef(AST* ast, Scope* parent) {
ast->scope = scope_init(parent);
ASTFDefData* fdef = (ASTFDefData*)ast->data;
AST* val = ast;
char* key = fdef->name;
scope_add(parent, key, val);
return fdef->body; // Function definitions return function body.
}
AST* exec_lambda(size_t argc, AST** argv, AST* exp, Scope* parent) {
Scope* callscope = scope_init(parent);
ASTLambdaData* lambda = (ASTLambdaData*)exp->data;
for (int i = 0; i < argc; i++) {
char* key = ((ASTArgData*)lambda->parv[i]->data)->name;
AST* val = exec_exp(argv[i], parent);
scope_add(callscope, key, val);
}
return exec_exp(lambda->body, callscope);
}
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(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;

320
src/grammar.y Normal file
View File

@@ -0,0 +1,320 @@
%{
#include <string.h>
#include <stdio.h>
#include "../../src/include/ast.h"
#include "../../src/include/lexer.h"
#include "../../src/include/dlist.h"
#include "../../src/include/builtin.h"
int yylex(void);
void yyerror(char const*);
AST* root = NULL;
%}
%code requires {
#include "../../src/include/ast.h"
#include "../../src/include/dlist.h"
#include "../../src/include/builtin.h"
}
%union {
double fval;
char* strval;
AST* ast;
ArgArr* argarr;
DList* exps;
}
%define parse.error verbose
%token BOOLT // Boolean true (TRUE or T).
%token BOOLF // Boolean false (FALSE or F).
%token IF // if or ?.
%token ELSE // else or :.
%token BLOCKS // Block start {.
%token BLOCKE // Block end }.
%token GROUPS // Group start (.
%token GROUPE // Group end ).
%token SEP // Seperator ,.
%token EQ // Equals =.
%token DEQ // Double equals ==.
%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.
%token BACKSLASH
%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:
inputstart {
$$ = $1;
}
| input EXPSEP exp {
dlist_append($1, $3);
$$ = $1;
}
;
inputend:
%empty
| 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:
// Number.
NUM { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); }
| BOOLT { $$ = ast_init(AST_TYPE_BOOL, ast_bool_data_init(1)); }
| BOOLF { $$ = ast_init(AST_TYPE_BOOL, ast_bool_data_init(0)); }
| exp DEQ exp {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = $1;
argv[1] = $3;
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init(
2,
argv,
ast_init(AST_TYPE_BIF, ast_bif_data_init(builtin_eq))
));
}
| IF exp exp exp {
AST** argv = calloc(3, sizeof(AST*));
argv[0] = $2;
argv[1] = $3;
argv[2] = $4;
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init(
3,
argv,
ast_init(AST_TYPE_BIF, ast_bif_data_init(builtin_if))
));
}
| IF exp exp ELSE exp {
AST** argv = calloc(3, sizeof(AST*));
argv[0] = $2;
argv[1] = $3;
argv[2] = $5;
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init(
3,
argv,
ast_init(AST_TYPE_BIF, ast_bif_data_init(builtin_if))
));
}
// Variable reference.
| WORD {
$$ = ast_init(AST_TYPE_VREF, ast_vref_data_init($1));
}
// Call (general form).
| exp GROUPS arg GROUPE {
size_t argc = $3->ln;
AST** argv = $3->buf;
argarr_destroypsv($3);
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init(
argc,
argv,
$1
));
}
// Call (convenient form).
| 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(
argc,
argv,
ast_init(AST_TYPE_VREF, ast_vref_data_init($1))
));
}
// Call (hacky convenient form).
| WORD GROUPS GROUPE {
size_t argc = 0;
AST** argv = NULL;
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init(
argc,
argv,
ast_init(AST_TYPE_VREF, ast_vref_data_init($1))
));
}
// Function definitions. Convert to VDef of Lambda.
| WORD GROUPS arg GROUPE exp {
size_t parc = $3->ln;
AST** parv = $3->buf;
argarr_destroypsv($3);
$$ = ast_init(AST_TYPE_VDEF, ast_vdef_data_init(
$1,
ast_init(AST_TYPE_LAMBDA, ast_lambda_data_init(
parc, parv, $5
))
));
}
// Lambda definitions.
| BACKSLASH GROUPS arg GROUPE exp {
size_t parc = $3->ln;
AST** parv = $3->buf;
argarr_destroypsv($3);
$$ = ast_init(AST_TYPE_LAMBDA, ast_lambda_data_init(parc, parv, $5));
}
// Block.
| BLOCKS block BLOCKE {
$$ = ast_init(AST_TYPE_BLOCK, ast_block_data_init((AST**) $2->buf, $2->ln));
}
// Negative.
| SUB exp {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-1));
argv[1] = $2;
$$ = ast_init(AST_TYPE_CALL,
ast_call_data_init(
2,
argv,
ast_init(AST_TYPE_BIF,
ast_bif_data_init(builtin_mul)
)
)
);
}
// Group.
| GROUPS exp GROUPE { $$ = $2; }
// Variable definition.
| WORD EQ exp {
$$ = ast_init(AST_TYPE_VDEF, ast_vdef_data_init($1, $3));
}
| exp ADD exp {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = $1;
argv[1] = $3;
$$ = ast_init(AST_TYPE_CALL,
ast_call_data_init(
2,
argv,
ast_init(AST_TYPE_BIF, ast_bif_data_init(builtin_sum))
)
);
}
| exp SUB exp {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = $1;
argv[1] = $3;
$$ = ast_init(AST_TYPE_CALL,
ast_call_data_init(
2,
argv,
ast_init(AST_TYPE_BIF, ast_bif_data_init(builtin_sub))
)
);
}
| exp MUL exp {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = $1;
argv[1] = $3;
$$ = ast_init(AST_TYPE_CALL,
ast_call_data_init(
2,
argv,
ast_init(AST_TYPE_BIF, ast_bif_data_init(builtin_mul))
)
);
}
| exp DIV exp {
AST** argv = calloc(2, sizeof(AST*));
argv[0] = $1;
argv[1] = $3;
$$ = ast_init(AST_TYPE_CALL,
ast_call_data_init(
2,
argv,
ast_init(AST_TYPE_BIF, ast_bif_data_init(builtin_div))
)
);
}
%%

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);
}

176
src/include/ast.h Normal file
View File

@@ -0,0 +1,176 @@
#ifndef AST_H
#define AST_H
#include "scope.h"
#include <stdlib.h>
// The type of an `AST`.
typedef enum {
// Primitive types.
AST_TYPE_NUM, // A number (float).
AST_TYPE_STR, // A string
AST_TYPE_INT, // An integer.
AST_TYPE_BOOL, // A boolean.
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_LAMBDA, // An anonymous function definition.
AST_TYPE_ARG, // A definition argument.
AST_TYPE_MAX = AST_TYPE_ARG,
} ASTType;
// An Abstract Syntax Tree.
typedef struct {
ASTType type; // The type of the `AST`.
void* data; // The data of the `AST`.
Scope* scope; // The scope of the `AST`.
} AST;
// Create a new `AST`.
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`.
void ast_destroy(AST* ast);
// A number.
typedef double ASTNumData;
// Create a new `ASTNumData`.
ASTNumData* ast_num_data_init(double val);
// Destroy an `ASTNumData`.
void ast_num_data_destroy(ASTNumData* num);
// A boolean.
typedef int ASTBoolData;
// Create a new `ASTBoolData`.
ASTBoolData* ast_bool_data_init(int val);
// Destroy an `ASTBoolData`.
void ast_bool_data_destroy(ASTBoolData* bol);
// 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);
// Argument list as anonymous struct.
#define ARGS \
struct { \
size_t argc; \
AST** argv; \
}
// Parameter list as anonymous struct.
#define PARS \
struct { \
size_t parc; \
AST** parv; \
}
// 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 lambda.
typedef struct {
PARS; // The parameters the lambda can accept.
AST* body; // The body expression to be executed.
} ASTLambdaData;
// Creates a new `ASTLambdaData`.
ASTLambdaData* ast_lambda_data_init(size_t parc, AST** parv, AST* body);
// Destroy an `ASTLambdaData`.
void ast_lambda_data_destroy(ASTLambdaData*);
// A call.
typedef struct {
ARGS; // The arguments the call is made with.
AST* exp; // The expression the call is to.
} ASTCallData;
// Create a new `ASTCallData`.
ASTCallData* ast_call_data_init(size_t argc, AST** argv, AST* exp);
// Destroy an `ASTCallData`.
void ast_call_data_destroy(ASTCallData* call);
// A variable definition. Associates a name with an expression.
typedef struct {
char* name;
AST* exp;
} ASTVDefData;
// Create a new `ASTVDefData`.
ASTVDefData* ast_vdef_data_init(char* name, AST* exp);
// Destroy an `ASTVDefData`.
void ast_vdef_data_destroy(ASTVDefData* vdef);
// A variable reference.
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);
// 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);
typedef struct {
char* name; // Function name.
ARGS; // Function args.
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);
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);
// Find the expression associated with a name in the nearest scope.
AST* ast_find(Scope* scope, char* name);
#endif

44
src/include/ast_print.h Normal file
View File

@@ -0,0 +1,44 @@
#ifndef AST_PRINT_H
#define AST_PRINT_H
#include "ast.h"
// Print an `AST`, recursively.
void ast_print(AST* ast);
// Helper function to `ast_print()`, where `i` is indentation level.
void ast_print_i(AST* ast, int i);
// Print an `ASTNumData`.
void ast_num_print(ASTNumData*, int i);
// Print an `ASTBoolData`.
void ast_bool_print(ASTBoolData*, int i);
// Print an `ASTExecData`.
void ast_exc_print(ASTExcData*, int i);
// Print an `ASTCallData`.
void ast_call_print(ASTCallData*, int i);
// Print an `ASTVDefData`.
void ast_vdef_print(ASTVDefData*, int depth);
// Print an `ASTVRefData`.
void ast_vref_print(ASTVrefData*, int i);
// Print an `ASTBlockData`.
void ast_block_print(ASTBlockData*, int i);
// Print an `ASTFDefData`.
void ast_fdef_print(ASTFDefData* fdef, int i);
// Print an `ASTArgData`.
void ast_arg_print(ASTArgData* arg, int i);
// Print an `ASTLambdaData`.
void ast_lambda_print(ASTLambdaData* arg, int i);
// Print an `ASTBIFData`.
void ast_bif_print(ASTBIFData* arg, int i);
#endif

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

@@ -0,0 +1,44 @@
#ifndef BUILTIN_H
#define BUILTIN_H
#include "ast.h"
#include <stddef.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);
// Die.
AST* builtin_die(size_t argc, AST** argv, Scope* parent);
// If statement.
AST* builtin_if(size_t argc, AST** argv, Scope* parent);
// Equality.
AST* builtin_eq(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 },
{ "die", builtin_die },
{"_if", builtin_if},
{"eq", builtin_eq},
};
#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

@@ -7,17 +7,21 @@
typedef struct {
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.
} Dstr;
// Initialize a `DStr`.
Dstr* dstr_init(void);
// Destroy a `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);
// Append ch to dest.
// Append `ch` to `dest`.
void dstr_appendch(Dstr* dest, char ch);
#endif

32
src/include/exec.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef EXEC_H
#define EXEC_H
#include "ast.h"
#include "scope.h"
// Start executing at the root of the AST. Initialize the `scope`.
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 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);
// Execute a lambda expression.
AST* exec_lambda(size_t argc, AST** argv, AST* exp, Scope* parent);
// Print the result of an execution.
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

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

@@ -1,58 +1,39 @@
#ifndef LEXER_H
#define LEXER_H
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <stddef.h>
#include "util.h"
#include "token.h"
#include "ast.h"
#define TOKENS_MAX 32
#define ZERO_CHAR 30
#define ARLN 8
// What the lexer is currently looking at.
typedef enum {
LEXER_STATE_CONFUSED, // Can't decide what it's looking at (also initial
// state).
LEXER_STATE_NUM, // Looking at a number.
LEXER_STATE_CALL, // Looking at a call.
} LexerState;
extern char* inp;
// Lexer: converts text to tokens.
typedef struct {
char* src; // The source text.
size_t srcl; // The number of source chars.
char* cchar; // The current character.
Token** tokens; // The tokens produced.
size_t ntokens; // The number of tokens.
LexerState state; // What the lexer is looking at.
} Lexer;
size_t sz;
size_t ln;
AST** buf;
} ArgArr;
// Create a lexer.
Lexer* lexer_init(char* src);
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);
// Destroy a lexer.
void lexer_destroy(Lexer* lexer);
#include "../../build/grammars/grammar.tab.h"
// Convert text to tokens.
void lexer_lex(Lexer* lexer);
extern YYSTYPE yylval;
// Lex in confused mode.
void lexer_do_confused(Lexer* lexer);
// Accumulate an integer.
int acc_int(int c);
// Lex in number mode.
void lexer_do_number(Lexer* lexer);
// Accumulate a floating-point number.
double acc_float(int c);
// Lex in call mode.
void lexer_do_call(Lexer* lexer);
// Increment the lexer's current character pointer.
void lexer_inc(Lexer* lexer);
// Add a token to the lexer.
void lexer_add_token(Lexer* lexer, Token* token);
// Called by `yyparse()` (in bison-generated files.)
int yylex();
void yyerror(char const* s);
#endif

View File

@@ -1,13 +0,0 @@
#ifndef PARSER_H
#define PARSER_H
// Expression one of:
// - Operation
// - Number
// Operation contains:
// - Type
// - Expression 1
// - Expression 2
#endif

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

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

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

View File

@@ -1,32 +0,0 @@
#ifndef TOKEN_H
#define TOKEN_H
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "dstr.h"
typedef enum {
TOKEN_TYPE_CALL,
TOKEN_TYPE_NUMBER,
} TokenType;
// Token.
typedef struct {
TokenType type; // The type of the Token.
size_t valn; // The length of val.
char* val; // The text of the Token.
size_t len; // Length of the text of the Token.
} Token;
Token* token_init(TokenType type, char* val, size_t valn);
void token_destroy(Token* token);
// Returns a string representation of the Token.
Dstr* token_to_dstr(Token* token);
// Returns a string representation of the TokenType.
char* token_type_to_str(TokenType t);
#endif

View File

@@ -1,20 +1,115 @@
#ifndef UTIL_H
#define UTIL_H
#ifdef DBG
#include <signal.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))
// Trap GDB &c.
#define TRAP() RAISE(SIGTRAP)
#ifdef DBG // Debug macros
// Log a message.
#define log_dbg(msg) \
printf("\033[37;1mdbg\033[0m:\033[37;5m%s\033[0m:\033[32m " msg \
"\033[0m\n", \
__func__);
printf( \
"\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n", \
__func__ \
);
// Log a message with formatting.
#define log_dbgf(msg, ...) \
printf("\033[37;1mdbg\033[0m:\033[37;5m%s\033[0m:\033[32m " msg \
"\033[0m\n", \
__func__, __VA_ARGS__);
printf( \
"\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n", \
__func__, __VA_ARGS__ \
);
#else
#else // ifdef DBG
#define log_dbg(msg)
#endif
#define log_dbgf(msg, ...)
#endif // ifdef DBG else
// Resent color code.
#define COL_RESET "\e[0m"
// Regular color codes.
#define COL_BLA "\e[0;30m"
#define COL_RED "\e[0;31m"
#define COL_GRE "\e[0;32m"
#define COL_YEL "\e[0;33m"
#define COL_BLU "\e[0;34m"
#define COL_MAG "\e[0;35m"
#define COL_CYA "\e[0;36m"
#define COL_WHI "\e[0;37m"
// Bold color codes.
#define COL_BBLA "\e[1;30m"
#define COL_BRED "\e[1;31m"
#define COL_BGRE "\e[1;32m"
#define COL_BYEL "\e[1;33m"
#define COL_BBLU "\e[1;34m"
#define COL_BMAG "\e[1;35m"
#define COL_BCYA "\e[1;36m"
#define COL_BWHI "\e[1;37m"
// Start in indent block.
#define INDENT_BEGIN(ILVL) \
__attribute__((unused)) int INDENT_lvl = ILVL; \
Dstr* INDENT_spacing = dstr_init(); \
for (int INDENT_j = 0; INDENT_j < ILVL; INDENT_j++) \
dstr_appendch(INDENT_spacing, ' ');
// Print & indent the title of a section.
#define INDENT_TITLE(THING, WHERE) \
printf( \
"%s" COL_BCYA THING COL_RESET " @" COL_MAG " %p\n" COL_RESET, \
INDENT_spacing->buf, WHERE \
);
// Print & indent a thing.
#define INDENT_FIELD(FIELD, VAL, ...) \
printf( \
"%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.
#define INDENT_FIELD_NL(FIELD, VAL, ...) \
printf( \
"%s " COL_BWHI FIELD ":" COL_RESET "\n %s " COL_WHI VAL COL_RESET \
"\n", \
INDENT_spacing->buf, INDENT_spacing->buf, __VA_ARGS__ \
);
// Print & indent a thing without any newline.
#define INDENT_FIELD_EXT_NONL_START(FIELD) \
printf("%s " COL_BWHI FIELD ":\n" COL_RESET COL_WHI, INDENT_spacing->buf);
#define INDENT_FIELD_NONL_END printf("\n" COL_RESET);
// Print an array A of N things, by calling the function F.
#define INDENT_FIELD_LIST(FIELD, A, N, F) \
printf("%s " COL_BWHI FIELD ": [\n" COL_RESET, INDENT_spacing->buf); \
for (int INDENT_i = 0; INDENT_i < N; INDENT_i++) { \
F(A[INDENT_i], INDENT_lvl + 2); \
} \
printf(COL_BWHI "%s ]\n" COL_RESET, INDENT_spacing->buf);
// End an indent block.
#define INDENT_END \
printf(COL_RESET); \
dstr_destroy(INDENT_spacing);
#define INDENT_FIELD_LIST_OPEN(FIELD) \
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

View File

@@ -1,102 +1,155 @@
#include <complex.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "include/dstr.h"
#include "include/lexer.h"
#include "include/util.h"
Lexer* lexer_init(char* src) {
Lexer* lexer = malloc(sizeof(Lexer));
ArgArr* argarr_init() {
ArgArr* argarr = malloc(sizeof(ArgArr));
lexer->src = src;
lexer->srcl = strlen(src);
lexer->cchar = lexer->src;
argarr->sz = ARLN * sizeof(AST*);
argarr->ln = 0;
argarr->buf = malloc(argarr->sz);
lexer->tokens = calloc(TOKENS_MAX, sizeof(Token*));
lexer->ntokens = 0;
lexer->state = LEXER_STATE_CONFUSED;
log_dbgf("created new lexer @ %p", lexer);
return lexer;
return argarr;
}
void lexer_destroy(Lexer* lexer) {
free(lexer->src);
for (int i = 0; i < lexer->ntokens; i++) token_destroy(lexer->tokens[i]);
void argarr_destroy(ArgArr* argarr) {
free(argarr->buf);
free(argarr);
}
void lexer_lex(Lexer* lexer) {
while (*lexer->cchar) {
switch (lexer->state) {
case LEXER_STATE_CONFUSED: lexer_do_confused(lexer); break;
case LEXER_STATE_NUM: lexer_do_number(lexer); break;
case LEXER_STATE_CALL: lexer_do_call(lexer); break;
default: break;
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 value = c - '0';
while (isdigit(*inp)) {
value = value * 10 + (*inp - '0'); // Accumulate value.
inp++;
}
return value;
}
void lexer_do_confused(Lexer* lexer) {
log_dbgf("lexer @ %p entered confused mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar);
double acc_float(int c) {
int dplaces = 0;
double value = (double)(c - '0');
lexer->state = LEXER_STATE_CONFUSED;
if (isdigit(*lexer->cchar)) lexer_do_number(lexer);
else lexer_do_call(lexer);
}
void lexer_do_number(Lexer* lexer) {
log_dbgf("lexer @ %p entered number mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar);
lexer->state = LEXER_STATE_NUM;
// Size of the number string.
size_t numsz;
// Where the number string starts.
char* start = lexer->cchar;
for (numsz = 0; *lexer->cchar && isdigit(*lexer->cchar); numsz++)
lexer_inc(lexer);
char* num = malloc(numsz + 1);
memcpy(num, start, numsz);
num[numsz] = '\0';
lexer_add_token(lexer, token_init(TOKEN_TYPE_NUMBER, num, 1));
}
void lexer_do_call(Lexer* lexer) {
log_dbgf("lexer @ %p entered call mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar);
lexer->state = LEXER_STATE_CALL;
// Size of the call string.
size_t callsz;
// Where the call string starts.
char* start = lexer->cchar;
for (; *lexer->cchar && (isblank(lexer->cchar) || *lexer->cchar == '\n'); lexer_inc(lexer));
for (callsz = 0; *lexer->cchar && isalpha(*lexer->cchar); callsz++)
lexer_inc(lexer);
char* call = malloc(callsz + 1);
memcpy(call, start, callsz);
call[callsz] = '\0';
lexer_add_token(lexer, token_init(TOKEN_TYPE_CALL, call, 1));
}
void lexer_inc(Lexer* lexer) {
lexer->cchar += sizeof(char);
}
void lexer_add_token(Lexer* lexer, Token* token) {
assert(lexer->ntokens < TOKENS_MAX);
if (lexer->ntokens < TOKENS_MAX - 1) {
lexer->tokens[lexer->ntokens] = token;
lexer->ntokens++;
// Grab everything prior to '.'.
while (isdigit(*inp)) {
value = value * 10 + (*inp - '0'); // Accumulate value.
inp++;
}
if (*inp == '.') {
inp++;
while (isdigit(*inp)) {
value = value * 10 + (*inp - '0'); // Accumulate value.
dplaces++;
inp++;
}
value = value / pow(10, dplaces);
}
return value;
}
char* acc_word(int c) {
Dstr* val = dstr_init();
while (isalpha(*inp) || *inp == '_') {
dstr_appendch(val, *(inp - 1));
inp++;
}
dstr_appendch(val, *(inp - 1));
char* ret = val->buf;
dstr_destroypsv(val);
return ret;
}
char* acc_deq(int c) {
Dstr* val = dstr_init();
while (*inp == '=') {
dstr_appendch(val, *(inp - 1));
inp++;
}
dstr_appendch(val, *(inp - 1));
char* ret = val->buf;
dstr_destroypsv(val);
return ret;
}
int yylex() {
if (*inp == '\0') return YYEOF;
// Skip all whitespace.
while (*inp == ' ' || *inp == '\t') inp++;
// Assign & consume current character.
int c = *inp++;
// Check for NUM.
if (isdigit(c)) {
yylval.fval = acc_float(c); // Set the token value.
return NUM;
}
if (c == '=') {
yylval.strval = acc_deq(c);
if (!strcmp(yylval.strval, "=")) return EQ;
if (!strcmp(yylval.strval, "==")) return DEQ;
}
if (isalpha(c) || c == '_') {
yylval.strval = acc_word(c);
if (!strcmp(yylval.strval, "TRUE") || !strcmp(yylval.strval, "T"))
return BOOLT;
if (!strcmp(yylval.strval, "FALSE") || !strcmp(yylval.strval, "F"))
return BOOLF;
if (!strcmp(yylval.strval, "if")) return IF;
if (!strcmp(yylval.strval, "else")) return ELSE;
return WORD;
}
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;
case '\\': return BACKSLASH;
case '?': return IF;
case ':': return ELSE;
default: fprintf(stderr, "Unexpected character: %c\n", c);
}
return 0;
}
void yyerror(char const* s) { fprintf(stderr, "Parse error: %s\n", s); }

View File

@@ -1,24 +1,80 @@
#include <stdio.h>
#include <string.h>
#include "include/ast.h"
#include "include/ast_print.h"
#include "include/dstr.h"
#include "include/token.h"
#include "include/util.h"
#include "include/exec.h"
#include "include/gc.h"
#include "include/lexer.h"
#include "include/util.h"
#include "../build/grammars/grammar.tab.h"
// Global Abstract Syntax Tree.
extern AST* root;
extern char* inp;
extern int yyparse();
int main(int argc, char** argv) {
while(1) {
Dstr* cline = dstr_init(); // The current line.
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) {
Dstr* ln = dstr_init();
char c;
printf("> ");
fflush(stdout);
for (char cch; (cch = getchar() != EOF);) {
dstr_appendch(cline, fgetc(stdin));
// Accumulate line.
do {
c = getc(stdin);
switch (c) {
case EOF: dstr_destroy(ln); goto lnskip;
case '\n': goto lnend;
default: dstr_appendch(ln, c);
}
} while (1);
lnend:
log_dbgf("cline: %s", ln->buf);
if (ln->ln > 0) {
inp = ln->buf;
if (yyparse() == 0) {
log_dbg("Parsed successfully!\n");
} else printf("Parse error.\n");
#ifdef DBG
ast_print(root);
#endif
AST* eval = exec_start(root);
ast_print(eval);
// Awful hack to exit when die() is called, until proper exception
// handling is implemented. TODO TODO TODO PLSFIX.
if (eval->type == AST_TYPE_EXC &&
((ASTExcData*)eval->data)->msg[0] == '8') {
gc_hack_free();
exit(1);
}
gc_hack_free();
}
if (cline->ln > 0) {
Lexer* lexer = lexer_init(cline->buf);
lexer_lex(lexer);
printf("\n=%s\n", token_to_dstr(lexer->tokens[0])->buf);
dstr_destroy(ln);
}
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);
}

41
src/stack.c Normal file
View File

@@ -0,0 +1,41 @@
#include <assert.h>
#include <stdio.h> // IWYU pragma: keep. Req by util macros.
#include <string.h>
#include "include/stack.h"
#include "include/util.h"
Stack* stack_init() {
talloc(Stack, stack);
memset(stack->buf, 0, sizeof(void*) * STACK_MAX);
stack->ln = 0;
return stack;
}
void stack_destroy(Stack* stack) {
// Can only free an empty stack.
assert(stack->ln == 0);
free(stack);
}
void stack_push(Stack* stack, void* val) {
if (stack->ln >= STACK_MAX) {
log_dbgf("Ran out of stack (max: %d)", STACK_MAX);
return;
}
stack->buf[stack->ln] = val;
stack->ln++;
log_dbgf("pushed to stack, inc ln to %ld", stack->ln);
}
void* stack_pop(Stack* stack) {
if (stack->ln <= 0) {
log_dbg("Can't pop empty stack.");
return (void*)-1;
}
return stack->buf[--stack->ln];
}

View File

@@ -1,41 +0,0 @@
#include "include/token.h"
#include "include/dstr.h"
#include <stdlib.h>
Token* token_init(TokenType type, char* val, size_t valn) {
Token* t = malloc(sizeof(Token));
t->type = type;
t->val = val;
t->valn = valn;
return t;
}
void token_destroy(Token* t) {
free(t->val);
free(t);
}
Dstr* token_to_dstr(Token* token) {
Dstr* str = dstr_init();
size_t titlesz = sizeof("Token @ 0x00000000");
char title[titlesz];
sprintf(title, "Token @ %p", token);
dstr_append(str, title, titlesz - 1);
dstr_append(str, "\n", 1);
size_t typesz = sizeof("type: 1");
char type[typesz];
// If token_to_dstr starts breaking, it might be because there're more than
// 10 types. FIXME.
sprintf(type, "type: %d", token->type);
dstr_append(str, type, typesz - 1);
dstr_append(str, "\n", 1);
dstr_append(str, "val: ", 5);
dstr_append(str, token->val, token->valn);
return str;
}

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!" ]
}

21
type-notes.md Normal file
View File

@@ -0,0 +1,21 @@
Primitive Types
- num
- bool
- str
```
fact(x) = ? (x <= 1) 1 : f(x-1) * x
> lambda
fact(5) == 120
> True
```
Ordered collections.
| Name | Homogeneous | Fixed Size | Unique |
|---|---|---|---|
| Collection | No | No | No |
| List | Yes | No | No |
| Array | Yes | Yes | No |
| Group | No | Yes | No |
| Set | Yes | No | Yes |
| Perm | Yes | Yes | Yes |