#include "builtins/core.h"
 #include "builtins/arithmetic.h"
 #include "builtins/combinators.h"
+#include "builtins/io.h"
 
 #include <inttypes.h>
 
                return x_arith_dispatch(b, rest, env);
        case COMB_PREFIX:
                return x_comb_dispatch(b, rest, env);
+       case IO_PREFIX:
+               return x_io_dispatch(b, rest, env);
        default:
                return from_nil();
        }
        newenv = load_core_env(env);
        newenv = load_arith_env(newenv);
        newenv = load_comb_env(newenv);
+       newenv = load_io_env(newenv);
 
        return newenv;
 }
 
--- /dev/null
+
+
+#include "../types.h"
+#include "../builtins.h"
+#include "../sexpr.h"
+#include "../config.h"
+#include "io.h"
+
+#include <stdlib.h>
+#include <inttypes.h>
+
+Sexpr* io_print(Sexpr* b, Sexpr* rest, Sexpr* env) {
+       if(IO_PRINT_ARGS != u64_get_num_args(b)) {
+               return cons(b, rest);
+       }
+       Sexpr* arg = clone(car(b->value.b.args));
+       sexpr_free(b);
+       char* out = sprint_sexpr(arg);
+       sexpr_free(arg);
+       PRINT(out);
+       free(out);
+       return cons(from_t(), rest);
+}
+
+
+Sexpr* x_io_dispatch(Sexpr* b, Sexpr* rest, Sexpr* env) {
+       uint64_t code = b->value.b.opcode & 0xff;
+
+       switch(code) {
+       case IO_PRINT:
+               return io_print(b, rest, env);
+       default:
+               return from_nil();
+       }
+       return from_nil();
+}
+
+Sexpr* load_io_env(Sexpr* env) {
+       load_builtin("print", (IO_PREFIX << 8) | IO_PRINT, env);
+
+       return env;
+}
 
--- /dev/null
+#ifndef _B_IO_H
+#define _B_IO_H
+
+#include "../types.h"
+
+#define IO_PREFIX 0x03
+
+#define IO_PRINT 0x00
+#define IO_PRINT_ARGS 1
+
+Sexpr* x_io_dispatch(Sexpr* s, Sexpr* rest, Sexpr* env);
+Sexpr* load_io_env(Sexpr* env);
+
+
+
+#endif
 
--- /dev/null
+#ifndef _CONFIG_H
+#define _CONFIG_H
+
+
+// configuration file for various compile-time things
+// i.e. uint size, so on
+
+
+
+#include <stdio.h>
+
+#define K_UINT_TYPE uint64_t
+#define K_UINT_PRINT PRIu64
+#define K_UINT_SCAN SCNu64
+
+#define WARN(m, v) printf("WARN: %s%s\n", m, v)
+#define ERR(m, v) printf("ERROR: %s%s\n", m, v)
+#define PRINTMV(m, v) printf("%s%s\n", m, v)
+#define PRINT(s) printf("%s\n", s)
+
+#endif
 
 
 #include <stdio.h>
 #include <stdlib.h>
+//#include <unistd.h>
 
 #include <editline/readline.h>
 
 #include "parser.h"
 #include "builtins.h"
 #include "sexpr.h"
+#include "util.h"
 
 
 int main(int argc, char** argv) {
        Sexpr* env = init_dict();
        load_env(env);
 
+       while(argc > 1) {
+               printf("ac/av: %d, %s\n", argc, argv[argc-1]);
+               // lol am i loading files back to front?
+               env = load_file(env, argv[argc-1]);
+               argc--;
+       }
+       
        char* input = NULL;
        while(1) {
                input = readline("> ");
 
--- /dev/null
+
+// this file exists becaause I didn't know where else to put the load_file function...
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "types.h"
+#include "sexpr.h"
+#include "eval.h"
+#include "builtins.h"
+#include "parser.h"
+
+Sexpr* load_file(Sexpr* env, char* path) {
+       char* buf;
+       size_t len;
+       FILE* f = fopen(path, "r");
+       if(f) {
+               fseek(f, 0, SEEK_END);
+               len = ftell(f);
+               fseek(f, 0, SEEK_SET);
+               buf = malloc(len+1);
+               if(buf) {
+                       fread(buf, 1, len, f);
+                       buf[len] = '\n'; // deals with no newline at end shenanigans
+               }
+               fclose(f);
+               if(buf) {
+                       // file loaded into buf
+                       // wait i forget how my dealloc works with this stuff, gonna have to play with it
+                       Sexpr* in = parse(buf);
+                       free(buf);
+                       if(in==NULL) return env;
+                       Sexpr* curr = in;
+                       // okay, the file is likely a bunch of (def ...)s, so i need to eval this expression by expression
+                       while(curr->type != NIL) {
+                               eval(clone(car(curr)), env);
+                               curr = cdr(curr);
+                       }
+               }
+       }
+       return env;
+}
 
--- /dev/null
+#ifndef _UTIL_H
+#define _UTIL_H
+
+#include "types.h"
+
+Sexpr* load_file(Sexpr* env, char* path);
+
+
+
+
+#endif