summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-29 11:37:25 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-29 11:37:25 -0500
commit426d9c9977489f7adba7f4b554e8466a47e520f1 (patch)
treefd5e83ef2e7c8e16fd66f2784736337170ab32de
parentd79ac12de0ceb4ff82f486c26608b754b145f0fc (diff)
made #foreign a part of the language
-rw-r--r--README.html31
-rw-r--r--README.md3
-rwxr-xr-xbuild.sh17
-rw-r--r--compatibility.c77
-rw-r--r--docs/00.html7
-rw-r--r--docs/01.html4
-rw-r--r--eval.c2
-rw-r--r--foreign.c4
8 files changed, 31 insertions, 114 deletions
diff --git a/README.html b/README.html
index baa360d..e3ea45d 100644
--- a/README.html
+++ b/README.html
@@ -11,24 +11,24 @@ and there are almost definitely bugs right now.</strong>
I would recommend against using it for anything big or important.
Many parts of it may change in the future.</p>
-<p><code>toc</code> improves on C&rsquo;s syntax (and semantics) in many ways,
+<p><code>toc</code> improves on C's syntax (and semantics) in many ways,
To declare <code>x</code> as an integer and set it to 5,
you can do:</p>
<p><code>
-x := 5; // Declare x and set x to 5 (infer type)
-x : int = 5; // Explicitly make the type int.
-x : int; x = 5; // Declare x as an integer, then set it to 5.
+x := 5; // Declare x and set x to 5 (infer type) <br />
+x : int = 5; // Explicitly make the type int. <br />
+x : int; x = 5; // Declare x as an integer, then set it to 5.
</code></p>
-<p><code>toc</code> is statically typed and has many of C&rsquo;s features, but
+<p><code>toc</code> is statically typed and has many of C's features, but
it is nearly as fast in theory.</p>
<p>See <code>docs</code> for more information (in progress).</p>
<p><code>tests</code> has some test programs written in <code>toc</code>.</p>
-<p>To compile the compiler on a Unix-y system, just run <code>./build.sh release</code>. You can supply a compiler by running <code>CC=tcc ./build.sh release</code>, or build it in debug mode without the <code>release</code>.</p>
+<p>To compile the compiler on a Unix-y system, just run <code>./build.sh release</code>. You can supply a compiler by running <code>CC=tcc ./build.sh release</code>, or build it in debug mode without the <code>release</code>. To disable compile time foreign function support (which you will need to do if you don't have ffcall/dl), prefix this with <code>COMPILE_TIME_FOREIGN_FN_SUPPORT=no</code>.</p>
<p>On other systems, you can just compile main.c with a C compiler. <code>toc</code> uses several C99 and a couple of C11 features, so it might not work on all compilers. But it does compile on quite a few, including <code>clang</code>, <code>gcc</code>, and <code>tcc</code>. It can also be compiled as if it were C++, so, MSVC and <code>g++</code> can also compile it (it does rely on implicit casting of <code>void *</code> though). The <em>outputted</em> code should be C99-compliant.</p>
@@ -37,11 +37,10 @@ it is nearly as fast in theory.</p>
<p><code>toc</code> compiles to C. Here are some reasons why:</p>
<ul>
-<li>Speed. C is one of the most performant programming languages out there. It also has compilers which are very good at optimizing (better than anything I could write).</li>
+<li>Speed. C is one of the most performant programming languages out there. It also has compilers which are very good at optimizing (better than anything I could write). </li>
<li>Portability. C is probably the most portable language. It has existed for >30 years and can run on practically anything. Furthermore, all major languages nowadays can call functions written in C.</li>
</ul>
-
<hr />
<h3><code>toc</code> Compiler Source Code</h3>
@@ -54,15 +53,15 @@ it is nearly as fast in theory.</p>
<h4>Build system</h4>
-<p><code>toc</code> is set up as a unity build, meaning that there is only one translation unit. So, <code>main.c</code> <code>#include</code>s <code>toc.c</code>, which <code>#include</code>s all of <code>toc</code>&rsquo;s files.</p>
+<p><code>toc</code> is set up as a unity build, meaning that there is only one translation unit. So, <code>main.c</code> <code>#include</code>s <code>toc.c</code>, which <code>#include</code>s all of <code>toc</code>'s files.</p>
<h5>Why?</h5>
-<p>This improves compilation speeds (especially from scratch), since you don&rsquo;t have to include headers a bunch of times for each translation unit. This is more of a problem in C++, where, for example, doing <code>#include &lt;map&gt;</code> ends up turning into 25,000 lines after preprocessing. All of toc&rsquo;s source code, which includes most of the C standard library, at the time of this writing (Dec 2019) is only 22,000 lines after preprocessing; imagine including all of that once for each translation unit which includes <code>map</code>. It also obviates the need for fancy build systems like CMake.</p>
+<p>This improves compilation speeds (especially from scratch), since you don't have to include headers a bunch of times for each translation unit. This is more of a problem in C++, where, for example, doing <code>#include &lt;map&gt;</code> ends up turning into 25,000 lines after preprocessing. All of toc's source code, which includes most of the C standard library, at the time of this writing (Dec 2019) is only 22,000 lines after preprocessing; imagine including all of that once for each translation unit which includes <code>map</code>. It also obviates the need for fancy build systems like CMake.</p>
<h4>New features</h4>
-<p>Here are all the C99 features which <code>toc</code> depends on (I might have forgotten some&hellip;):</p>
+<p>Here are all the C99 features which <code>toc</code> depends on (I might have forgotten some...):</p>
<ul>
<li>Declare anywhere</li>
@@ -71,15 +70,13 @@ it is nearly as fast in theory.</p>
<li>Flexible array members</li>
</ul>
-
<p>And here are all of its C11 features:</p>
<ul>
<li>Anonymous structures/unions</li>
-<li><code>max_align_t</code> - It can still compile without this, and will almost definitely work, but it won&rsquo;t technically be standard-compliant</li>
+<li><code>max_align_t</code> - It can still compile without this, and will almost definitely work, but it won't technically be standard-compliant</li>
</ul>
-
<h4>More</h4>
<p>See <code>main.c</code> for a bit more information.</p>
@@ -94,13 +91,13 @@ it is nearly as fast in theory.</p>
<tr><th>Version</th><th>Description</th><th>Date</th></tr>
<tr><td>0.0</td><td>Initial version.</td><td>2019 Dec 6</td></tr>
<tr><td>0.1</td><td>Constant parameter inference.</td><td>2019 Dec 15</td></tr>
+<tr><td>0.2</td><td>Foreign functions and #include.</td><td>2020 Jan 29</td></tr>
</table>
-
<hr />
<h3>Report a bug</h3>
-<p>If you find a bug, you can report it through <a href="https://github.com/pommicket/toc/issues">GitHub&rsquo;s issue tracker</a>, or by emailing pommicket@gmail.com.</p>
+<p>If you find a bug, you can report it through <a href="https://github.com/pommicket/toc/issues">GitHub's issue tracker</a>, or by emailing pommicket@gmail.com.</p>
-<p>Just send me the <code>toc</code> source code which results in the bug, and I&rsquo;ll try to fix it.</p>
+<p>Just send me the <code>toc</code> source code which results in the bug, and I'll try to fix it. </p>
diff --git a/README.md b/README.md
index 2fa6838..f602920 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ See `docs` for more information (in progress).
`tests` has some test programs written in `toc`.
-To compile the compiler on a Unix-y system, just run `./build.sh release`. You can supply a compiler by running `CC=tcc ./build.sh release`, or build it in debug mode without the `release`.
+To compile the compiler on a Unix-y system, just run `./build.sh release`. You can supply a compiler by running `CC=tcc ./build.sh release`, or build it in debug mode without the `release`. To disable compile time foreign function support (which you will need to do if you don't have ffcall/dl), prefix this with `COMPILE_TIME_FOREIGN_FN_SUPPORT=no`.
On other systems, you can just compile main.c with a C compiler. `toc` uses several C99 and a couple of C11 features, so it might not work on all compilers. But it does compile on quite a few, including `clang`, `gcc`, and `tcc`. It can also be compiled as if it were C++, so, MSVC and `g++` can also compile it (it does rely on implicit casting of `void *` though). The *outputted* code should be C99-compliant.
@@ -82,6 +82,7 @@ Here are the major versions of `toc`.
<tr><th>Version</th><th>Description</th><th>Date</th></tr>
<tr><td>0.0</td><td>Initial version.</td><td>2019 Dec 6</td></tr>
<tr><td>0.1</td><td>Constant parameter inference.</td><td>2019 Dec 15</td></tr>
+<tr><td>0.2</td><td>Foreign functions and #include.</td><td>2020 Jan 29</td></tr>
</table>
---
diff --git a/build.sh b/build.sh
index 6dadf63..6a415a6 100755
--- a/build.sh
+++ b/build.sh
@@ -21,22 +21,19 @@ else
WARNINGS=''
fi
-if [ "$1" = "" ]; then
- if [ "$COMPILE_TIME_FOREIGN_FN_SUPPORT" != "no" ]; then
- ADDITIONAL_FLAGS="$ADDITIONAL_FLAGS -DCOMPILE_TIME_FOREIGN_FN_SUPPORT=1 -lffcall -ldl"
- fi
+if [ "$COMPILE_TIME_FOREIGN_FN_SUPPORT" != "no" ]; then
+ ADDITIONAL_FLAGS="$ADDITIONAL_FLAGS -DCOMPILE_TIME_FOREIGN_FN_SUPPORT=1 -lffcall -ldl"
fi
-DEBUG_FLAGS="-O0 -no-pie -gdwarf-2 -pipe $WARNINGS -std=c11 -DTOC_DEBUG"
+
+DEBUG_FLAGS="-O0 $WARNINGS -std=c11 -DTOC_DEBUG"
+if [ "$CC" = "gcc" ]; then
+ DEBUG_FLAGS="$DEBUG_FLAGS -no-pie -gdwarf-2 -pipe"
+fi
RELEASE_FLAGS="-O3 -s -DNDEBUG $WARNINGS -std=c11"
if [ "$1" = "release" ]; then
FLAGS="$RELEASE_FLAGS $ADDITIONAL_FLAGS"
-
- COMMAND="$CC compatibility.c -Wall -Wextra -o compatibility"
- echo $COMMAND
- $COMMAND || exit 1
- FLAGS="$FLAGS $(./compatibility)"
else
FLAGS="$DEBUG_FLAGS $ADDITIONAL_FLAGS"
fi
diff --git a/compatibility.c b/compatibility.c
deleted file mode 100644
index 6a7c32c..0000000
--- a/compatibility.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-This is free and unencumbered software released into the public domain.
-Anyone is free to copy, modify, publish, use, compile, sell, or
-distribute this software, either in source code form or as a compiled
-binary, for any purpose, commercial or non-commercial, and by any
-means.
-In jurisdictions that recognize copyright laws, the author or authors
-of this software dedicate any and all copyright interest in the
-software to the public domain. We make this dedication for the benefit
-of the public at large and to the detriment of our heirs and
-successors. We intend this dedication to be an overt act of
-relinquishment in perpetuity of all present and future rights to this
-software under copyright law.
-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 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.
-For more information, please refer to <http://unlicense.org/>
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-
-typedef float F32;
-typedef double F64;
-typedef uint32_t U32;
-typedef uint64_t U64;
-
-int main(void) {
- int *p;
- memset(&p, 0, sizeof p);
- if (p) {
- fprintf(stderr, "You cannot run toc. Sorry.\n");
- return EXIT_FAILURE;
- }
-
-
- FILE *f;
- f = tmpfile();
- /* endianness test */
- putc(0x12, f);
- putc(0x34, f);
- putc(0x56, f);
- putc(0x78, f);
-
- if (sizeof(float) != 4 || sizeof(double) != 8) {
- fprintf(stderr, "You may experience some problems with toc (sizeof(double) and sizeof(float) are strange).");
- goto unusual;
- } else {
- F32 flt = -12.3456f;
- fwrite(&flt, sizeof flt, 1, f);
- F64 dbl = -12.3456;
- fwrite(&dbl, sizeof dbl, 1, f);
- }
- fseek(f, 0L, SEEK_SET);
- U32 num;
- fread(&num, sizeof num, 1, f);
- if (num != 0x78563412) {
- /* not little endian */
- goto unusual;
- }
- U32 flt_rep;
- fread(&flt_rep, sizeof flt_rep, 1, f);
- if (flt_rep != 0xc1458794) goto unusual;
- U64 dbl_rep;
- fread(&dbl_rep, sizeof dbl_rep, 1, f);
- if (dbl_rep != 0xc028b0f27bb2fec5) goto unusual;
- return 0;
- unusual:
- printf("-DBINFILE_PORTABLE");
- return 0;
-}
diff --git a/docs/00.html b/docs/00.html
index b8c961c..cd0c352 100644
--- a/docs/00.html
+++ b/docs/00.html
@@ -30,7 +30,7 @@ x := 0.0;
when no type is specified, it defaults to an <code>int</code>, whereas <code>0.0</code>
defaults to a <code>float</code>.</p>
-<p>Here are all of toc&rsquo;s builtin types and their ranges of values:</p>
+<p>Here are all of toc's builtin types and their ranges of values:</p>
<ul>
<li><code>int</code> - A 64-bit signed integer (always), -9223372036854775808 to 9223372036854775807</li>
@@ -49,14 +49,13 @@ defaults to a <code>float</code>.</p>
<li><code>char</code> - A character. The specific values are technically platform-dependent, but usually there are 256 of them.</li>
</ul>
-
<p>At the moment, it is not technically guaranteed that <code>f32</code>/<code>float</code> is actually 32-bit and that <code>f64</code> is actually 64-bit; they are platform dependent. Perhaps someday there will be a version of toc which does not compile to C, where that could be guaranteed.</p>
<p>To make declarations constant, use <code>::</code> instead of <code>:</code>. e.g.</p>
<p><code>
-x ::= 5+3;
+x ::= 5+3; <br />
y :: float = 5.123;
</code></p>
-<p>Here, &ldquo;constant&rdquo; means constant at compile time, not read-only as it does in C. One interesting thing about toc is that normal functions can run at compile time, so pretty much any expression is a valid initializer for a constant, e.g. doing <code>x ::= some_function();</code> runs <code>some_function</code> at compile time, not at run time.</p>
+<p>Here, "constant" means constant at compile time, not read-only as it does in C. One interesting thing about toc is that normal functions can run at compile time, so pretty much any expression is a valid initializer for a constant, e.g. doing <code>x ::= some_function();</code> runs <code>some_function</code> at compile time, not at run time.</p>
diff --git a/docs/01.html b/docs/01.html
index 6dce358..633295b 100644
--- a/docs/01.html
+++ b/docs/01.html
@@ -7,7 +7,7 @@ main ::= fn() {
};
</code></p>
-<p>It declares a constant, <code>main</code>, which is a function with an empty body. Note that the syntax for declaring functions is the same as the syntax for declaring constants (it isn&rsquo;t something like <code>fn main() { ... }</code>).</p>
+<p>It declares a constant, <code>main</code>, which is a function with an empty body. Note that the syntax for declaring functions is the same as the syntax for declaring constants (it isn't something like <code>fn main() { ... }</code>).</p>
<p>Assuming you have compiled the compiler (see <code>README.md</code> for instructions about that), you can compile it with</p>
@@ -15,4 +15,4 @@ main ::= fn() {
toc &lt;your filename&gt;
</code></p>
-<p>You will get a file called <code>out.c</code>, which you can then put through your C compiler to get an executable file which does nothing. Congratulations! You&rsquo;ve written your first toc program.</p>
+<p>You will get a file called <code>out.c</code>, which you can then put through your C compiler to get an executable file which does nothing. Congratulations! You've written your first toc program.</p>
diff --git a/eval.c b/eval.c
index 8019f4f..1eb7c1e 100644
--- a/eval.c
+++ b/eval.c
@@ -735,7 +735,7 @@ static void *eval_ptr_to_struct_field(Evaluator *ev, Expression *dot_expr) {
struc_data = struc.ptr;
if (struc_data == NULL) {
err_print(dot_expr->where, "Attempt to dereference NULL pointer.");
- return false;
+ return NULL;
}
} else {
struc_data = struc.struc;
diff --git a/foreign.c b/foreign.c
index b55a908..48d8d4a 100644
--- a/foreign.c
+++ b/foreign.c
@@ -312,8 +312,8 @@ static bool foreign_call(ForeignFnManager *ffmgr, FnExpr *fn, Type *fn_type, Val
static void ffmgr_free(ForeignFnManager *ffmgr) {
arr_foreach(ffmgr->libs_loaded.slots, StrHashTableSlotPtr, slotp) {
if (*slotp) {
- Library lib = *(Library *)((*slotp)->data);
- dlclose(lib.handle);
+ Library *lib = (void *)((*slotp)->data);
+ dlclose(lib->handle);
}
}
str_hash_table_free(&ffmgr->libs_loaded);