Compare commits
	
		
			168 Commits
		
	
	
		
			ec268f6047
			...
			v1.0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 24f93ce750 | |||
| 2fc3f1e1df | |||
| 9525535323 | |||
| 0fa1c176f4 | |||
| 868dcb6788 | |||
| 4fb698918c | |||
| df74d29e54 | |||
| 7181b31d4b | |||
| 7630e4b99f | |||
| 74d5a212cd | |||
| 90fce2fce4 | |||
| 94689be83b | |||
| cb5fa27eb3 | |||
| 7c08e8da4d | |||
| fdf526750d | |||
| 4e5b12b5b2 | |||
| b102a32999 | |||
| 518f2e9803 | |||
| 0e6bb7aa16 | |||
| 14ddf51f3c | |||
| ac1d76361f | |||
| b789193484 | |||
| ab97f78fab | |||
| 7c0b212ab4 | |||
| 80c8038374 | |||
| e3cd78e1b4 | |||
| b7b90f528b | |||
| 0ef44be808 | |||
| 8924818ec4 | |||
| 73efa7e136 | |||
| 4e8d7131d6 | |||
| bfce18ab81 | |||
| 7b648c4bd7 | |||
| 4ec5d1c075 | |||
| 5ba070ced7 | |||
| 8256643c0b | |||
| 29a217928e | |||
| 482f2b4877 | |||
| 36fd838a8f | |||
| 289243de38 | |||
| 67aafb3ead | |||
| 3b5bee0695 | |||
| 970fc39198 | |||
| 8d3e43d7dc | |||
| d4293e87f3 | |||
| abb8ff6b58 | |||
| 80122b6572 | |||
| a4afd3b58a | |||
| 90c8c91410 | |||
| f5ab0e9cb0 | |||
| 0fb1f1d55f | |||
| 1d83aa65a4 | |||
| 3f30662cde | |||
| 743d16f696 | |||
| 7b99292547 | |||
| 4a516d8edb | |||
| 5b0950cabb | |||
| 40051de9ae | |||
| 2d01b09ee9 | |||
| ff68b756ef | |||
| c2f2658e9c | |||
| 3e80f6430d | |||
| 5b50d423fa | |||
| a04d318e45 | |||
| 7258f162c9 | |||
| 6e05f1334a | |||
| 4e66f7875a | |||
| 845a7f87b2 | |||
| 5b163b26dd | |||
| f8ee7cc66e | |||
| d699f492fa | |||
| 018404eea1 | |||
| 18c61d86dc | |||
| eaf65697de | |||
| ce6e558761 | |||
| db6e591d77 | |||
| 58554e8727 | |||
| 4b9f269938 | |||
| 3d0f534017 | |||
| 38c6a9113c | |||
| 109bcb3fa5 | |||
| 79b60e4853 | |||
| 8cab531129 | |||
| eb3fbca030 | |||
| 40b91b96bd | |||
| 67f659e263 | |||
| b8ce193299 | |||
| 11401e75a7 | |||
| a6be116a2d | |||
| 3678940537 | |||
| cddf5eed76 | |||
| c685d6e55f | |||
| 6cbc28e092 | |||
| 408a5a46c0 | |||
| 6903aeb383 | |||
| fbabf71d64 | |||
| 78e31c3e27 | |||
| be3baee74e | |||
| d5a07fae56 | |||
| 4153903443 | |||
| 77d58bd69e | |||
| 47a3143752 | |||
| 4fb73b3c6f | |||
| e5c58d5fc5 | |||
| 5d81054cf6 | |||
| 66c518fe43 | |||
| 5ecdf2d89a | |||
| a5a86dc080 | |||
| 70393ef9ae | |||
| efac7f7747 | |||
| 3fcffc81ad | |||
| 27e61471a8 | |||
| c94d7863a7 | |||
| 4dd1f2b5f1 | |||
| 1a2249a0da | |||
| 8b01407374 | |||
| 3ab2696705 | |||
| 0293c925d2 | |||
| 16d62f280f | |||
| 0dbeff7077 | |||
| 96038f4baa | |||
| 6d7ff5d43f | |||
| 868ee84aeb | |||
| 694eb43eab | |||
| 694d40124f | |||
| 39778ce08d | |||
| cfd44621d5 | |||
| 4be71317b0 | |||
| 49642553e1 | |||
| 1e11b5921d | |||
| 7343c3b9d9 | |||
| 9e8410d4cf | |||
| bc0c4f33ad | |||
| 1098fa252f | |||
| 0b1905429c | |||
| e7d3ea3697 | |||
| 577bde6e57 | |||
| 60b9ed9eb2 | |||
| d13bf883b5 | |||
| 681e005a68 | |||
| 2ce89fb39a | |||
| 907bc26264 | |||
| e243e862ae | |||
| 5e930b9847 | |||
| ed3ec885c0 | |||
| 835bcfe121 | |||
| 9432496875 | |||
| 0731e40e6a | |||
| 35322de3ac | |||
| c3d8d6f8e5 | |||
| 1f2bca5028 | |||
| 9a9e5cd3e0 | |||
| 4d828500af | |||
| deac5ca5b8 | |||
| e05ebeef2a | |||
| bdca40bae4 | |||
| b4cd46a1e7 | |||
| a57acc1176 | |||
| ffcf2fb013 | |||
| c7a9c8215c | |||
| ca4cf2cd68 | |||
| e19fc8820a | |||
| ee3f2919c6 | |||
| 653736622f | |||
| e3afe52ab7 | |||
| 905acacd07 | |||
| 8763fa35dd | |||
| feae5d560a | 
@@ -1,12 +1,13 @@
 | 
				
			|||||||
---
 | 
					---
 | 
				
			||||||
BasedOnStyle: LLVM
 | 
					 | 
				
			||||||
AlignConsecutiveShortCaseStatements:
 | 
					AlignConsecutiveShortCaseStatements:
 | 
				
			||||||
  Enabled: true
 | 
					  Enabled: true
 | 
				
			||||||
  AcrossEmptyLines: true
 | 
					  AcrossEmptyLines: true
 | 
				
			||||||
  AcrossComments: true
 | 
					  AcrossComments: true
 | 
				
			||||||
 | 
					IndentCaseLabels: true
 | 
				
			||||||
AllowShortBlocksOnASingleLine: Always
 | 
					AllowShortBlocksOnASingleLine: Always
 | 
				
			||||||
AllowShortCaseLabelsOnASingleLine: true
 | 
					AllowShortCaseLabelsOnASingleLine: true
 | 
				
			||||||
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
 | 
					AllowShortIfStatementsOnASingleLine: AllIfsAndElse
 | 
				
			||||||
AllowShortLoopsOnASingleLine: true
 | 
					AllowShortLoopsOnASingleLine: true
 | 
				
			||||||
IndentWidth: 4
 | 
					IndentWidth: 4
 | 
				
			||||||
PointerAlignment: Left
 | 
					PointerAlignment: Left
 | 
				
			||||||
 | 
					AlignAfterOpenBracket: BlockIndent
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -4,5 +4,5 @@ tags
 | 
				
			|||||||
*.out
 | 
					*.out
 | 
				
			||||||
.cache
 | 
					.cache
 | 
				
			||||||
build/*
 | 
					build/*
 | 
				
			||||||
compile_commands.json
 | 
					 | 
				
			||||||
vgcore.*
 | 
					vgcore.*
 | 
				
			||||||
 | 
					compile_commands.json
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					[submodule "test/Unity"]
 | 
				
			||||||
 | 
						path = test/Unity
 | 
				
			||||||
 | 
						url = https://github.com/ThrowTheSwitch/Unity
 | 
				
			||||||
							
								
								
									
										95
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,32 +1,4 @@
 | 
				
			|||||||
NAME = scl
 | 
					include config.mk
 | 
				
			||||||
 | 
					 | 
				
			||||||
TARGET = $(NAME).out
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SRC_DIR = src
 | 
					 | 
				
			||||||
INC_DIR = $(SRC_DIR)/include
 | 
					 | 
				
			||||||
BUILD_DIR = build
 | 
					 | 
				
			||||||
OBJ_DIR = $(BUILD_DIR)/obj
 | 
					 | 
				
			||||||
GRAM_DIR = $(BUILD_DIR)/grammars
 | 
					 | 
				
			||||||
TEST_DIR = test
 | 
					 | 
				
			||||||
TEST_BUILD_DIR = $(BUILD_DIR)/test
 | 
					 | 
				
			||||||
TEST_OBJ_DIR = $(TEST_BUILD_DIR)/obj
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CC = clang
 | 
					 | 
				
			||||||
LINK = clang
 | 
					 | 
				
			||||||
CFLAGS = -Wall -DDBG -ggdb
 | 
					 | 
				
			||||||
LDFLAGS = -lm
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SRC_FILES = $(wildcard $(SRC_DIR)/*.c)
 | 
					 | 
				
			||||||
OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_FILES))
 | 
					 | 
				
			||||||
OBJ_FILES_NOMAIN = $(filter-out $(OBJ_DIR)/main.o, $(OBJ_FILES)) # Object files without main.c.
 | 
					 | 
				
			||||||
GRAM_FILES = $(GRAM_DIR)/grammar.tab.c $(GRAM_DIR)/grammar.tab.h
 | 
					 | 
				
			||||||
UNITY_C = $(TEST_DIR)/unity/unity.c
 | 
					 | 
				
			||||||
TEST_SRC_FILES = $(wildcard $(TEST_DIR)/*.c)
 | 
					 | 
				
			||||||
TEST_OBJ_FILES = $(patsubst $(TEST_DIR)/%.c, $(TEST_OBJ_DIR)/%.o, $(TEST_SRC_FILES))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RESETCOLOR = \033[0m
 | 
					 | 
				
			||||||
WHITE = $(RESETCOLOR)\033[37m
 | 
					 | 
				
			||||||
WHITE_BOLD = $(RESETCOLOR)\033[37;1m
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
all: $(TARGET)
 | 
					all: $(TARGET)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -34,51 +6,72 @@ release: clean
 | 
				
			|||||||
release: CFLAGS = -Wall -O2
 | 
					release: CFLAGS = -Wall -O2
 | 
				
			||||||
release: $(TARGET)
 | 
					release: $(TARGET)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run the target.
 | 
				
			||||||
run: $(TARGET)
 | 
					run: $(TARGET)
 | 
				
			||||||
	@ echo -e "$(WHITE_BOLD)Running... $(RESETCOLOR)./$(TARGET)"
 | 
						./$(TARGET)
 | 
				
			||||||
	@ ./$(TARGET)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Generate grammars with bison.
 | 
					# Generate grammars with bison.
 | 
				
			||||||
$(GRAM_FILES): $(SRC_DIR)/grammar.y
 | 
					$(GRAM_FILES): $(SRC_DIR)/grammar.y
 | 
				
			||||||
	@ mkdir -p $(GRAM_DIR)
 | 
						@ mkdir -p $(GRAM_DIR)
 | 
				
			||||||
	@ echo -e "$(WHITE_BOLD)Generating grammars...$(RESETCOLOR) bison $< -o$(GRAM_DIR)/grammar.tab.c -H$(GRAM_DIR)/grammar.tab.h"
 | 
						@ $(PRINT) "$(WHITE_BOLD)Generating grammars...$(RESETCOLOR)"
 | 
				
			||||||
	@ bison $< -o$(GRAM_DIR)/grammar.tab.c -H$(GRAM_DIR)/grammar.tab.h
 | 
						$(BISON) $< -o$(GRAM_DIR)/grammar.tab.c -H$(GRAM_DIR)/grammar.tab.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Compile grammars.
 | 
					# Compile grammars.
 | 
				
			||||||
$(OBJ_DIR)/grammar.o: $(GRAM_DIR)/grammar.tab.c $(GRAM_DIR)/grammar.tab.h $(OBJ_DIR)/lexer.o
 | 
					$(OBJ_DIR)/grammar.o: $(GRAM_DIR)/grammar.tab.c $(GRAM_DIR)/grammar.tab.h $(OBJ_DIR)/lexer.o
 | 
				
			||||||
 | 
						@ $(PRINT) "$(WHITE_BOLD)Compiling grammars...$(RESETCOLOR)"
 | 
				
			||||||
	$(CC) $(CFLAGS) -c $< -o $@
 | 
						$(CC) $(CFLAGS) -c $< -o $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Lexer depends on grammars.
 | 
					# Lexer depends on grammars.
 | 
				
			||||||
$(OBJ_DIR)/lexer.o: $(SRC_DIR)/lexer.c $(GRAM_FILES)
 | 
					$(OBJ_DIR)/lexer.o: $(SRC_DIR)/lexer.c $(GRAM_FILES)
 | 
				
			||||||
	@ mkdir -p $(OBJ_DIR)
 | 
						@ mkdir -p $(OBJ_DIR)
 | 
				
			||||||
 | 
						@ $(PRINT) "$(WHITE_BOLD)Compiling source object $(WHITE)$@$(WHITE_BOLD)... $(RESETCOLOR)"
 | 
				
			||||||
	$(CC) $(CFLAGS) -c $< -o $@
 | 
						$(CC) $(CFLAGS) -c $< -o $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Compile project sources.
 | 
					# Compile project source objects.
 | 
				
			||||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(INC_DIR)/%.h
 | 
					$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(INC_DIR)/%.h
 | 
				
			||||||
	@ mkdir -p $(OBJ_DIR)
 | 
						@ mkdir -p $(OBJ_DIR)
 | 
				
			||||||
	@ echo -e "$(WHITE_BOLD)Compiling $(WHITE)$<$(WHITE_BOLD)... $(RESETCOLOR)$(CC) $(CFLAGS) -c $< -o $@"
 | 
						@ $(PRINT) "$(WHITE_BOLD)Compiling source object $(WHITE)$@$(WHITE_BOLD)... $(RESETCOLOR)"
 | 
				
			||||||
	@ $(CC) $(CFLAGS) -c $< -o $@
 | 
						$(CC) $(CFLAGS) -c $< -o $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Link to final binary.
 | 
					# Link to final binary.
 | 
				
			||||||
$(TARGET): $(OBJ_DIR)/grammar.o $(OBJ_FILES)
 | 
					$(TARGET): $(OBJ_DIR)/grammar.o $(OBJ_FILES)
 | 
				
			||||||
	@ echo -e "$(WHITE_BOLD)Linking $(WHITE)$(TARGET)$(WHITE_BOLD)...$(RESETCOLOR) $(CC) -o $(TARGET) $(OBJ_FILES) $(LDFLAGS)"
 | 
						@ $(PRINT) "$(WHITE_BOLD)Linking $(WHITE)$@$(WHITE_BOLD)...$(RESETCOLOR)"
 | 
				
			||||||
	@ $(LINK) -o $(TARGET) $(OBJ_FILES) $(OBJ_DIR)/grammar.o $(LDFLAGS)
 | 
						$(LINK) -o $(TARGET) $(OBJ_FILES) $(OBJ_DIR)/grammar.o $(LDFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Compile test sources.
 | 
					# Compile Unity object.
 | 
				
			||||||
$(TEST_OBJ_DIR)/%.o: $(TEST_DIR)/%.c
 | 
					$(UNITY_OBJ): $(UNITY_C) $(UNITY_H)
 | 
				
			||||||
 | 
						@ $(PRINT) "$(WHITE_BOLD)Compiling Unity...$(RESETCOLOR)"
 | 
				
			||||||
 | 
						$(CC) $(CFLAGS) -D UNITY_OUTPUT_COLOR -c $< -o $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Compile test object.
 | 
				
			||||||
 | 
					$(TEST_OBJ_DIR)/test_%.o: $(TEST_DIR)/test_%.c
 | 
				
			||||||
	@ mkdir -p $(TEST_OBJ_DIR)
 | 
						@ mkdir -p $(TEST_OBJ_DIR)
 | 
				
			||||||
	@ echo -e "$(WHITE_BOLD)Compiling Test $(WHITE)$<$(WHITE_BOLD)... $(WHITE)$(CC) $(CFLAGS) -I$(SRC_DIR)/include -c $< -o $@$(RESETCOLOR)"
 | 
						@ $(PRINT) "$(WHITE_BOLD)Compiling test object $(WHITE)$@$(WHITE_BOLD)...$(RESETCOLOR)"
 | 
				
			||||||
	@ $(CC) $(CFLAGS) -I$(SRC_DIR)/include -c $< -o $@
 | 
						$(CC) $(CFLAGS) -c $< -o $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Link the test executable.
 | 
					# Link final test binary.
 | 
				
			||||||
test: $(TEST_OBJ_FILES) $(OBJ_FILES_NOMAIN) $(UNITY_C)
 | 
					$(TEST_BUILD_DIR)/test_%.out: $(TEST_OBJ_DIR)/test_%.o $(OBJ_DIR)/grammar.o $(OBJ_FILES_NOMAIN) $(UNITY_OBJ)
 | 
				
			||||||
	@ echo -e "$(WHITE_BOLD)Linking test binary$(WHITE)...$(RESETCOLOR)"
 | 
						@ mkdir -p $(TEST_BUILD_DIR)
 | 
				
			||||||
	@ $(LINK) -DUNITY_OUTPUT_COLOR $(TEST_OBJ_FILES) $(OBJ_FILES_NOMAIN) $(UNITY_C) -o $(TEST_BUILD_DIR)/test.out
 | 
						@ $(PRINT) "$(WHITE_BOLD)Linking test binary $(WHITE)$@$(WHITE_BOLD)...$(RESETCOLOR)"
 | 
				
			||||||
	@ echo -e "$(WHITE_BOLD)Running tests$(WHITE)...$(RESETCOLOR)"
 | 
						$(LINK) -o $@ $? $(LDFLAGS)
 | 
				
			||||||
	@ ./$(TEST_BUILD_DIR)/test.out
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run the test files.
 | 
				
			||||||
 | 
					test: $(TARGET) $(TEST_BIN_FILES)
 | 
				
			||||||
 | 
						@ $(PRINT) "$(WHITE_BOLD)Running unit tests...$(RESETCOLOR)"
 | 
				
			||||||
 | 
						for test in $(TEST_BIN_FILES); do ./$${test} || echo -e "$(RED_BOLD) BAD EXIT ON $${test} $(RESETCOLOR)"; done
 | 
				
			||||||
 | 
						@ $(PRINT) "$(WHITE_BOLD)Running validation tests...$(RESETCOLOR)"
 | 
				
			||||||
 | 
						$(BATS) $(TEST_VAL_DIR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Clean out objects, binaries, and built artifacts.
 | 
				
			||||||
clean:
 | 
					clean:
 | 
				
			||||||
	@ echo -e "$(WHITE_BOLD)Cleaning up...$(WHITE) $(OBJ_DIR)/*.o $(TEST_OBJ_DIR)/*.o $(TEST_BUILD_DIR)/test.out $(TARGET) $(GRAM_DIR)/* $(RESETCOLOR)"
 | 
						@ $(PRINT) "$(WHITE_BOLD)Cleaning up...$(RESETCOLOR)"
 | 
				
			||||||
	@ rm -rf $(OBJ_DIR)/*.o $(TEST_OBJ_DIR)/*.o $(TEST_BUILD_DIR)/test.out $(TARGET) $(GRAM_DIR)/*
 | 
						rm -rf $(OBJ_DIR)/*.o $(TEST_OBJ_DIR)/*.o $(TEST_BUILD_DIR)/test.out $(TARGET) $(GRAM_DIR)/* $(UNITY_OBJ)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: all clean test nocolor release run
 | 
					# Get LOC.
 | 
				
			||||||
 | 
					lines:
 | 
				
			||||||
 | 
						@ wc -l $(SRC_FILES) $(INC_FILES) $(GRAM_SRC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: all clean test nocolor release run lines
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run this intermediary even though make thinks it's useless.
 | 
				
			||||||
 | 
					.PRECIOUS: $(TEST_OBJ_FILES)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										76
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								README.md
									
									
									
									
									
								
							@@ -1,37 +1,71 @@
 | 
				
			|||||||
# SCL: Simple Calculator Language
 | 
					# SCL: Simple CAS Language
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*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
 | 
				
			||||||
 | 
					handwritten 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/scl/scl -b stable && cd scl
 | 
				
			||||||
 | 
					make release
 | 
				
			||||||
 | 
					./scl.out
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### For Development
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					git clone git@signorovitch.org:scl/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.
 | 
				
			||||||
 | 
					*Note that tests are currently in poor use. I hope to amend this in the future.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Syntax
 | 
					## Syntax
 | 
				
			||||||
 | 
					
 | 
				
			||||||
As one would expect, you can evaluate simple infix expressions:
 | 
					SCL's syntax will feel familiar to other functional programming languages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```scl
 | 
					```scl
 | 
				
			||||||
> 1 + 1
 | 
					> x = 3 + 3 * 3; x + 1
 | 
				
			||||||
 | 
					= 13
 | 
				
			||||||
 | 
					> f(x) x + 1
 | 
				
			||||||
 | 
					> f(1)
 | 
				
			||||||
= 2
 | 
					= 2
 | 
				
			||||||
```
 | 
					> (\(x) 2 * x)(5)
 | 
				
			||||||
 | 
					= 10
 | 
				
			||||||
You can also define your own functions:
 | 
					> f(g) g(2)
 | 
				
			||||||
 | 
					> f(\(x) 2 * x)
 | 
				
			||||||
```scl
 | 
					 | 
				
			||||||
> f(x) 2x
 | 
					 | 
				
			||||||
> f(2)
 | 
					 | 
				
			||||||
= 4
 | 
					= 4
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SCL will dynamically decide on types, but you can state them explicitly as
 | 
					Here's a simple factorial function, using recursion:
 | 
				
			||||||
well:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
```scl
 | 
					```scl
 | 
				
			||||||
> f(x:int) 2x
 | 
					> fac(n) = {
 | 
				
			||||||
> f(2.2)
 | 
					>   f(n, a) = {
 | 
				
			||||||
! f(x:int): x must be of type int.
 | 
					>     if n == 1
 | 
				
			||||||
 | 
					>       a
 | 
				
			||||||
 | 
					>     else
 | 
				
			||||||
 | 
					>       f(n - 1, a * n);
 | 
				
			||||||
 | 
					>   }
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
					>   f(n, 1);
 | 
				
			||||||
 | 
					> }
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Variables can be defined, with several attributes:
 | 
					SCL's syntax is quite flexible. The above function could be more concisely
 | 
				
			||||||
 | 
					written as:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```scl
 | 
					```scl
 | 
				
			||||||
> a = 1             // Interpret type automatically.
 | 
					> fac(n) (n, 1) -> f(n, a) ? n == 1 a f(n - 1, a * n)
 | 
				
			||||||
> b:int = 1         // Must be int.
 | 
					 | 
				
			||||||
> c:const:int = 1   // Constant: value can never change.
 | 
					 | 
				
			||||||
> d:lazy = (1 + 1)  // Interpreter will wait as long as possible before
 | 
					 | 
				
			||||||
                    // evaluating.
 | 
					 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										55
									
								
								STATUS.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								STATUS.md
									
									
									
									
									
										Normal 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
 | 
				
			||||||
 | 
					    - [x] Parse `if` statements
 | 
				
			||||||
 | 
					    - [ ] Parse `loop`s
 | 
				
			||||||
 | 
					    - [ ] Parse `for` loops
 | 
				
			||||||
 | 
					    - [ ] Parse `while` loops
 | 
				
			||||||
 | 
					    - [ ] Parse `case` statements
 | 
				
			||||||
 | 
					    - [ ] Parse `goto` statements
 | 
				
			||||||
 | 
					  - [x] 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
 | 
				
			||||||
 | 
					  - [x] 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
 | 
				
			||||||
							
								
								
									
										10
									
								
								TODO.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								TODO.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					Differentiate kind literals, constructors, and kinds themselves.
 | 
				
			||||||
 | 
					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
									
								
							
							
						
						
									
										40
									
								
								config.mk
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										25
									
								
								definitions.md
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										2
									
								
								examples/function.scl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					apply(f, x) f(x)
 | 
				
			||||||
 | 
					apply(\(x) x + 1, 2)
 | 
				
			||||||
							
								
								
									
										3
									
								
								examples/types.scl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								examples/types.scl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					x: Int = 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<name> : <expression> = <expression>
 | 
				
			||||||
							
								
								
									
										221
									
								
								src/ast.c
									
									
									
									
									
								
							
							
						
						
									
										221
									
								
								src/ast.c
									
									
									
									
									
								
							@@ -1,21 +1,36 @@
 | 
				
			|||||||
 | 
					#include <inttypes.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "include/ast.h"
 | 
					#include "include/ast.h"
 | 
				
			||||||
#include "include/dstr.h"
 | 
					#include "include/gc.h"
 | 
				
			||||||
 | 
					#include "include/scope.h"
 | 
				
			||||||
#include "include/util.h"
 | 
					#include "include/util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern AST* root;
 | 
					extern AST* root;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char* asttype_names[] = {
 | 
					 | 
				
			||||||
    [AST_TYPE_CALL] = "CALL",
 | 
					 | 
				
			||||||
    [AST_TYPE_NUM] = "NUMBER",
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AST* ast_init(ASTType type, void* data) {
 | 
					AST* ast_init(ASTType type, void* data) {
 | 
				
			||||||
 | 
					    AST* ast = gc_alloc(sizeof(AST), GC_TYPE_AST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ast->type = type;
 | 
				
			||||||
 | 
					    ast->data = data;
 | 
				
			||||||
 | 
					    ast->scope = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ast->type > AST_TYPE_MAX) {
 | 
				
			||||||
 | 
					        log_dbgf(
 | 
				
			||||||
 | 
					            "Attempted to create invalid AST (%i > %i) to GC: ast:%p",
 | 
				
			||||||
 | 
					            ast->type, AST_TYPE_MAX, ast
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ast;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST* ast_init_scope(ASTType type, void* data, Scope* scope) {
 | 
				
			||||||
    AST* ast = malloc(sizeof(AST));
 | 
					    AST* ast = malloc(sizeof(AST));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ast->type = type;
 | 
					    ast->type = type;
 | 
				
			||||||
    ast->data = data;
 | 
					    ast->data = data;
 | 
				
			||||||
 | 
					    ast->scope = scope;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ast;
 | 
					    return ast;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -24,59 +39,102 @@ void ast_destroy(AST* ast) {
 | 
				
			|||||||
    if (!ast) return;
 | 
					    if (!ast) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (ast->type) {
 | 
					    switch (ast->type) {
 | 
				
			||||||
    case AST_TYPE_NUM:  ast_num_data_destroy(ast->data); break;
 | 
					        case AST_TYPE_LIT_NUM:  ast_num_data_destroy(ast->data); break;
 | 
				
			||||||
 | 
					        case AST_TYPE_LIT_BOOL: ast_bool_data_destroy(ast->data); break;
 | 
				
			||||||
 | 
					        case AST_TYPE_LIT_KIND: ast_kind_data_destroy(ast->data); break;
 | 
				
			||||||
        case AST_TYPE_CALL:     ast_call_data_destroy(ast->data); break;
 | 
					        case AST_TYPE_CALL:     ast_call_data_destroy(ast->data); break;
 | 
				
			||||||
    default:            log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX);
 | 
					        case AST_TYPE_REF:      ast_ref_data_destroy(ast->data); break;
 | 
				
			||||||
    }
 | 
					        case AST_TYPE_DEF:      ast_def_data_destroy(ast->data); break;
 | 
				
			||||||
 | 
					        case AST_TYPE_BLOCK:    ast_block_data_destroy(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;
 | 
				
			||||||
 | 
					        case AST_TYPE_FORCE:    ast_force_data_destroy(ast->data); break;
 | 
				
			||||||
 | 
					        case AST_TYPE_PRESERVE: ast_preserve_data_destroy(ast->data); break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ast_print(AST* ast) { ast_print_i(ast, 0); }
 | 
					    free(ast);
 | 
				
			||||||
 | 
					 | 
				
			||||||
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_CALL: ast_call_print(ast->data, i + 2); break;
 | 
					 | 
				
			||||||
    default:            exit(1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    INDENT_FIELD_NONL_END;
 | 
					 | 
				
			||||||
    INDENT_END;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ASTNumData* ast_num_data_init(double val) {
 | 
					ASTNumData* ast_num_data_init(double val) {
 | 
				
			||||||
    talloc(ASTNumData, num);
 | 
					    talloc(ASTNumData, num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    log_dbgf("val: %lf", val);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    *num = val;
 | 
					    *num = val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return num;
 | 
					    return num;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ast_num_data_destroy(ASTNumData* num) {
 | 
					void ast_num_data_destroy(ASTNumData* num) { free(num); }
 | 
				
			||||||
    if (!num) return free(num);
 | 
					
 | 
				
			||||||
 | 
					ASTBoolData* ast_bool_data_init(int val) {
 | 
				
			||||||
 | 
					    talloc(ASTBoolData, bol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *bol = val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return bol;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ast_num_print(ASTNumData* data, int i) {
 | 
					void ast_bool_data_destroy(ASTBoolData* bol) { free(bol); }
 | 
				
			||||||
    INDENT_BEGIN(i);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    INDENT_FIELD("data", "%lf", *data);
 | 
					const char* ast_lit_kind_names[AST_LIT_KIND_MAX + 2] = {
 | 
				
			||||||
 | 
					    [AST_LIT_KIND_NUM] = "Number",
 | 
				
			||||||
 | 
					    [AST_LIT_KIND_BOOL] = "Boolean",
 | 
				
			||||||
 | 
					    [AST_LIT_KIND_KIND] = "Type",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    INDENT_END;
 | 
					ASTKindData* ast_kind_data_init(ASTKindData val) {
 | 
				
			||||||
 | 
					    talloc(ASTKindData, kind);
 | 
				
			||||||
 | 
					    *kind = val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return kind;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ASTCallData* ast_call_data_init(char* to, size_t argc, AST** argv) {
 | 
					void ast_kind_data_destroy(ASTKindData* kind) { free(kind); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
					    talloc(ASTCallData, call);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    log_dbgf("to: %s", to);
 | 
					    call->exp = exp;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    call->to = to;
 | 
					 | 
				
			||||||
    call->argc = argc;
 | 
					    call->argc = argc;
 | 
				
			||||||
    call->argv = argv;
 | 
					    call->argv = argv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -84,18 +142,87 @@ ASTCallData* ast_call_data_init(char* to, size_t argc, AST** argv) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ast_call_data_destroy(ASTCallData* call) {
 | 
					void ast_call_data_destroy(ASTCallData* call) {
 | 
				
			||||||
    if (!call) return free(call->to);
 | 
					    if (!call) return;
 | 
				
			||||||
    for (size_t i = 0; i < call->argc; i++) free(call->argv[i]);
 | 
					    free(call->argv);
 | 
				
			||||||
    free(call);
 | 
					    free(call);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ast_call_print(ASTCallData* data, int i) {
 | 
					// Def.
 | 
				
			||||||
    INDENT_BEGIN(i);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    INDENT_TITLE("ASTCallData", data);
 | 
					ASTDefData* ast_def_data_init(char* name, AST* kind, AST* exp) {
 | 
				
			||||||
    INDENT_FIELD("to", "%s", data->to);
 | 
					    talloc(ASTDefData, def);
 | 
				
			||||||
    INDENT_FIELD("argc", "%ld", data->argc);
 | 
					 | 
				
			||||||
    INDENT_FIELD_LIST("argv", data->argv, data->argc, ast_print_i);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    INDENT_END;
 | 
					    def->name = name;
 | 
				
			||||||
 | 
					    def->kind = kind;
 | 
				
			||||||
 | 
					    def->exp = exp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return def;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ast_def_data_destroy(ASTDefData* vdef) {
 | 
				
			||||||
 | 
					    free(vdef->name);
 | 
				
			||||||
 | 
					    free(vdef);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Ref.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASTRefData* ast_ref_data_init(char* to) {
 | 
				
			||||||
 | 
					    talloc(ASTRefData, ref);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ref->to = to;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ref;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ast_ref_data_destroy(ASTRefData* ref) {
 | 
				
			||||||
 | 
					    free(ref->to);
 | 
				
			||||||
 | 
					    free(ref);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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) {
 | 
				
			||||||
 | 
					    free(block->inside);
 | 
				
			||||||
 | 
					    free(block);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASTForceData* ast_force_data_init(AST* body) {
 | 
				
			||||||
 | 
					    talloc(ASTForceData, force);
 | 
				
			||||||
 | 
					    force->body = body;
 | 
				
			||||||
 | 
					    return force;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ast_force_data_destroy(ASTForceData* force) { free(force); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ASTPreserveData* ast_preserve_data_init(AST* body) {
 | 
				
			||||||
 | 
					    talloc(ASTPreserveData, preserve);
 | 
				
			||||||
 | 
					    preserve->body = body;
 | 
				
			||||||
 | 
					    return preserve;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ast_preserve_data_destroy(ASTPreserveData* preserve) { free(preserve); }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										199
									
								
								src/ast_print.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								src/ast_print.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,199 @@
 | 
				
			|||||||
 | 
					#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] = "CALL",
 | 
				
			||||||
 | 
					    [AST_TYPE_LIT_NUM] = "LITERAL NUMBER",
 | 
				
			||||||
 | 
					    [AST_TYPE_LIT_BOOL] = "LITERAL BOOLEAN",
 | 
				
			||||||
 | 
					    [AST_TYPE_REF] = "REFERENCE",
 | 
				
			||||||
 | 
					    [AST_TYPE_DEF] = "DEFINITION",
 | 
				
			||||||
 | 
					    [AST_TYPE_BLOCK] = "BLOCK",
 | 
				
			||||||
 | 
					    [AST_TYPE_EXC] = "EXCEPTION",
 | 
				
			||||||
 | 
					    [AST_TYPE_ARG] = "DEFINITION ARGUMENT",
 | 
				
			||||||
 | 
					    [AST_TYPE_LAMBDA] = "LAMBDA",
 | 
				
			||||||
 | 
					    [AST_TYPE_BIF] = "BUILTIN FUNCTION",
 | 
				
			||||||
 | 
					    [AST_TYPE_FORCE] = "FORCE",
 | 
				
			||||||
 | 
					    [AST_TYPE_PRESERVE] = "PRESERVE"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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_LIT_NUM:
 | 
				
			||||||
 | 
					            printf("%s  %lf\n", INDENT_spacing->buf, *(ASTNumData*)ast->data);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case AST_TYPE_LIT_BOOL:
 | 
				
			||||||
 | 
					            printf(
 | 
				
			||||||
 | 
					                "%s  %s\n", INDENT_spacing->buf,
 | 
				
			||||||
 | 
					                *(ASTBoolData*)ast->data ? "true" : "false"
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case AST_TYPE_LIT_KIND:
 | 
				
			||||||
 | 
					            printf(
 | 
				
			||||||
 | 
					                "%s  %s\n", INDENT_spacing->buf,
 | 
				
			||||||
 | 
					                ast_lit_kind_names[*(ASTKindData*)ast->data]
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            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_REF:      ast_ref_print(ast->data, i + 2); break;
 | 
				
			||||||
 | 
					        case AST_TYPE_DEF:      ast_def_print(ast->data, i + 2); break;
 | 
				
			||||||
 | 
					        case AST_TYPE_BLOCK:    ast_block_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;
 | 
				
			||||||
 | 
					        case AST_TYPE_FORCE:    ast_force_print(ast->data, i + 2); break;
 | 
				
			||||||
 | 
					        case AST_TYPE_PRESERVE: ast_preserve_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_def_print(ASTDefData* def, int depth) {
 | 
				
			||||||
 | 
					    INDENT_BEGIN(depth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INDENT_TITLE("ASTDefData", def);
 | 
				
			||||||
 | 
					    INDENT_FIELD("name", "%s", def->name);
 | 
				
			||||||
 | 
					    if (def->kind) {
 | 
				
			||||||
 | 
					        INDENT_FIELD_EXT_NONL_START("kind");
 | 
				
			||||||
 | 
					        ast_print_i(def->kind, depth + 2);
 | 
				
			||||||
 | 
					        INDENT_FIELD_NONL_END;
 | 
				
			||||||
 | 
					    } else INDENT_FIELD("kind", "%s", "Any");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INDENT_FIELD_EXT_NONL_START("exp");
 | 
				
			||||||
 | 
					    ast_print_i(def->exp, depth + 2); // 2 because already indented.
 | 
				
			||||||
 | 
					    INDENT_FIELD_NONL_END;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INDENT_END;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ast_ref_print(ASTRefData* data, int i) {
 | 
				
			||||||
 | 
					    INDENT_BEGIN(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INDENT_TITLE("ASTRefData", 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_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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ast_force_print(ASTForceData* force, int i) {
 | 
				
			||||||
 | 
					    INDENT_BEGIN(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INDENT_TITLE("ASTForceData", force);
 | 
				
			||||||
 | 
					    INDENT_FIELD_EXT_NONL_START("body");
 | 
				
			||||||
 | 
					    ast_print_i(force->body, i + 2);
 | 
				
			||||||
 | 
					    INDENT_FIELD_NONL_END;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INDENT_END;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ast_preserve_print(ASTPreserveData* preserve, int i) {
 | 
				
			||||||
 | 
					    INDENT_BEGIN(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INDENT_TITLE("ASTPreserveData", preserve);
 | 
				
			||||||
 | 
					    INDENT_FIELD_EXT_NONL_START("body");
 | 
				
			||||||
 | 
					    ast_print_i(preserve->body, i + 2);
 | 
				
			||||||
 | 
					    INDENT_FIELD_NONL_END;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INDENT_END;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										211
									
								
								src/builtin.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								src/builtin.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,211 @@
 | 
				
			|||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "include/ast.h"
 | 
				
			||||||
 | 
					#include "include/builtin.h"
 | 
				
			||||||
 | 
					#include "include/exec.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_LIT_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_LIT_NUM, ast_num_data_init(total));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST* builtin_sub(size_t argc, AST** argv, Scope* parent) {
 | 
				
			||||||
 | 
					    if (argc <= 0) return ast_init(AST_TYPE_LIT_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_LIT_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_LIT_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_LIT_NUM, ast_num_data_init(total));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST* builtin_mul(size_t argc, AST** argv, Scope* parent) {
 | 
				
			||||||
 | 
					    if (argc <= 0) return ast_init(AST_TYPE_LIT_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_LIT_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_LIT_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_LIT_NUM, ast_num_data_init(total));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST* builtin_div(size_t argc, AST** argv, Scope* parent) {
 | 
				
			||||||
 | 
					    if (argc <= 0) return ast_init(AST_TYPE_LIT_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_LIT_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_LIT_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_LIT_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_LIT_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_LIT_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_LIT_NUM:
 | 
				
			||||||
 | 
					            if (*(ASTNumData*)first->data == *(ASTNumData*)second->data)
 | 
				
			||||||
 | 
					                return ast_init(AST_TYPE_LIT_BOOL, ast_bool_data_init(1));
 | 
				
			||||||
 | 
					            else return ast_init(AST_TYPE_LIT_BOOL, ast_bool_data_init(0));
 | 
				
			||||||
 | 
					        case AST_TYPE_LIT_BOOL:
 | 
				
			||||||
 | 
					            if (*(ASTNumData*)first->data == *(ASTNumData*)second->data)
 | 
				
			||||||
 | 
					                return ast_init(AST_TYPE_LIT_BOOL, ast_bool_data_init(1));
 | 
				
			||||||
 | 
					            else return ast_init(AST_TYPE_LIT_BOOL, ast_bool_data_init(0));
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            return ast_init(
 | 
				
			||||||
 | 
					                AST_TYPE_LIT_BOOL, ast_bool_data_init(0)
 | 
				
			||||||
 | 
					            ); // Can't equate nonprimatives. I think. Maybe.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										44
									
								
								src/dlist.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/dlist.c
									
									
									
									
									
										Normal 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++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/dstr.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								src/dstr.c
									
									
									
									
									
								
							@@ -1,13 +1,14 @@
 | 
				
			|||||||
#include "include/dstr.h"
 | 
					#include "include/dstr.h"
 | 
				
			||||||
#include "include/util.h"
 | 
					#include "include/util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Dstr* dstr_init(void) {
 | 
					Dstr* dstr_init(void) {
 | 
				
			||||||
    Dstr* dstr = malloc(sizeof(Dstr));
 | 
					    Dstr* dstr = malloc(sizeof(Dstr));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dstr->bufsz = DSTR_INITSZ;
 | 
					    dstr->sz = DSTR_INITSZ;
 | 
				
			||||||
    dstr->buf = malloc(DSTR_INITSZ);
 | 
					    dstr->buf = malloc(DSTR_INITSZ);
 | 
				
			||||||
    *dstr->buf = '\0';
 | 
					    *dstr->buf = '\0';
 | 
				
			||||||
    dstr->ln = 0;
 | 
					    dstr->ln = 0;
 | 
				
			||||||
@@ -20,14 +21,22 @@ void dstr_destroy(Dstr* dstr) {
 | 
				
			|||||||
    free(dstr);
 | 
					    free(dstr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void dstr_append(Dstr* dest, char* src, size_t ln) {
 | 
					void dstr_destroypsv(Dstr* dstr) { free(dstr); }
 | 
				
			||||||
    while (dest->ln + ln + 1 > dest->bufsz) {
 | 
					
 | 
				
			||||||
 | 
					// Check whether the buffer is overflowing and resize it if necessary.
 | 
				
			||||||
 | 
					void dstr_check_resz(Dstr* dstr, size_t ln) {
 | 
				
			||||||
 | 
					    while (dstr->ln + ln + 1 > dstr->sz) {
 | 
				
			||||||
        // Double the buffer size when overflown.
 | 
					        // Double the buffer size when overflown.
 | 
				
			||||||
        dest->bufsz *= 2;
 | 
					        dstr->sz *= 2;
 | 
				
			||||||
        dest->buf = realloc(dest->buf, dest->bufsz);
 | 
					        dstr->buf = realloc(dstr->buf, dstr->sz);
 | 
				
			||||||
        log_dbgf("dstr @ %p doubled from %ld to %ld", dest, dest->bufsz / 2,
 | 
					        log_dbgf(
 | 
				
			||||||
                 dest->bufsz);
 | 
					            "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
 | 
					    // Overwrites the \0 at the end of the string, keeps the null from the given
 | 
				
			||||||
    // string.
 | 
					    // string.
 | 
				
			||||||
@@ -36,13 +45,7 @@ void dstr_append(Dstr* dest, char* src, size_t ln) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void dstr_appendch(Dstr* dest, char ch) {
 | 
					void dstr_appendch(Dstr* dest, char ch) {
 | 
				
			||||||
    if (dest->ln + 1 + 1 > dest->bufsz) {
 | 
					    dstr_check_resz(dest, 1);
 | 
				
			||||||
        // Double the buffer size when overflown.
 | 
					 | 
				
			||||||
        dest->bufsz *= 2;
 | 
					 | 
				
			||||||
        dest->buf = realloc(dest->buf, dest->bufsz);
 | 
					 | 
				
			||||||
        log_dbgf("dstr @ %p doubled from %ld to %ld", dest, dest->bufsz / 2,
 | 
					 | 
				
			||||||
                 dest->bufsz);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Overwrites the preexisting null terminator, and adds one of its own.
 | 
					    // Overwrites the preexisting null terminator, and adds one of its own.
 | 
				
			||||||
    dest->buf[dest->ln] = ch;
 | 
					    dest->buf[dest->ln] = ch;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										195
									
								
								src/exec.c
									
									
									
									
									
								
							
							
						
						
									
										195
									
								
								src/exec.c
									
									
									
									
									
								
							@@ -1,41 +1,192 @@
 | 
				
			|||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "include/ast.h"
 | 
					#include "include/ast.h"
 | 
				
			||||||
 | 
					#include "include/builtin.h"
 | 
				
			||||||
#include "include/exec.h"
 | 
					#include "include/exec.h"
 | 
				
			||||||
 | 
					#include "include/htab.h"
 | 
				
			||||||
 | 
					#include "include/scope.h"
 | 
				
			||||||
#include "include/util.h"
 | 
					#include "include/util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern AST* root;
 | 
					AST* exec_start(AST* ast) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
ASTNumData exec_expr(AST* ast) {
 | 
					 | 
				
			||||||
    ast_print(ast);
 | 
					 | 
				
			||||||
    log_dbg("Started execution.");
 | 
					    log_dbg("Started execution.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!ast) return ast;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Scope* global = scope_init(NULL);
 | 
				
			||||||
 | 
					    global->uses = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 0; i < BUILTIN_FNS_LN; i++)
 | 
				
			||||||
 | 
					        htab_ins(
 | 
				
			||||||
 | 
					            global->here, BUILTIN_FNS[i].name,
 | 
				
			||||||
 | 
					            ast_init(AST_TYPE_BIF, ast_bif_data_init(BUILTIN_FNS[i].fn))
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AST* defnum =
 | 
				
			||||||
 | 
					        ast_init(AST_TYPE_LIT_KIND, ast_kind_data_init(AST_LIT_KIND_NUM));
 | 
				
			||||||
 | 
					    htab_ins(global->here, "Num", defnum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AST* defbool =
 | 
				
			||||||
 | 
					        ast_init(AST_TYPE_LIT_KIND, ast_kind_data_init(AST_LIT_KIND_BOOL));
 | 
				
			||||||
 | 
					    htab_ins(global->here, "Bool", defbool);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AST* defkind =
 | 
				
			||||||
 | 
					        ast_init(AST_TYPE_LIT_KIND, ast_kind_data_init(AST_LIT_KIND_KIND));
 | 
				
			||||||
 | 
					    htab_ins(global->here, "Type", defkind);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    log_dbg("Completed startup sequence.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AST* res = exec_exp(ast, global);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST* exec_exp(AST* ast, Scope* parent) {
 | 
				
			||||||
    switch (ast->type) {
 | 
					    switch (ast->type) {
 | 
				
			||||||
    case AST_TYPE_CALL: return exec_call(ast);
 | 
					        case AST_TYPE_BLOCK: return exec_block(ast, parent);
 | 
				
			||||||
    case AST_TYPE_NUM:
 | 
					        case AST_TYPE_CALL:  return exec_call(ast, parent);
 | 
				
			||||||
        exec_print(*(ASTNumData*)ast->data);
 | 
					        case AST_TYPE_LIT_NUM:
 | 
				
			||||||
        return *(ASTNumData*)ast->data;
 | 
					            return ast_init(
 | 
				
			||||||
    default: printf("what\n");
 | 
					                AST_TYPE_LIT_NUM, ast_num_data_init(*(ASTNumData*)ast->data)
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        case AST_TYPE_LIT_BOOL:
 | 
				
			||||||
 | 
					            return ast_init(
 | 
				
			||||||
 | 
					                AST_TYPE_LIT_BOOL, ast_bool_data_init(*(ASTBoolData*)ast->data)
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        case AST_TYPE_REF:      return exec_ref(ast, parent);
 | 
				
			||||||
 | 
					        case AST_TYPE_DEF:      return exec_def(ast, parent);
 | 
				
			||||||
 | 
					        case AST_TYPE_BIF:
 | 
				
			||||||
 | 
					        case AST_TYPE_LAMBDA:   return ast;
 | 
				
			||||||
 | 
					        case AST_TYPE_FORCE:    return exec_force(ast, parent);
 | 
				
			||||||
 | 
					        case AST_TYPE_PRESERVE: return exec_preserve(ast, parent);
 | 
				
			||||||
 | 
					        default:                printf("what\n"); exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ASTNumData exec_call(AST* ast) {
 | 
					AST* exec_block(AST* ast, Scope* parent) {
 | 
				
			||||||
    log_dbg("Started call execution.");
 | 
					    ASTBlockData* block = (ASTBlockData*)ast->data;
 | 
				
			||||||
    fflush(stdout);
 | 
					
 | 
				
			||||||
 | 
					    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;
 | 
					    ASTCallData* calldata = (ASTCallData*)ast->data;
 | 
				
			||||||
    if (!strcmp(calldata->to, "+") && calldata->argc == 2) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					    AST* exp = exec_exp(calldata->exp, parent);
 | 
				
			||||||
        ASTNumData* n1 = (ASTNumData*)calldata->argv[0]->data;
 | 
					 | 
				
			||||||
        ASTNumData* n2 = (ASTNumData*)calldata->argv[1]->data;
 | 
					 | 
				
			||||||
        */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ASTNumData n1 = exec_expr(calldata->argv[0]);
 | 
					    switch (exp->type) {
 | 
				
			||||||
        ASTNumData n2 = exec_expr(calldata->argv[1]);
 | 
					        case AST_TYPE_BIF:
 | 
				
			||||||
 | 
					            return ((ASTBIFData)exp->data)(
 | 
				
			||||||
        return n1 + n2;
 | 
					                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)
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return -1000;
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST* exec_def(AST* ast, Scope* parent) {
 | 
				
			||||||
 | 
					    // Use parent's scope.
 | 
				
			||||||
 | 
					    exec_inherit_scope(ast, parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ASTDefData* data = (ASTDefData*)ast->data;
 | 
				
			||||||
 | 
					    AST* val = data->exp;
 | 
				
			||||||
 | 
					    char* key = data->name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (data->kind) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ASTKindData kind = *(ASTKindData*)exec_exp(data->kind, parent)->data ==
 | 
				
			||||||
 | 
					                           AST_LIT_KIND_NUM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (kind == AST_LIT_KIND_NUM && data->exp->type != AST_TYPE_LIT_NUM)
 | 
				
			||||||
 | 
					            return ast_init(
 | 
				
			||||||
 | 
					                AST_TYPE_EXC, ast_exc_data_init("Expected Num.", NULL)
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (kind == AST_LIT_KIND_BOOL && data->exp->type != AST_TYPE_LIT_BOOL)
 | 
				
			||||||
 | 
					            return ast_init(
 | 
				
			||||||
 | 
					                AST_TYPE_EXC, ast_exc_data_init("Expected Bool.", NULL)
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (kind == AST_LIT_KIND_KIND && data->exp->type != AST_TYPE_LIT_KIND)
 | 
				
			||||||
 | 
					            return ast_init(
 | 
				
			||||||
 | 
					                AST_TYPE_EXC, ast_exc_data_init("Expected Type.", NULL)
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    scope_add(parent, key, val); // Add variable definition to parent scope.
 | 
				
			||||||
 | 
					    return exec_exp(val, parent);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST* exec_ref(AST* ast, Scope* parent) {
 | 
				
			||||||
 | 
					    // Use parent's scope.
 | 
				
			||||||
 | 
					    exec_inherit_scope(ast, parent);
 | 
				
			||||||
 | 
					    log_dbg("attempting to reference var");
 | 
				
			||||||
 | 
					    ASTRefData* ref = (ASTRefData*)ast->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AST* found = ast_find(parent, ref->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`.", ref->to
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        return ast_init(AST_TYPE_EXC, ast_exc_data_init(msg, NULL));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // return exec_exp(found, ast->scope);
 | 
				
			||||||
 | 
					    return found;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST* exec_force(AST* ast, Scope* parent) {
 | 
				
			||||||
 | 
					    AST* body = ((ASTForceData*)ast->data)->body;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (body->type == AST_TYPE_REF) {
 | 
				
			||||||
 | 
					        return exec_exp(exec_ref(body, parent), parent);
 | 
				
			||||||
 | 
					    } else return exec_exp(body, parent);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST* exec_preserve(AST* ast, Scope* parent) {
 | 
				
			||||||
 | 
					    return ((ASTPreserveData*)ast->data)->body;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void exec_print(double n) { printf("= %lf\n", n); }
 | 
					void exec_print(double n) { printf("= %lf\n", n); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline void exec_new_scope(AST* ast, Scope* inherit) {
 | 
				
			||||||
 | 
					    Scope* scope = scope_init(inherit);
 | 
				
			||||||
 | 
					    ast->scope = scope;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Update linked status.
 | 
				
			||||||
 | 
					    scope->uses++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline void exec_inherit_scope(AST* ast, Scope* inherit) {
 | 
				
			||||||
 | 
					    ast->scope = inherit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Update uses.
 | 
				
			||||||
 | 
					    inherit->uses++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								src/fnv1a.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/fnv1a.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					#include "include/fnv1a.h"
 | 
				
			||||||
 | 
					#include "include/util.h"
 | 
				
			||||||
 | 
					#include "include/util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <stdio.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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    log_dbgf("Hash of %s was %lu", key, hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return hash;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								src/gc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/gc.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					#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* 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:
 | 
				
			||||||
 | 
					                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
									
								
							
							
						
						
									
										6
									
								
								src/global.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					#include "include/global.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Global input text.
 | 
				
			||||||
 | 
					char* inp = NULL;
 | 
				
			||||||
							
								
								
									
										406
									
								
								src/grammar.y
									
									
									
									
									
								
							
							
						
						
									
										406
									
								
								src/grammar.y
									
									
									
									
									
								
							@@ -1,7 +1,10 @@
 | 
				
			|||||||
%{
 | 
					%{
 | 
				
			||||||
 | 
					    #include <string.h>
 | 
				
			||||||
    #include <stdio.h>
 | 
					    #include <stdio.h>
 | 
				
			||||||
    #include "../../src/include/ast.h"
 | 
					    #include "../../src/include/ast.h"
 | 
				
			||||||
    #include "../../src/include/lexer.h"
 | 
					    #include "../../src/include/lexer.h"
 | 
				
			||||||
 | 
					    #include "../../src/include/dlist.h"
 | 
				
			||||||
 | 
					    #include "../../src/include/builtin.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int yylex(void);
 | 
					    int yylex(void);
 | 
				
			||||||
    void yyerror(char const*);
 | 
					    void yyerror(char const*);
 | 
				
			||||||
@@ -11,48 +14,399 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
%code requires {
 | 
					%code requires {
 | 
				
			||||||
    #include "../../src/include/ast.h"
 | 
					    #include "../../src/include/ast.h"
 | 
				
			||||||
 | 
					    #include "../../src/include/dlist.h"
 | 
				
			||||||
 | 
					    #include "../../src/include/builtin.h"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%union {
 | 
					%union {
 | 
				
			||||||
    double fval;
 | 
					    double fval;
 | 
				
			||||||
    char* strval;
 | 
					    char* strval;
 | 
				
			||||||
    AST* ast;
 | 
					    AST* ast;
 | 
				
			||||||
 | 
					    ArgArr* argarr;
 | 
				
			||||||
 | 
					    DList* exps;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%define parse.error verbose
 | 
					%define parse.error verbose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%token<fval> NUM
 | 
					%token BOOLT // Boolean true (TRUE or T).
 | 
				
			||||||
%token<strval> CALL
 | 
					%token BOOLF // Boolean false (FALSE or F).
 | 
				
			||||||
%token PLUS
 | 
					
 | 
				
			||||||
%token NL
 | 
					%token IF // if or ?.
 | 
				
			||||||
%type<ast> exp
 | 
					%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 RARROW // Right arrow ->.
 | 
				
			||||||
 | 
					%token LARROW // Left arrow <-.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%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 COLON // Colon :.
 | 
				
			||||||
 | 
					%token STOP // Stop sign $.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%token FORCE // Force operator !.
 | 
				
			||||||
 | 
					%token PRESERVE // Preserve operator @.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%token BACKSLASH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%left ADD SUB
 | 
				
			||||||
 | 
					%left MUL DIV
 | 
				
			||||||
 | 
					%left RARROW
 | 
				
			||||||
 | 
					%right LARROW
 | 
				
			||||||
 | 
					%nonassoc STOP
 | 
				
			||||||
 | 
					%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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%%
 | 
					%%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
input:
 | 
					maybe_stop: %empty | STOP;
 | 
				
			||||||
    %empty
 | 
					
 | 
				
			||||||
    | exp { root = $1; }
 | 
					inputstart:
 | 
				
			||||||
 | 
					    exp {
 | 
				
			||||||
 | 
					        DList* exps = dlist_init();
 | 
				
			||||||
 | 
					        dlist_append(exps, $1);
 | 
				
			||||||
 | 
					        $$ = exps;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    ;
 | 
					    ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
exp:
 | 
					input:
 | 
				
			||||||
    NUM { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); }
 | 
					    inputstart {
 | 
				
			||||||
    | NUM PLUS NUM {
 | 
					        $$ = $1;
 | 
				
			||||||
        AST* argv[2] = {
 | 
					 | 
				
			||||||
            ast_init(AST_TYPE_NUM, ast_num_data_init($1)),
 | 
					 | 
				
			||||||
            ast_init(AST_TYPE_NUM, ast_num_data_init($3))
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        $$ = ast_init(AST_TYPE_CALL, ast_call_data_init("+", 2, argv));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /*| NUM PLUS exp {
 | 
					    | input EXPSEP exp {
 | 
				
			||||||
        AST* argv[2] = {
 | 
					        dlist_append($1, $3);
 | 
				
			||||||
            ast_init(AST_TYPE_NUM, ast_num_data_init($1)),
 | 
					        $$ = $1;
 | 
				
			||||||
            $3
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        $$ = ast_init(AST_TYPE_CALL, ast_call_data_init("+", 2, argv));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    | exp PLUS exp {
 | 
					    ;
 | 
				
			||||||
        AST* argv[2] = { $1, $3 };
 | 
					 | 
				
			||||||
        $$ = ast_init(AST_TYPE_CALL, ast_call_data_init("+", 2, argv));
 | 
					 | 
				
			||||||
    };*/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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:
 | 
				
			||||||
 | 
					    // Stop sign.
 | 
				
			||||||
 | 
					    exp STOP { $$ = $1; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Variable reference.
 | 
				
			||||||
 | 
					    | WORD {
 | 
				
			||||||
 | 
					        $$ = ast_init(AST_TYPE_REF, ast_ref_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 (general hacky form).
 | 
				
			||||||
 | 
					    | exp GROUPS GROUPE {
 | 
				
			||||||
 | 
					        size_t argc = 1;
 | 
				
			||||||
 | 
					        AST** argv = NULL;
 | 
				
			||||||
 | 
					        $$ = ast_init(AST_TYPE_CALL, ast_call_data_init(
 | 
				
			||||||
 | 
					            argc,
 | 
				
			||||||
 | 
					            argv,
 | 
				
			||||||
 | 
					            $1
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Call (right arrow general form).
 | 
				
			||||||
 | 
					    | GROUPS arg GROUPE RARROW exp {
 | 
				
			||||||
 | 
					        size_t argc = $2->ln;
 | 
				
			||||||
 | 
					        AST** argv = $2->buf;
 | 
				
			||||||
 | 
					        argarr_destroypsv($2);
 | 
				
			||||||
 | 
					        $$ = ast_init(AST_TYPE_CALL, ast_call_data_init(
 | 
				
			||||||
 | 
					            argc,
 | 
				
			||||||
 | 
					            argv,
 | 
				
			||||||
 | 
					            $5
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    | exp RARROW exp {
 | 
				
			||||||
 | 
					        size_t argc = 1;
 | 
				
			||||||
 | 
					        AST** argv = malloc(sizeof(AST*));
 | 
				
			||||||
 | 
					        argv[0] = $1;
 | 
				
			||||||
 | 
					        $$ = ast_init(AST_TYPE_CALL, ast_call_data_init(
 | 
				
			||||||
 | 
					            argc,
 | 
				
			||||||
 | 
					            argv,
 | 
				
			||||||
 | 
					            $3
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    | exp LARROW exp {
 | 
				
			||||||
 | 
					        size_t argc = 1;
 | 
				
			||||||
 | 
					        AST** argv = malloc(sizeof(AST*));
 | 
				
			||||||
 | 
					        argv[0] = $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_REF, ast_ref_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_REF, ast_ref_data_init($1))
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Number.
 | 
				
			||||||
 | 
					    | NUM { $$ = ast_init(AST_TYPE_LIT_NUM, ast_num_data_init($1)); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    | BOOLT { $$ = ast_init(AST_TYPE_LIT_BOOL, ast_bool_data_init(1)); }
 | 
				
			||||||
 | 
					    | BOOLF { $$ = ast_init(AST_TYPE_LIT_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))
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Function definitions. Convert to Def of Lambda.
 | 
				
			||||||
 | 
					    | WORD GROUPS arg GROUPE exp maybe_stop {
 | 
				
			||||||
 | 
					        size_t parc = $3->ln;
 | 
				
			||||||
 | 
					        AST** parv = $3->buf;
 | 
				
			||||||
 | 
					        argarr_destroypsv($3);
 | 
				
			||||||
 | 
					        $$ = ast_init(AST_TYPE_DEF, ast_def_data_init(
 | 
				
			||||||
 | 
					            $1,
 | 
				
			||||||
 | 
					            NULL,
 | 
				
			||||||
 | 
					            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));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Force operator.
 | 
				
			||||||
 | 
					    | FORCE exp {
 | 
				
			||||||
 | 
					        $$ = ast_init(AST_TYPE_FORCE, ast_force_data_init($2));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Preserve operator.
 | 
				
			||||||
 | 
					    | PRESERVE exp {
 | 
				
			||||||
 | 
					        $$ = ast_init(AST_TYPE_PRESERVE, ast_preserve_data_init($2));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Block.
 | 
				
			||||||
 | 
					    | BLOCKS block BLOCKE {
 | 
				
			||||||
 | 
					        AST** exps = (AST**) $2->buf;
 | 
				
			||||||
 | 
					        dlist_destroypsv($2);
 | 
				
			||||||
 | 
					        $$ = ast_init(AST_TYPE_BLOCK, ast_block_data_init((AST**) exps, $2->ln));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Negative.
 | 
				
			||||||
 | 
					    | SUB exp {
 | 
				
			||||||
 | 
					        AST** argv = calloc(2, sizeof(AST*));
 | 
				
			||||||
 | 
					        argv[0] = ast_init(AST_TYPE_LIT_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; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Definition with type annotation.
 | 
				
			||||||
 | 
					    | WORD COLON exp EQ exp {
 | 
				
			||||||
 | 
					        $$ = ast_init(AST_TYPE_DEF, ast_def_data_init($1, $3, $5));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Definition with type annotation.
 | 
				
			||||||
 | 
					    | WORD COLON WORD EQ exp {
 | 
				
			||||||
 | 
					        $$ = ast_init(AST_TYPE_DEF, ast_def_data_init(
 | 
				
			||||||
 | 
					            $1,
 | 
				
			||||||
 | 
					            ast_init(AST_TYPE_REF, ast_ref_data_init($3)),
 | 
				
			||||||
 | 
					            $5
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Definition.
 | 
				
			||||||
 | 
					    | WORD EQ exp {
 | 
				
			||||||
 | 
					        $$ = ast_init(AST_TYPE_DEF, ast_def_data_init($1, NULL, $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
									
								
							
							
						
						
									
										36
									
								
								src/htab.c
									
									
									
									
									
										Normal 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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,38 +1,193 @@
 | 
				
			|||||||
#ifndef AST_H
 | 
					#ifndef AST_H
 | 
				
			||||||
#define AST_H
 | 
					#define AST_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "scope.h"
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The type of an `AST`.
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
    AST_TYPE_NUM,
 | 
					    // Primitive type literals.
 | 
				
			||||||
    AST_TYPE_CALL,
 | 
					    AST_TYPE_LIT_NUM,  // A number (float) literal.
 | 
				
			||||||
    AST_TYPE_MAX = AST_TYPE_CALL
 | 
					    AST_TYPE_LIT_BOOL, // A boolean literal.
 | 
				
			||||||
 | 
					    AST_TYPE_LIT_VEC,  // A vector literal.
 | 
				
			||||||
 | 
					    AST_TYPE_LIT_KIND, // A kind literal.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AST_TYPE_EXC_CON,  // Exception constructor `Exc`.
 | 
				
			||||||
 | 
					    AST_TYPE_VEC_CON,  // Vectpr constructor `Vec()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Collection types:
 | 
				
			||||||
 | 
					    AST_TYPE_VEC,  // A vector (fixed size, fixed type).
 | 
				
			||||||
 | 
					    AST_TYPE_LIST, // A list (variable size, variable type).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Syntactic types:
 | 
				
			||||||
 | 
					    AST_TYPE_FORCE,
 | 
				
			||||||
 | 
					    AST_TYPE_PRESERVE,
 | 
				
			||||||
 | 
					    AST_TYPE_BLOCK,  // A block of code (scope).
 | 
				
			||||||
 | 
					    AST_TYPE_ARG,    // A definition argument.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Misc. types.
 | 
				
			||||||
 | 
					    AST_TYPE_BIF,    // Built-in function.
 | 
				
			||||||
 | 
					    AST_TYPE_CALL,   // A function call.
 | 
				
			||||||
 | 
					    AST_TYPE_DEF,   // A definition.
 | 
				
			||||||
 | 
					    AST_TYPE_REF,   // A variable reference.
 | 
				
			||||||
 | 
					    AST_TYPE_LAMBDA, // An anonymous function definition.
 | 
				
			||||||
 | 
					    AST_TYPE_EXC,   // An exception.
 | 
				
			||||||
 | 
					    AST_TYPE_MAX = AST_TYPE_EXC,
 | 
				
			||||||
} ASTType;
 | 
					} ASTType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// An Abstract Syntax Tree.
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    ASTType type;
 | 
					    ASTType type; // The type of the `AST`.
 | 
				
			||||||
    void* data;
 | 
					    void* data;   // The data of the `AST`.
 | 
				
			||||||
 | 
					    Scope* scope; // The scope of the `AST`.
 | 
				
			||||||
} AST;
 | 
					} AST;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create a new `AST`.
 | 
				
			||||||
AST* ast_init(ASTType type, void* data);
 | 
					AST* ast_init(ASTType type, void* data);
 | 
				
			||||||
 | 
					// Create a new `AST` with a specified scope.
 | 
				
			||||||
 | 
					AST* ast_init_scope(ASTType type, void* data, Scope* scope);
 | 
				
			||||||
 | 
					// Destroy an `AST`.
 | 
				
			||||||
void ast_destroy(AST* ast);
 | 
					void ast_destroy(AST* ast);
 | 
				
			||||||
void ast_print(AST* ast);
 | 
					 | 
				
			||||||
void ast_print_i(AST* ast, int i);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A number.
 | 
				
			||||||
typedef double ASTNumData;
 | 
					typedef double ASTNumData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create a new `ASTNumData`.
 | 
				
			||||||
ASTNumData* ast_num_data_init(double val);
 | 
					ASTNumData* ast_num_data_init(double val);
 | 
				
			||||||
 | 
					// Destroy an `ASTNumData`.
 | 
				
			||||||
void ast_num_data_destroy(ASTNumData* num);
 | 
					void ast_num_data_destroy(ASTNumData* num);
 | 
				
			||||||
void ast_num_print(ASTNumData*, int i);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A literal kind.
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    AST_LIT_KIND_BOOL,
 | 
				
			||||||
 | 
					    AST_LIT_KIND_NUM,
 | 
				
			||||||
 | 
					    AST_LIT_KIND_KIND,
 | 
				
			||||||
 | 
					    AST_LIT_KIND_MAX = AST_LIT_KIND_KIND
 | 
				
			||||||
 | 
					} ASTKindData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern const char* ast_lit_kind_names[AST_LIT_KIND_MAX + 2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create a new `ASTKindData`.
 | 
				
			||||||
 | 
					ASTKindData* ast_kind_data_init(ASTKindData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Destroy an `ASTKindData`.
 | 
				
			||||||
 | 
					void ast_kind_data_destroy(ASTKindData*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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 {
 | 
					typedef struct {
 | 
				
			||||||
    char* to;       // What the call's to.
 | 
					    PARS;      // The parameters the lambda can accept.
 | 
				
			||||||
    size_t argc;    // Argument count.
 | 
					    AST* body; // The body expression to be executed.
 | 
				
			||||||
    AST** argv;     // Argument vector.
 | 
					} 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;
 | 
					} ASTCallData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ASTCallData* ast_call_data_init(char* to, size_t argc, AST** argv);
 | 
					// 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);
 | 
					void ast_call_data_destroy(ASTCallData* call);
 | 
				
			||||||
void ast_call_print(ASTCallData*, int i);
 | 
					
 | 
				
			||||||
 | 
					// A definition. Associates a name and kind with an expression.
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    char* name;
 | 
				
			||||||
 | 
					    AST* kind; // If NULL, assume `Any` kind.
 | 
				
			||||||
 | 
					    AST* exp;
 | 
				
			||||||
 | 
					} ASTDefData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create a new `ASTDefData`.
 | 
				
			||||||
 | 
					ASTDefData* ast_def_data_init(char* name, AST* kind, AST* exp);
 | 
				
			||||||
 | 
					// Destroy an `ASTDefData`.
 | 
				
			||||||
 | 
					void ast_def_data_destroy(ASTDefData* vdef);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A reference.
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    char* to; // What the reference's to.
 | 
				
			||||||
 | 
					} ASTRefData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create a new `ASTRefData`.
 | 
				
			||||||
 | 
					ASTRefData* ast_ref_data_init(char* to);
 | 
				
			||||||
 | 
					// Destroy an `ASTRefData`.
 | 
				
			||||||
 | 
					void ast_ref_data_destroy(ASTRefData* 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A force operator.
 | 
				
			||||||
 | 
					typedef struct {AST* body;} ASTForceData;
 | 
				
			||||||
 | 
					ASTForceData* ast_force_data_init(AST* body);
 | 
				
			||||||
 | 
					void ast_force_data_destroy(ASTForceData* force);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A preserve operator.
 | 
				
			||||||
 | 
					typedef struct {AST* body;} ASTPreserveData;
 | 
				
			||||||
 | 
					ASTPreserveData* ast_preserve_data_init(AST* body);
 | 
				
			||||||
 | 
					void ast_preserve_data_destroy(ASTPreserveData* preserve);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										49
									
								
								src/include/ast_print.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/include/ast_print.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					#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 `ASTKindData`.
 | 
				
			||||||
 | 
					void ast_kind_print(ASTKindData*, int i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Print an `ASTExecData`.
 | 
				
			||||||
 | 
					void ast_exc_print(ASTExcData*, int i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Print an `ASTCallData`.
 | 
				
			||||||
 | 
					void ast_call_print(ASTCallData*, int i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Print an `ASTDefData`.
 | 
				
			||||||
 | 
					void ast_def_print(ASTDefData*, int depth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Print an `ASTRefData`.
 | 
				
			||||||
 | 
					void ast_ref_print(ASTRefData*, int i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Print an `ASTBlockData`.
 | 
				
			||||||
 | 
					void ast_block_print(ASTBlockData*, 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Print an `ASTForceData`.
 | 
				
			||||||
 | 
					void ast_force_print(ASTForceData* force, int i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Print an `ASTPreserveData`.
 | 
				
			||||||
 | 
					void ast_preserve_print(ASTPreserveData* preserve, int i);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										44
									
								
								src/include/builtin.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/include/builtin.h
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										24
									
								
								src/include/dlist.h
									
									
									
									
									
										Normal 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
 | 
				
			||||||
@@ -7,17 +7,21 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    char* buf; // The buffer containing the string.
 | 
					    char* buf; // The buffer containing the string.
 | 
				
			||||||
    size_t bufsz; // The size of the buffer.
 | 
					    size_t sz; // The size of the buffer.
 | 
				
			||||||
    size_t ln; // The number of characters in the buffer.
 | 
					    size_t ln; // The number of characters in the buffer.
 | 
				
			||||||
} Dstr;
 | 
					} Dstr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Initialize a `DStr`.
 | 
				
			||||||
Dstr* dstr_init(void);
 | 
					Dstr* dstr_init(void);
 | 
				
			||||||
 | 
					// Destroy a `DStr`.
 | 
				
			||||||
void dstr_destroy(Dstr* dstr);
 | 
					void dstr_destroy(Dstr* dstr);
 | 
				
			||||||
 | 
					// Destroy `DStr` structure but preserve `DStr->buf`.
 | 
				
			||||||
 | 
					void dstr_destroypsv(Dstr* dstr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Append ln characters of src to dest.
 | 
					// Append `ln` characters of `src` to `dest`.
 | 
				
			||||||
void dstr_append(Dstr* dest, char* src, size_t ln);
 | 
					void dstr_append(Dstr* dest, char* src, size_t ln);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Append ch to dest.
 | 
					// Append `ch` to `dest`.
 | 
				
			||||||
void dstr_appendch(Dstr* dest, char ch);
 | 
					void dstr_appendch(Dstr* dest, char ch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,9 +2,35 @@
 | 
				
			|||||||
#define EXEC_H
 | 
					#define EXEC_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "ast.h"
 | 
					#include "ast.h"
 | 
				
			||||||
 | 
					#include "scope.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ASTNumData exec_expr(AST* ast);
 | 
					// Start executing at the root of the AST. Initialize the `scope`.
 | 
				
			||||||
ASTNumData exec_call(AST* ast);
 | 
					AST* exec_start(AST* ast);
 | 
				
			||||||
 | 
					// Execute an expression. Delegates to the other executor functions.
 | 
				
			||||||
 | 
					AST* exec_exp(AST* ast, Scope* parent);
 | 
				
			||||||
 | 
					// Execute the expressions of a block.
 | 
				
			||||||
 | 
					AST* exec_block(AST* ast, Scope* parent);
 | 
				
			||||||
 | 
					// Execute a call.
 | 
				
			||||||
 | 
					AST* exec_call(AST* ast, Scope* parent);
 | 
				
			||||||
 | 
					// Execute a definition.
 | 
				
			||||||
 | 
					AST* exec_def(AST* ast, Scope* parent);
 | 
				
			||||||
 | 
					// Execute a reference.
 | 
				
			||||||
 | 
					AST* exec_ref(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);
 | 
				
			||||||
 | 
					// Execute a force expression.
 | 
				
			||||||
 | 
					AST* exec_force(AST* ast, Scope* parent);
 | 
				
			||||||
 | 
					// Execute a preserve expression.
 | 
				
			||||||
 | 
					AST* exec_preserve(AST* ast, Scope* parent);
 | 
				
			||||||
 | 
					// Print the result of an execution.
 | 
				
			||||||
void exec_print(double n);
 | 
					void exec_print(double n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create a new scope and mark it as linked. Also update inherited scope.
 | 
				
			||||||
 | 
					void exec_new_scope(AST* ast, Scope* inherit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Inherit from another scope and mark it as linked.
 | 
				
			||||||
 | 
					void exec_inherit_scope(AST* ast, Scope* inherit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								src/include/fnv1a.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/include/fnv1a.h
									
									
									
									
									
										Normal 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
 | 
				
			||||||
							
								
								
									
										32
									
								
								src/include/gc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/include/gc.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					#ifndef GC_H
 | 
				
			||||||
 | 
					#define GC_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <stdbool.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
									
								
							
							
						
						
									
										4
									
								
								src/include/global.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					#ifndef GLOBAL_H
 | 
				
			||||||
 | 
					#define GLOBAL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										29
									
								
								src/include/htab.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/include/htab.h
									
									
									
									
									
										Normal 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
 | 
				
			||||||
@@ -2,20 +2,29 @@
 | 
				
			|||||||
#define LEXER_H
 | 
					#define LEXER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ast.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARLN 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern char* inp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    size_t sz;
 | 
				
			||||||
 | 
					    size_t ln;
 | 
				
			||||||
 | 
					    AST** buf;
 | 
				
			||||||
 | 
					} ArgArr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ArgArr* argarr_init();
 | 
				
			||||||
 | 
					void argarr_destroy(ArgArr* argarr);
 | 
				
			||||||
 | 
					// Destroy ArgArr structure but preserve -> buf.
 | 
				
			||||||
 | 
					void argarr_destroypsv(ArgArr* argarr);
 | 
				
			||||||
 | 
					void argarr_add(ArgArr* argarr, AST* arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __has_include
 | 
					 | 
				
			||||||
    #if __has_include("../../build/grammars/grammar.tab.h")
 | 
					 | 
				
			||||||
#include "../../build/grammars/grammar.tab.h"
 | 
					#include "../../build/grammars/grammar.tab.h"
 | 
				
			||||||
    #else
 | 
					 | 
				
			||||||
        #warn "Build resources not present!"
 | 
					 | 
				
			||||||
    #endif
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    #warn "Not sure whether build-time resources are present."
 | 
					 | 
				
			||||||
    #include "../../build/grammars/grammar.tab.h"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern YYSTYPE yylval;
 | 
					extern YYSTYPE yylval;
 | 
				
			||||||
extern char* inp;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Accumulate an integer.
 | 
					// Accumulate an integer.
 | 
				
			||||||
int acc_int(int c);
 | 
					int acc_int(int c);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								src/include/scope.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/include/scope.h
									
									
									
									
									
										Normal 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
 | 
				
			||||||
@@ -6,18 +6,19 @@
 | 
				
			|||||||
#define STACK_MAX 64
 | 
					#define STACK_MAX 64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    size_t i;               // Current index in the stack.
 | 
					    size_t ln;            // The length of the stack (i.e., how many elements).
 | 
				
			||||||
    void* val[STACK_MAX];   // The stack itself.
 | 
					    void* buf[STACK_MAX]; // The stack itself.
 | 
				
			||||||
} Stack;
 | 
					} Stack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create a `Stack`.
 | 
				
			||||||
Stack* stack_init();
 | 
					Stack* stack_init();
 | 
				
			||||||
// Destroy a stack.
 | 
					// Destroy a `Stack`.
 | 
				
			||||||
// Note that `stack->i` must be `0`.
 | 
					// Note that `->i` must be `0`, i.e. the `Stack` must be empty.
 | 
				
			||||||
void stack_destroy(Stack* stack);
 | 
					void stack_destroy(Stack* stack);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Push a value to the stack.
 | 
					// Push a value to the `Stack`.
 | 
				
			||||||
void stack_push(Stack* stack, void* val);
 | 
					void stack_push(Stack* stack, void* val);
 | 
				
			||||||
// Pop a value from the stack.
 | 
					// Pop a value from the `Stack`.
 | 
				
			||||||
void* stack_pop(Stack* stack);
 | 
					void* stack_pop(Stack* stack);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,17 +1,35 @@
 | 
				
			|||||||
#ifndef UTIL_H
 | 
					#ifndef UTIL_H
 | 
				
			||||||
#define UTIL_H
 | 
					#define UTIL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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
 | 
					#ifdef DBG // Debug macros
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Log a message.
 | 
					// Log a message.
 | 
				
			||||||
#define log_dbg(msg)                                                           \
 | 
					#define log_dbg(msg)                                                           \
 | 
				
			||||||
    printf("\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n", \
 | 
					    printf(                                                                    \
 | 
				
			||||||
           __func__);
 | 
					        "\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n",    \
 | 
				
			||||||
 | 
					        __func__                                                               \
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Log a message with formatting.
 | 
					// Log a message with formatting.
 | 
				
			||||||
#define log_dbgf(msg, ...)                                                     \
 | 
					#define log_dbgf(msg, ...)                                                     \
 | 
				
			||||||
    printf("\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n", \
 | 
					    printf(                                                                    \
 | 
				
			||||||
           __func__, __VA_ARGS__);
 | 
					        "\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n",    \
 | 
				
			||||||
 | 
					        __func__, __VA_ARGS__                                                  \
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else // ifdef DBG
 | 
					#else // ifdef DBG
 | 
				
			||||||
#define log_dbg(msg)
 | 
					#define log_dbg(msg)
 | 
				
			||||||
@@ -50,18 +68,25 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Print & indent the title of a section.
 | 
					// Print & indent the title of a section.
 | 
				
			||||||
#define INDENT_TITLE(THING, WHERE)                                             \
 | 
					#define INDENT_TITLE(THING, WHERE)                                             \
 | 
				
			||||||
    printf("%s" COL_BCYA THING COL_RESET " @" COL_MAG " %p\n" COL_RESET, INDENT_spacing->buf, WHERE);
 | 
					    printf(                                                                    \
 | 
				
			||||||
 | 
					        "%s" COL_BCYA THING COL_RESET " @" COL_MAG " %p\n" COL_RESET,          \
 | 
				
			||||||
 | 
					        INDENT_spacing->buf, WHERE                                             \
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Print & indent a thing.
 | 
					// Print & indent a thing.
 | 
				
			||||||
#define INDENT_FIELD(FIELD, VAL, ...)                                          \
 | 
					#define INDENT_FIELD(FIELD, VAL, ...)                                          \
 | 
				
			||||||
    printf("%s " COL_BWHI FIELD ": " COL_RESET COL_WHI VAL COL_RESET "\n",     \
 | 
					    printf(                                                                    \
 | 
				
			||||||
           INDENT_spacing->buf, __VA_ARGS__);
 | 
					        "%s " COL_BWHI FIELD ": " COL_RESET COL_WHI VAL COL_RESET "\n",        \
 | 
				
			||||||
 | 
					        INDENT_spacing->buf, __VA_ARGS__                                       \
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Print & indent a thing with a newline before the val.
 | 
					// Print & indent a thing with a newline before the val.
 | 
				
			||||||
#define INDENT_FIELD_NL(FIELD, VAL, ...)                                       \
 | 
					#define INDENT_FIELD_NL(FIELD, VAL, ...)                                       \
 | 
				
			||||||
    printf("%s " COL_BWHI FIELD ":" COL_RESET "\n %s " COL_WHI VAL COL_RESET   \
 | 
					    printf(                                                                    \
 | 
				
			||||||
 | 
					        "%s " COL_BWHI FIELD ":" COL_RESET "\n %s " COL_WHI VAL COL_RESET      \
 | 
				
			||||||
        "\n",                                                                  \
 | 
					        "\n",                                                                  \
 | 
				
			||||||
           INDENT_spacing->buf, INDENT_spacing->buf, __VA_ARGS__);
 | 
					        INDENT_spacing->buf, INDENT_spacing->buf, __VA_ARGS__                  \
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Print & indent a thing without any newline.
 | 
					// Print & indent a thing without any newline.
 | 
				
			||||||
#define INDENT_FIELD_EXT_NONL_START(FIELD)                                     \
 | 
					#define INDENT_FIELD_EXT_NONL_START(FIELD)                                     \
 | 
				
			||||||
@@ -77,9 +102,14 @@
 | 
				
			|||||||
    printf(COL_BWHI "%s ]\n" COL_RESET, INDENT_spacing->buf);
 | 
					    printf(COL_BWHI "%s ]\n" COL_RESET, INDENT_spacing->buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// End an indent block.
 | 
					// End an indent block.
 | 
				
			||||||
#define INDENT_END printf(COL_RESET); dstr_destroy(INDENT_spacing);
 | 
					#define INDENT_END                                                             \
 | 
				
			||||||
 | 
					    printf(COL_RESET);                                                         \
 | 
				
			||||||
 | 
					    dstr_destroy(INDENT_spacing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Allocate a pointer with a type.
 | 
					#define INDENT_FIELD_LIST_OPEN(FIELD)                                          \
 | 
				
			||||||
#define talloc(T, X) T* X = malloc(sizeof(T));
 | 
					    printf("%s " COL_BWHI FIELD ": [\n" COL_RESET, INDENT_spacing->buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define INDENT_FIELD_LIST_CLOSE                                                \
 | 
				
			||||||
 | 
					    printf(COL_BWHI "%s ]\n" COL_RESET, INDENT_spacing->buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										114
									
								
								src/lexer.c
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								src/lexer.c
									
									
									
									
									
								
							@@ -1,9 +1,43 @@
 | 
				
			|||||||
 | 
					#include <complex.h>
 | 
				
			||||||
#include <ctype.h>
 | 
					#include <ctype.h>
 | 
				
			||||||
#include <limits.h>
 | 
					#include <limits.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <math.h>
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "include/dstr.h"
 | 
				
			||||||
#include "include/lexer.h"
 | 
					#include "include/lexer.h"
 | 
				
			||||||
 | 
					#include "include/util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ArgArr* argarr_init() {
 | 
				
			||||||
 | 
					    ArgArr* argarr = malloc(sizeof(ArgArr));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    argarr->sz = ARLN * sizeof(AST*);
 | 
				
			||||||
 | 
					    argarr->ln = 0;
 | 
				
			||||||
 | 
					    argarr->buf = malloc(argarr->sz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return argarr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void argarr_destroy(ArgArr* argarr) {
 | 
				
			||||||
 | 
					    free(argarr->buf);
 | 
				
			||||||
 | 
					    free(argarr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void argarr_destroypsv(ArgArr* argarr) { free(argarr); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void argarr_add(ArgArr* argarr, AST* arg) {
 | 
				
			||||||
 | 
					    if ((argarr->ln + 1) * sizeof(AST*) > argarr->sz) {
 | 
				
			||||||
 | 
					        argarr->sz *= 2;
 | 
				
			||||||
 | 
					        argarr->buf = realloc(argarr->buf, argarr->sz);
 | 
				
			||||||
 | 
					        log_dbgf(
 | 
				
			||||||
 | 
					            "ArgArr @ %p doubled from %ld to %ld", argarr, argarr->sz / 2,
 | 
				
			||||||
 | 
					            argarr->sz
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    argarr->buf[argarr->ln++] = arg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int acc_int(int c) {
 | 
					int acc_int(int c) {
 | 
				
			||||||
    int value = c - '0';
 | 
					    int value = c - '0';
 | 
				
			||||||
@@ -28,46 +62,94 @@ double acc_float(int c) {
 | 
				
			|||||||
        inp++;
 | 
					        inp++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while (isdigit(*inp)) {
 | 
					        while (isdigit(*inp)) {
 | 
				
			||||||
            // TODO:
 | 
					 | 
				
			||||||
            // Accumulate as int, divide once at end.
 | 
					 | 
				
			||||||
            // value = value + (((double)(*inp - '0'))/pow(10.0l, (double)(inp-oinp))); // Accumulate value.
 | 
					 | 
				
			||||||
            value = value * 10 + (*inp - '0'); // Accumulate value.
 | 
					            value = value * 10 + (*inp - '0'); // Accumulate value.
 | 
				
			||||||
            dplaces++;
 | 
					            dplaces++;
 | 
				
			||||||
            inp++;
 | 
					            inp++;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        value = value / pow(10, dplaces);
 | 
					        value = value / pow(10, dplaces);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // > 1.20000
 | 
					 | 
				
			||||||
    // = 1.0 + 2/10
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // > 1.23
 | 
					 | 
				
			||||||
    // = 1.2 + 3/100
 | 
					 | 
				
			||||||
    return value;
 | 
					    return value;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char* acc_word(int c) {
 | 
				
			||||||
 | 
					    Dstr* val = dstr_init();
 | 
				
			||||||
 | 
					    while (isalpha(*inp) || *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() {
 | 
					int yylex() {
 | 
				
			||||||
    if (*inp == '\0') return YYEOF;
 | 
					    if (*inp == '\0') return YYEOF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Skip all whitespace.
 | 
					    // Skip all whitespace.
 | 
				
			||||||
    while (*inp == ' ' || *inp == '\t') { inp++; }
 | 
					    while (*inp == ' ' || *inp == '\t') inp++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Assign & consume current character.
 | 
					    // Assign & consume current character.
 | 
				
			||||||
    int c = *inp++;
 | 
					    int c = *inp++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (c == '-' && *inp == '>' && inp++) { return RARROW; }
 | 
				
			||||||
 | 
					    if (c == '<' && *inp == '-' && inp++) { return LARROW; }
 | 
				
			||||||
 | 
					    if (c == '=' && *inp == '=' && inp++) { return DEQ; }
 | 
				
			||||||
 | 
					    if (c == '=' && *inp != '=') { return EQ; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Check for NUM.
 | 
					    // Check for NUM.
 | 
				
			||||||
    if (isdigit(c)) {
 | 
					    if (isdigit(c)) {
 | 
				
			||||||
        yylval.fval = acc_float(c); // Set the token value.
 | 
					        yylval.fval = acc_float(c); // Set the token value.
 | 
				
			||||||
        return NUM;
 | 
					        return NUM;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (c) {
 | 
					    if (isalpha(c) || c == '_') {
 | 
				
			||||||
    case '+': return PLUS;
 | 
					        yylval.strval = acc_word(c);
 | 
				
			||||||
    case '\n': return NL;
 | 
					
 | 
				
			||||||
    default:  return CALL;
 | 
					        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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fprintf(stderr, "Unexpected character: %c\n", c);
 | 
					    switch (c) {
 | 
				
			||||||
 | 
					        case '+':  return ADD;
 | 
				
			||||||
 | 
					        case '\n': return NL;
 | 
				
			||||||
 | 
					        case '-':  return SUB;
 | 
				
			||||||
 | 
					        case '*':  return MUL;
 | 
				
			||||||
 | 
					        case '/':  return DIV;
 | 
				
			||||||
 | 
					        case '(':  return GROUPS;
 | 
				
			||||||
 | 
					        case ')':  return GROUPE;
 | 
				
			||||||
 | 
					        case ',':  return SEP;
 | 
				
			||||||
 | 
					        case ';':  return EXPSEP;
 | 
				
			||||||
 | 
					        case '{':  return BLOCKS;
 | 
				
			||||||
 | 
					        case '}':  return BLOCKE;
 | 
				
			||||||
 | 
					        case '\\': return BACKSLASH;
 | 
				
			||||||
 | 
					        case '?':  return IF;
 | 
				
			||||||
 | 
					        case ':':  return COLON;
 | 
				
			||||||
 | 
					        case '$':  return STOP;
 | 
				
			||||||
 | 
					        case '!':  return FORCE;
 | 
				
			||||||
 | 
					        case '@':  return PRESERVE;
 | 
				
			||||||
 | 
					        default:   fprintf(stderr, "Unexpected character: %c\n", c);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										50
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								src/main.c
									
									
									
									
									
								
							@@ -1,23 +1,34 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "include/ast.h"
 | 
					#include "include/ast.h"
 | 
				
			||||||
 | 
					#include "include/ast_print.h"
 | 
				
			||||||
#include "include/dstr.h"
 | 
					#include "include/dstr.h"
 | 
				
			||||||
 | 
					#include "include/exec.h"
 | 
				
			||||||
 | 
					#include "include/gc.h"
 | 
				
			||||||
#include "include/lexer.h"
 | 
					#include "include/lexer.h"
 | 
				
			||||||
#include "include/util.h"
 | 
					#include "include/util.h"
 | 
				
			||||||
#include "include/exec.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../build/grammars/grammar.tab.h"
 | 
					#include "../build/grammars/grammar.tab.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Global Abstract Syntax Tree.
 | 
					// Global Abstract Syntax Tree.
 | 
				
			||||||
extern AST* root;
 | 
					extern AST* root;
 | 
				
			||||||
 | 
					extern char* inp;
 | 
				
			||||||
// Global input text.
 | 
					 | 
				
			||||||
char* inp = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int yyparse();
 | 
					extern int yyparse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char** argv) {
 | 
					int main(int argc, char** argv) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (argc - 1 && strlen(argv[1]) > 0 && (inp = argv[1]) && !yyparse()) {
 | 
				
			||||||
 | 
					        // log_dbg("Parsed successfully!\n");
 | 
				
			||||||
 | 
					        // ast_print(root);
 | 
				
			||||||
 | 
					        AST* eval = exec_start(root);
 | 
				
			||||||
 | 
					        ast_print(eval);
 | 
				
			||||||
 | 
					        // ast_destroy(eval);
 | 
				
			||||||
 | 
					        // ast_destroy(root);
 | 
				
			||||||
 | 
					        gc_hack_free();
 | 
				
			||||||
 | 
					        exit(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (1) {
 | 
					    while (1) {
 | 
				
			||||||
        Dstr* ln = dstr_init();
 | 
					        Dstr* ln = dstr_init();
 | 
				
			||||||
        char c;
 | 
					        char c;
 | 
				
			||||||
@@ -31,8 +42,7 @@ int main(int argc, char** argv) {
 | 
				
			|||||||
            switch (c) {
 | 
					            switch (c) {
 | 
				
			||||||
                case EOF:  dstr_destroy(ln); goto lnskip;
 | 
					                case EOF:  dstr_destroy(ln); goto lnskip;
 | 
				
			||||||
                case '\n': goto lnend;
 | 
					                case '\n': goto lnend;
 | 
				
			||||||
 | 
					                default:   dstr_appendch(ln, c);
 | 
				
			||||||
            default:   dstr_appendch(ln, c); log_dbgf("cchar: %c", c);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } while (1);
 | 
					        } while (1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -41,18 +51,34 @@ int main(int argc, char** argv) {
 | 
				
			|||||||
        log_dbgf("cline: %s", ln->buf);
 | 
					        log_dbgf("cline: %s", ln->buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (ln->ln > 0) {
 | 
					        if (ln->ln > 0) {
 | 
				
			||||||
            // I hope it's null-terminated.
 | 
					 | 
				
			||||||
            inp = ln->buf;
 | 
					            inp = ln->buf;
 | 
				
			||||||
            if (yyparse() == 0)
 | 
					            if (yyparse() == 0) {
 | 
				
			||||||
                printf("Parsed successfully!\n");
 | 
					                log_dbg("Parsed successfully!\n");
 | 
				
			||||||
            else
 | 
					            } else {
 | 
				
			||||||
                printf("Parse error.\n");
 | 
					                printf("Parse error.\n");
 | 
				
			||||||
 | 
					                dstr_destroy(ln);
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //exec_expr(root);
 | 
					#ifdef DBG
 | 
				
			||||||
            ast_print(root);
 | 
					            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();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dstr_destroy(ln);
 | 
					        dstr_destroy(ln);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
lnskip:;
 | 
					lnskip:;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										37
									
								
								src/scope.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/scope.c
									
									
									
									
									
										Normal 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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								src/stack.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/stack.c
									
									
									
									
									
								
							@@ -1,40 +1,41 @@
 | 
				
			|||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h> // IWYU pragma: keep. Req by util macros.
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "include/util.h"
 | 
					 | 
				
			||||||
#include "include/stack.h"
 | 
					#include "include/stack.h"
 | 
				
			||||||
 | 
					#include "include/util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Stack* stack_init() {
 | 
					Stack* stack_init() {
 | 
				
			||||||
    talloc(Stack, stack);
 | 
					    talloc(Stack, stack);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(stack->val, 0, sizeof(void*) * STACK_MAX);
 | 
					    memset(stack->buf, 0, sizeof(void*) * STACK_MAX);
 | 
				
			||||||
    stack->i = 0;
 | 
					    stack->ln = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return stack;
 | 
					    return stack;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void stack_destroy(Stack* stack) {
 | 
					void stack_destroy(Stack* stack) {
 | 
				
			||||||
    // Can only free an empty stack.
 | 
					    // Can only free an empty stack.
 | 
				
			||||||
    assert(stack->i == 0);
 | 
					    assert(stack->ln == 0);
 | 
				
			||||||
    free(stack);
 | 
					    free(stack);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void stack_push(Stack* stack, void* val) {
 | 
					void stack_push(Stack* stack, void* val) {
 | 
				
			||||||
    if (stack->i >= STACK_MAX) {
 | 
					    if (stack->ln >= STACK_MAX) {
 | 
				
			||||||
        log_dbgf("Ran out of stack (max: %d)", STACK_MAX);
 | 
					        log_dbgf("Ran out of stack (max: %d)", STACK_MAX);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stack->val[stack->i] = val;
 | 
					    stack->buf[stack->ln] = val;
 | 
				
			||||||
    stack->i++;
 | 
					    stack->ln++;
 | 
				
			||||||
 | 
					    log_dbgf("pushed to stack, inc ln to %ld", stack->ln);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void* stack_pop(Stack* stack) {
 | 
					void* stack_pop(Stack* stack) {
 | 
				
			||||||
    if (stack->i <= 0) {
 | 
					    if (stack->ln <= 0) {
 | 
				
			||||||
        log_dbg("Can't pop empty stack.");
 | 
					        log_dbg("Can't pop empty stack.");
 | 
				
			||||||
        return (void*)-1;
 | 
					        return (void*)-1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return stack->val[--stack->i];
 | 
					    return stack->buf[--stack->ln];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								test/Unity
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								test/Unity
									
									
									
									
									
										Submodule
									
								
							 Submodule test/Unity added at 73237c5d22
									
								
							
							
								
								
									
										39
									
								
								test/dstr.c
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								test/dstr.c
									
									
									
									
									
								
							@@ -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);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										52
									
								
								test/lexer.c
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								test/lexer.c
									
									
									
									
									
								
							@@ -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);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										12
									
								
								test/main.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								test/main.c
									
									
									
									
									
								
							@@ -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;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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]();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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
 | 
					 | 
				
			||||||
							
								
								
									
										44
									
								
								test/test_ast.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								test/test_ast.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					#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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ast_destroy(ast);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					    UNITY_BEGIN();
 | 
				
			||||||
							
								
								
									
										41
									
								
								test/test_dlist.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								test/test_dlist.c
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										78
									
								
								test/test_dstr.c
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										27
									
								
								test/test_htab.c
									
									
									
									
									
										Normal 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();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										24
									
								
								test/token.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								test/token.c
									
									
									
									
									
								
							@@ -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);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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.
 | 
					 | 
				
			||||||
							
								
								
									
										2501
									
								
								test/unity/unity.c
									
									
									
									
									
								
							
							
						
						
									
										2501
									
								
								test/unity/unity.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -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
									
								
							
							
						
						
									
										131
									
								
								test/val/test.bats
									
									
									
									
									
										Normal 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!" ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								type_notes.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								type_notes.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					n: Int = 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 'Int': integer constructor
 | 
				
			||||||
 | 
					- '3': integer literal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v: Vec(3, Int) = <1, 2, 3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Point: Struct = { x: Int, y: Int }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					p: Point = { .x = 1, .y = 2 }
 | 
				
			||||||
 | 
					p.x + p.y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VecOf(n: Int, t: Type): Type = Vec(n, t)
 | 
				
			||||||
 | 
					strings: VecOf(3, Str) = <"Hello", ",", " world.">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					f(g) = g(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					g(n: Int): Int = n * 2
 | 
				
			||||||
 | 
					g: Lambda(Int, Int) = \(n: Int):Int n * 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Int, Vec, Str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					f(g: \(Int):Int ):Int = g(2)
 | 
				
			||||||
 | 
					f(g: Lambda(Int, Int)): Int = g(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					f: Lambda(Int, Str, Str) = \(s1: Str, s2: Str) length(s) + length(s2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Bad: Type = if Until.time() % 2 == 0 Str Int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Types are code.
 | 
				
			||||||
 | 
					- All types inherit from `Type` (the type of `Type` is `Type`).
 | 
				
			||||||
		Reference in New Issue
	
	Block a user