+++ /dev/null
-/* This file implements a simple POSIX-style option parsing implementation as
- * a set of macros. The file is heavily influenced and inspired by the arg.h
- * file from suckless.org (http://git.suckless.org/libsl/tree/arg.h). That file
- * is in turn inspired by the corresponding macros defined in plan9.
- *
- * The interface in this file assumes that the main function will have the
- * following prototype:
- *
- * int main(int argc, char** argv);
- *
- * An example usage of the interface would look something like the follwoing:
- *
- * char* ARGV0;
- * int main(int argc, char** argv) {
- * OPTBEGIN {
- * case 'a': printf("Simple option\n"); break;
- * case 'b': printf("Option with arg: %s\n", OPTARG()); break;
- * default: printf("Unknown option!\n");
- * } OPTEND;
- * return 0;
- * }
- */
-#ifndef OPT_H
-#define OPT_H
-
-/* This variable contains the value of argv[0] so that it can be referenced
- * again once the option parsing is done. This variable must be defined by the
- * program.
- *
- * NOTE: Ensure that you define this variable with external linkage (i.e. not
- * static)
- */
-extern char* ARGV0;
-
-/* This is a helper function used by the macros in this file to parse the next
- * option from the command line.
- */
-static inline char* __getopt(int* p_argc, char*** p_argv) {
- if (!(*p_argv)[0][1] && !(*p_argv)[1]) {
- return (char*)0;
- } else if ((*p_argv)[0][1]) {
- return &(*p_argv)[0][1];
- } else {
- *p_argv = *p_argv + 1;
- *p_argc = *p_argc - 1;
- return (*p_argv)[0];
- }
-}
-
-/* This macro is almost identical to the ARGBEGIN macro from suckless.org. If
- * it ain't broke, don't fix it. */
-#define OPTBEGIN \
- for ( \
- ARGV0 = *argv, argc--, argv++; \
- argv[0] && argv[0][1] && argv[0][0] == '-'; \
- argc--, argv++ \
- ) { \
- int brk_; char argc_ , **argv_, *optarg_; \
- if (argv[0][1] == '-' && !argv[0][2]) { \
- argv++, argc--; break; \
- } \
- for (brk_=0, argv[0]++, argv_=argv; argv[0][0] && !brk_; argv[0]++) { \
- if (argv_ != argv) break; \
- argc_ = argv[0][0]; \
- switch (argc_)
-
-/* Terminate the option parsing. */
-#define OPTEND }}
-
-/* Get the current option chracter */
-#define OPTC() (argc_)
-
-/* Get an argument from the command line and return it as a string. If no
- * argument is available, this macro returns NULL */
-#define OPTARG() \
- (optarg_ = __getopt(&argc,&argv), brk_ = (optarg_!=0), optarg_)
-
-/* Get an argument from the command line and return it as a string. If no
- * argument is available, this macro executes the provided code. If that code
- * returns, then abort is called. */
-#define EOPTARG(code) \
- (optarg_ = __getopt(&argc,&argv), \
- (!optarg_ ? ((code), abort(), (char*)0) : (brk_ = 1, optarg_)))
-
-/* Helper macro to recognize number options */
-#define OPTNUM \
- case '0': \
- case '1': \
- case '2': \
- case '3': \
- case '4': \
- case '5': \
- case '6': \
- case '7': \
- case '8': \
- case '9'
-
-/* Helper macro to recognize "long" options ala GNU style. */
-#define OPTLONG \
- case '-'
-
-#endif
+++ /dev/null
-
-/**
- @file sclpl.h
- @brief TODO: Describe this file
- $Revision$
- $HeadURL$
-*/
-#ifndef SCLPL_H
-#define SCLPL_H
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <assert.h>
-#include <string.h>
-
-#define IF(a) (a) ?
-#define ELSE :
-
-#define BITCOUNT (sizeof(void*) * 8u)
-#define REFCOUNT_MASK ((1u << (BITCOUNT/2u)) - 1u)
-#define RECCOUNT_MASK ((intptr_t)-1u)
-#define GET_RECCOUNT(a) (((a) & RECCOUNT_MASK) >> (BITCOUNT/2))
-#define MAKE_RECCOUNT(a) ((a) << (BITCOUNT/2))
-#define GET_REFCOUNT(a) ((a) & REFCOUNT_MASK)
-
-//#define __is_ptr(v) ((bool)((v & 1u) == 0))
-//#define __is_num(v) ((bool)((v & 1u) == 1))
-
-#define __nil ((_Value)NULL)
-#define __num(v) ((_Value)(((intptr_t)(v) << 1u) | 1u))
-#define __int(v) __num(v)
-#define __char(v) __num(v)
-#define __bool(v) __num(v)
-
-typedef struct {
- uintptr_t refcount;
-} _Object;
-
-typedef intptr_t _Value;
-
-static inline void* allocate(size_t nflds, size_t size)
-{
- _Object* p_obj = (_Object*)malloc(sizeof(_Object) + size);
- p_obj->refcount = MAKE_RECCOUNT(nflds) | 1;
- return (void*)(p_obj+1);
-}
-
-static inline _Value retain(_Value val)
-{
- assert( val && !(val & 1u) );
- (((_Object*)val)-1)->refcount++;
- return val;
-}
-
-static inline _Value release(_Value val)
-{
- assert( val && !(val & 1u) );
- (((_Object*)val)-1)->refcount--;
- return __nil;
-}
-
-static inline _Value reccount(_Value val)
-{
- assert( val && !(val & 1u) );
- return __num( (((_Object*)val)-1)->refcount >> (BITCOUNT/2) );
-}
-
-static inline _Value refcount(_Value val)
-{
- assert( val && !(val & 1u) );
- return __num( (((_Object*)val)-1)->refcount );
-}
-
-static inline _Value __float(double v) {
- double* dbl = (double*)allocate(0, sizeof(double));
- *dbl = v;
- return (_Value)dbl;
-}
-
-static inline _Value __string(char v[]) {
- size_t sz = strlen(v)+1;
- char* str = (char*)allocate(0, sz);
- (void)memcpy(str, v, sz);
- return (_Value)str;
-}
-
-static inline _Value __struct(size_t nflds, ...) {
- void** obj = (void**)allocate(nflds, sizeof(void*) * nflds);
- size_t i;
- va_list args;
- va_start(args, nflds);
- for(i = 0; i < nflds; i++)
- obj[i] = va_arg(args, void*);
- va_end(args);
- return (_Value)obj;
-}
-
-#define __struct_fld(val, idx) (((_Value*)val)[idx])
-
-#define __func(fn) __struct(1, fn)
-
-#define __closure(fn,nfree,...) __struct(nfree, fn, __VA_ARGS__)
-
-#define __call0(fn) ((__fnptr_0)(__struct_fld(fn,0) & ~1u))(fn)
-
-#define __calln(fn,nargs,...) ((__fnptr_##nargs)(__struct_fld(fn,0) & ~1u))(fn, __VA_ARGS__)
-
-typedef _Value (*__fnptr_0)(_Value env);
-
-typedef _Value (*__fnptr_1)(_Value env, _Value a0);
-
-typedef _Value (*__fnptr_2)(_Value env, _Value a0, _Value a1);
-
-typedef _Value (*__fnptr_3)(_Value env, _Value a0, _Value a1, _Value a2);
-
-typedef _Value (*__fnptr_4)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3);
-
-typedef _Value (*__fnptr_5)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3,
- _Value a4);
-
-typedef _Value (*__fnptr_6)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3,
- _Value a4, _Value a5);
-
-typedef _Value (*__fnptr_7)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3,
- _Value a4, _Value a5, _Value a6);
-
-typedef _Value (*__fnptr_8)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3,
- _Value a4, _Value a5, _Value a6, _Value a7);
-
-typedef _Value (*__fnptr_9)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3,
- _Value a4, _Value a5, _Value a6, _Value a7, _Value a8);
-
-typedef _Value (*__fnptr_10)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3,
- _Value a4, _Value a5, _Value a6, _Value a7, _Value a8);
-
-typedef _Value (*__fnptr_11)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3,
- _Value a4, _Value a5, _Value a6, _Value a7, _Value a8,
- _Value a9);
-
-typedef _Value (*__fnptr_12)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3,
- _Value a4, _Value a5, _Value a6, _Value a7, _Value a8,
- _Value a9, _Value a10);
-
-typedef _Value (*__fnptr_13)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3,
- _Value a4, _Value a5, _Value a6, _Value a7, _Value a8,
- _Value a9, _Value a10, _Value a11);
-
-typedef _Value (*__fnptr_14)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3,
- _Value a4, _Value a5, _Value a6, _Value a7, _Value a8,
- _Value a9, _Value a10, _Value a11, _Value a12);
-
-typedef _Value (*__fnptr_15)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3,
- _Value a4, _Value a5, _Value a6, _Value a7, _Value a8,
- _Value a9, _Value a10, _Value a11, _Value a12, _Value a14);
-
-typedef _Value (*__fnptr_16)(_Value env, _Value a0, _Value a1, _Value a2, _Value a3,
- _Value a4, _Value a5, _Value a6, _Value a7, _Value a8,
- _Value a9, _Value a10, _Value a11, _Value a12, _Value a14,
- _Value a15);
-
-typedef _Value (*__fnptr_n)(_Value env, ...);
-
-/*****************************************************************************/
-
-/* Boolean Operations */
-#define __not(val) __num(!((bool)__untag(val)))
-
-/* Character procedures */
-#define __char_lt(lval, rval) __ilt((lval), (rval))
-#define __char_gt(lval, rval) __igt((lval), (rval))
-#define __char_eq(lval, rval) __ieq((lval), (rval))
-#define __char_lte(lval, rval) __ilte((lval), (rval))
-#define __char_gte(lval, rval) __igte((lval), (rval))
-#define __char_upcase(val) assert(false)
-#define __char_downcase(val) assert(false)
-#define __char_foldcase(val) assert(false)
-
-/* Integer Operations */
-#define __untag(a) ((a) >> 1u)
-#define __iadd(lval, rval) __num(__untag(lval) + __untag(rval))
-#define __isub(lval, rval) __num(__untag(lval) - __untag(rval))
-#define __imul(lval, rval) __num(__untag(lval) * __untag(rval))
-#define __idiv(lval, rval) __num(__untag(lval) / __untag(rval))
-#define __imod(lval, rval) __num(__untag(lval) % __untag(rval))
-#define __ilt(lval, rval) __bool(__untag(lval) < __untag(rval))
-#define __igt(lval, rval) __bool(__untag(lval) > __untag(rval))
-#define __ieq(lval, rval) __bool(__untag(lval) == __untag(rval))
-#define __ilte(lval, rval) __bool(__untag(lval) <= __untag(rval))
-#define __igte(lval, rval) __bool(__untag(lval) >= __untag(rval))
-
-/* Float Operations */
-#define __fadd(lval, rval) __float(*lval + *rval)
-#define __fsub(lval, rval) __float(*lval - *rval)
-#define __fmul(lval, rval) __float(*lval * *rval)
-#define __fdiv(lval, rval) __float(*lval / *rval)
-#define __fmod(lval, rval) __float(*lval % *rval)
-#define __flt(lval, rval) __bool(*lval < *rval)
-#define __fgt(lval, rval) __bool(*lval > *rval)
-#define __feq(lval, rval) __bool(*lval == *rval)
-#define __flte(lval, rval) __bool(*lval <= *rval)
-#define __fgte(lval, rval) __bool(*lval >= *rval)
-
-/* String Operations */
-#define __string_length(val) strlen((char*)val)
-#define __string_ref(str, idx) __num(((char*)val)[idx])
-#define __string_set(str, idx, ch) (((char*)val)[idx] = ch, __nil)
-#define __string_eq(lval, rval) __num(0 == strcmp((char*)lval, (char*)rval))
-#define __string_lt(lval, rval) __num(-1 == strcmp((char*)lval, (char*)rval))
-#define __string_gt(lval, rval) __num(1 == strcmp((char*)lval, (char*)rval))
-#define __string_lte(lval, rval) __num(__string_lt(lval, rval) || __string_eq(lval, rval))
-#define __string_gte(lval, rval) __num(__string_gt(lval, rval) || __string_eq(lval, rval))
-#define __string_ci_eq(lval, rval) assert(false)
-#define __string_ci_lt(lval, rval) assert(false)
-#define __string_ci_gt(lval, rval) assert(false)
-#define __string_ci_lte(lval, rval) assert(false)
-#define __string_ci_gte(lval, rval) assert(false)
-#define __string_upcase(val, rval) assert(false)
-#define __string_downcase(val, rval) assert(false)
-#define __string_foldcase(val, rval) assert(false)
-#define __substring(val, start, end) assert(false)
-#define __string_concat(lval, rval) assert(false)
-
-/* Port Operations */
-_Value __port_read_char(_Value port);
-_Value __port_write_char(_Value port, _Value ch);
-_Value __port_read_byte(_Value port);
-_Value __port_write_byte(_Value port, _Value byte);
-_Value __open_input_file(_Value fname);
-_Value __open_output_file(_Value fname);
-_Value __close_port(_Value port);
-_Value __is_eof(_Value port);
-
-#endif /* SCLPL_H */
-/**
- @file sclpl.h
-*/
-#ifndef SCLPL_H
-#define SCLPL_H
-
+#define _XOPEN_SOURCE 700
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <errno.h>
#include <assert.h>
#include <setjmp.h>
-#include <opt.h>
/* Garbage Collection
*****************************************************************************/
/* AST Types
*****************************************************************************/
-typedef enum ASTType {
+typedef enum {
AST_STRING, AST_SYMBOL, AST_CHAR, AST_INT, AST_FLOAT, AST_BOOL, AST_IDENT,
AST_REQ, AST_DEF, AST_IF, AST_FUNC, AST_FNAPP, AST_LET, AST_TEMP
} ASTType;
// Grammar Routines
AST* toplevel(Parser* p);
-// Compiler Passes
-AST* normalize(AST* tree);
-void codegen(FILE* file, AST* tree);
+/* Option Parsing
+ *****************************************************************************/
-#endif /* SCLPL_H */
+/* This variable contains the value of argv[0] so that it can be referenced
+ * again once the option parsing is done. This variable must be defined by the
+ * program.
+ *
+ * NOTE: Ensure that you define this variable with external linkage (i.e. not
+ * static)
+ */
+extern char* ARGV0;
+
+/* This is a helper function used by the macros in this file to parse the next
+ * option from the command line.
+ */
+static inline char* __getopt(int* p_argc, char*** p_argv) {
+ if (!(*p_argv)[0][1] && !(*p_argv)[1]) {
+ return (char*)0;
+ } else if ((*p_argv)[0][1]) {
+ return &(*p_argv)[0][1];
+ } else {
+ *p_argv = *p_argv + 1;
+ *p_argc = *p_argc - 1;
+ return (*p_argv)[0];
+ }
+}
+
+/* This macro is almost identical to the ARGBEGIN macro from suckless.org. If
+ * it ain't broke, don't fix it. */
+#define OPTBEGIN \
+ for ( \
+ ARGV0 = *argv, argc--, argv++; \
+ argv[0] && argv[0][1] && argv[0][0] == '-'; \
+ argc--, argv++ \
+ ) { \
+ int brk_; char argc_ , **argv_, *optarg_; \
+ if (argv[0][1] == '-' && !argv[0][2]) { \
+ argv++, argc--; break; \
+ } \
+ for (brk_=0, argv[0]++, argv_=argv; argv[0][0] && !brk_; argv[0]++) { \
+ if (argv_ != argv) break; \
+ argc_ = argv[0][0]; \
+ switch (argc_)
+
+/* Terminate the option parsing. */
+#define OPTEND }}
+
+/* Get the current option chracter */
+#define OPTC() (argc_)
+
+/* Get an argument from the command line and return it as a string. If no
+ * argument is available, this macro returns NULL */
+#define OPTARG() \
+ (optarg_ = __getopt(&argc,&argv), brk_ = (optarg_!=0), optarg_)
+
+/* Get an argument from the command line and return it as a string. If no
+ * argument is available, this macro executes the provided code. If that code
+ * returns, then abort is called. */
+#define EOPTARG(code) \
+ (optarg_ = __getopt(&argc,&argv), \
+ (!optarg_ ? ((code), abort(), (char*)0) : (brk_ = 1, optarg_)))
+
+/* Helper macro to recognize number options */
+#define OPTNUM \
+ case '0': \
+ case '1': \
+ case '2': \
+ case '3': \
+ case '4': \
+ case '5': \
+ case '6': \
+ case '7': \
+ case '8': \
+ case '9'
+
+/* Helper macro to recognize "long" options ala GNU style. */
+#define OPTLONG \
+ case '-'
+++ /dev/null
-/**
- @file atf.c
- @brief See header for details
- $Revision$
- $HeadURL$
-*/
-#include "atf.h"
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#ifndef NO_SIGNALS
-#include <signal.h>
-#endif
-
-char* Curr_Test = NULL;
-char* Curr_File = NULL;
-unsigned int Curr_Line = 0;
-static unsigned int Total = 0;
-static unsigned int Failed = 0;
-
-#ifndef NO_SIGNALS
-static void handle_signal(int sig) {
- /* Determine the signal name */
- char* sig_name = NULL;
- switch(sig) {
- case SIGABRT: sig_name = "SIGABRT"; break;
- case SIGBUS: sig_name = "SIGBUS"; break;
- case SIGFPE: sig_name = "SIGFPE"; break;
- case SIGILL: sig_name = "SIGILL"; break;
- case SIGSEGV: sig_name = "SIGSEGV"; break;
- case SIGSYS: sig_name = "SIGSYS"; break;
- /* If we don't recognize it then just return and let the default handler
- catch it. */
- default: return;
- }
- /* Error and exit. No summary will be printed but the user will know which
- test has crashed. */
- fprintf(stderr,"%s:%d:0:%s:CRASH (signal: %d - %s)\n", Curr_File, Curr_Line, Curr_Test, sig, sig_name);
- Failed++;
- (void)atf_print_results();
- exit(1);
-}
-#endif
-
-void atf_init(int argc, char** argv) {
- /* I reserve the right to use these later */
- (void)argc;
- (void)argv;
-
-#ifndef NO_SIGNALS
- /* Init signal handler */
- signal(SIGABRT, handle_signal);
- signal(SIGBUS, handle_signal);
- signal(SIGFPE, handle_signal);
- signal(SIGILL, handle_signal);
- signal(SIGSEGV, handle_signal);
- signal(SIGSYS, handle_signal);
-#endif
-}
-
-void atf_run_suite(suite_t suite) {
- suite();
-}
-
-void atf_test_start(char* file, unsigned int line, char* name) {
- Curr_File = file;
- Curr_Line = line;
- Curr_Test = name;
- Total++;
-}
-
-bool atf_test_assert(bool success, char* expr, char* file, int line) {
- bool failed = !success;
- if (failed) atf_test_fail(expr,file,line);
- return failed;
-}
-
-void atf_test_fail(char* expr, char* file, int line) {
- Failed++;
- printf("%s:%d:0:%s:FAIL:( %s )\n", file, line, Curr_Test, expr); \
-}
-
-int atf_print_results(void) {
- static const char* results_string =
- "\nUnit Test Summary"
- "\n-----------------"
- "\nTotal: %d"
- "\nPassed: %d"
- "\nFailed: %d"
- "\n\n";
- printf(results_string, Total, Total - Failed, Failed);
- return Failed;
-}
-