commit 7af5655973d62a2ad986fa2c1fa9b92f4ad423a7 Author: neauoire Date: Sun Aug 22 18:09:27 2021 -0700 Init diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..d923eb7 --- /dev/null +++ b/.clang-format @@ -0,0 +1,21 @@ +AlignAfterOpenBracket: DontAlign +AlignEscapedNewlines: DontAlign +AlignOperands: DontAlign +AllowShortBlocksOnASingleLine: Always +AllowShortCaseLabelsOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: TopLevel +BinPackArguments: false +BinPackParameters: false +BreakBeforeBraces: WebKit +IndentCaseLabels: false +TabWidth: 4 +IndentWidth: 4 +ContinuationIndentWidth: 4 +UseTab: ForContinuationAndIndentation +ColumnLimit: 0 +ReflowComments: false +SortIncludes: false +SpaceBeforeParens: false \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6ec3af3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.DS* +*jpg~ +*png~ +*gif~ +*bmp~ + +*snarf +*theme diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..37e59e5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Devine Lu Linvega + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..111b397 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# Uxnlin + +A linter for the [Uxntal](https://wiki.xxiivv.com/site/uxntal.html) programming language, written in ANSI C. + +## Getting Started + +Begin by building the linter by running the build script. The linter(`uxnlin`) is created in the `/bin` folder. + +``` +./build.sh + --debug # Add debug flags to compiler +``` + +### Running + +The following command will read a `tal` file and raise warnings if optimizations can be found. + +``` +bin/uxnlin path/to/source.tal +``` + +## Need a hand? + +Find us in `#uxn`, on irc.esper.net diff --git a/bin/uxnlin b/bin/uxnlin new file mode 100755 index 0000000..e03c4f0 Binary files /dev/null and b/bin/uxnlin differ diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..86ceb0f --- /dev/null +++ b/build.sh @@ -0,0 +1,34 @@ +#!/bin/sh -e + +echo "Cleaning.." +rm -f ./bin/uxnlin + +# When clang-format is present + +if command -v clang-format > /dev/null 2>&1 +then + echo "Formatting.." + clang-format -i src/main.c +fi + +mkdir -p bin + +echo "Building.." +if [ "${1}" = '--debug' ]; +then + echo "[debug]" + cc src/main.c -std=c89 -DDEBUG -Wall -Wpedantic -Wno-unknown-pragmas -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined -o bin/uxnlin +else + cc src/main.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o bin/uxnlin +fi + +if [ -d "$HOME/bin" ] +then + echo "Installing in $HOME/bin" + cp bin/uxnlin $HOME/bin/ +fi + +echo "Linting.." +./bin/uxnlin etc/example.tal + +echo "Done." diff --git a/etc/example.tal b/etc/example.tal new file mode 100644 index 0000000..1bccfe9 --- /dev/null +++ b/etc/example.tal @@ -0,0 +1,13 @@ +( comment ) + +|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ] + +|0000 + +( program ) + +|0100 ( -> ) + + #0001 #0003 ADD2 + +BRK diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..1b6f23b --- /dev/null +++ b/src/main.c @@ -0,0 +1,70 @@ +#include + +/* +Copyright (c) 2021 Devine Lu Linvega + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. +*/ + +static char history[4][64]; + +/* clang-format off */ + +static char ops[][4] = { + "LIT", "INC", "POP", "DUP", "NIP", "SWP", "OVR", "ROT", + "EQU", "NEQ", "GTH", "LTH", "JMP", "JCN", "JSR", "STH", + "LDZ", "STZ", "LDR", "STR", "LDA", "STA", "DEI", "DEO", + "ADD", "SUB", "MUL", "DIV", "AND", "ORA", "EOR", "SFT" +}; + +static int scmp(char *a, char *b, int len) { int i = 0; while(a[i] == b[i] && i < len) if(!a[i++]) return 1; return 0; } /* string compare */ +static int sihx(char *s) { int i = 0; char c; while((c = s[i++])) if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f')) return 0; return i > 1; } /* string is hexadecimal */ +static int shex(char *s) { int n = 0, i = 0; char c; while((c = s[i++])) if(c >= '0' && c <= '9') n = n * 16 + (c - '0'); else if(c >= 'a' && c <= 'f') n = n * 16 + 10 + (c - 'a'); return n; } /* string to num */ +static int slen(char *s) { int i = 0; while(s[i] && s[++i]) ; return i; } /* string length */ +static char *scpy(char *src, char *dst, int len) { int i = 0; while((dst[i] = src[i]) && i < len - 2) i++; dst[i + 1] = '\0'; return dst; } /* string copy */ +static char *scat(char *dst, const char *src) { char *ptr = dst + slen(dst); while(*src) *ptr++ = *src++; *ptr = '\0'; return dst; } /* string cat */ + +#pragma mark - Helpers + +static int +error(char *name, char *msg) +{ + fprintf(stderr, "%s: %s\n", name, msg); + return 0; +} + +static void +record(char *w){ + printf("%s\n", w); +} + +/* clang-format on */ + +static int +pass1(FILE *f) +{ + char w[64]; + while(fscanf(f, "%s", w) == 1) { + record(w); + } + return 1; +} + +int +main(int argc, char *argv[]) +{ + FILE *f; + if(argc < 2) + return !error("usage", "input.tal"); + if(!(f = fopen(argv[1], "r"))) + return !error("Load", "Failed to open source."); + if(!pass1(f)) + return !error("Linter", "Failed to lint source."); + fclose(f); + return 0; +}