@@ -0,0 +1,187 @@
/*
conditionals.c
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include "conditionals.h"
#include <string.h>
#include <stdlib.h>
#include "var.h"
#include "dict.h"
#include "array.h"
#include "func.h"

typedef enum {
LESS,
GREATER,
LESSEQ,
GREATEREQ,
EQ,
NOTEQ
} comparison;

struct var *compd(struct array *, comparison);
struct var *compf(struct array *, comparison);

struct var *compd(struct array *args, comparison t) {
struct var *ret, *a1, *a2;
a1 = arrobj(args, 0);
a2 = arrobj(args, 1);

ret = calloc(1, sizeof(struct var));
ret->type = V_BOOL;

switch (t) {
case LESS:
ret->val.bval = (a1->val.ival < a2->val.ival);
break;

case LESSEQ:
ret->val.bval = (a1->val.ival <= a2->val.ival);
break;

case GREATER:
ret->val.bval = (a1->val.ival > a2->val.ival);
break;

case GREATEREQ:
ret->val.bval = (a1->val.ival >= a2->val.ival);
break;

case EQ:
ret->val.bval = (a1->val.ival == a2->val.ival);
break;

case NOTEQ:
ret->val.bval = (a1->val.ival != a2->val.ival);
break;

default:
break;
}
return ret;
}

struct var *compf(struct array *args, comparison t) {
struct var *ret, *a1, *a2;
a1 = arrobj(args, 0);
a2 = arrobj(args, 1);

ret = calloc(1, sizeof(struct var));
ret->type = V_BOOL;

switch (t) {
case LESS:
ret->val.bval = (a1->val.fval < a2->val.fval);
break;

case LESSEQ:
ret->val.bval = (a1->val.fval <= a2->val.fval);
break;

case GREATER:
ret->val.bval = (a1->val.fval > a2->val.fval);
break;

case GREATEREQ:
ret->val.bval = (a1->val.fval >= a2->val.fval);
break;

case EQ:
ret->val.bval = (a1->val.fval == a2->val.fval);
break;

case NOTEQ:
ret->val.bval = (a1->val.fval != a2->val.fval);
break;

default:
break;
}
return ret;
}

struct var *grtr(struct array *args) {
if (((struct var *)arrobj(args, 0))->type == V_INT)
return compd(args, GREATER);
else
return compf(args, GREATER);
}

struct var *less(struct array *args) {
if (((struct var *)arrobj(args, 0))->type == V_INT)
return compd(args, LESS);
else
return compf(args, LESS);
}

struct var *grteq(struct array *args) {
if (((struct var *)arrobj(args, 0))->type == V_INT)
return compd(args, GREATEREQ);
else
return compf(args, GREATEREQ);
}

struct var *lesseq(struct array *args) {
if (((struct var *)arrobj(args, 0))->type == V_INT)
return compd(args, LESSEQ);
else
return compf(args, LESSEQ);
}

struct var *eq(struct array *args) {
if (((struct var *)arrobj(args, 0))->type == V_INT)
return compd(args, EQ);
else
return compf(args, EQ);
}

struct var *noteq(struct array *args) {
if (((struct var *)arrobj(args, 0))->type == V_INT)
return compd(args, NOTEQ);
else
return compf(args, NOTEQ);
}

void condit_register(struct dict *funcs) {
struct func *f;

f = calloc(1, sizeof(struct func));
f->name = ">";
f->type = F_SPEC;
f->spec = grtr;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = ">=";
f->type = F_SPEC;
f->spec = grteq;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "<";
f->type = F_SPEC;
f->spec = less;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "<=";
f->type = F_SPEC;
f->spec = lesseq;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "=";
f->type = F_SPEC;
f->spec = eq;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "!=";
f->type = F_SPEC;
f->spec = noteq;
dictadd(funcs, f, f->name);
}
@@ -0,0 +1,26 @@
/*
conditionals.h
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__conditionals__
#define __pewter_lang__conditionals__

#include <stdio.h>

struct dict;
struct var;
struct array;

struct var *grtr(struct array *);
struct var *less(struct array *);
struct var *grteq(struct array *);
struct var *lesseq(struct array *);
struct var *eq(struct array *);
struct var *noteq(struct array *);
void condit_register(struct dict *);

#endif /* defined(__pewter_lang__conditionals__) */
44 cpu.c
@@ -0,0 +1,44 @@
/*
cpu.c
pewter_lang
Created by Christopher Loonam on 11/20/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdlib.h>
#include <unistd.h>
#include "dict.h"
#include "array.h"
#include "var.h"
#include "func.h"
#include "cpu.h"

struct var *slp(struct array *args) {
unsigned t;
struct var *v;

t = 0;
if (arrcnt(args) > 0) {
v = arrobj(args, 0);
if (v->type == V_INT) {
t = (unsigned)v->val.ival;
}
else if (v->type == V_DOUB) {
t = (unsigned)v->val.fval;
}
}
sleep(t);

return NULL;
}

void cpu_register(struct dict *funcs) {
struct func *f;

f = calloc(1, sizeof(struct func));
f->name = "wait";
f->type = F_SPEC;
f->spec = slp;
dictadd(funcs, f, f->name);
}
21 cpu.h
@@ -0,0 +1,21 @@
/*
cpu.h
pewter_lang
Created by Christopher Loonam on 11/20/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__cpu__
#define __pewter_lang__cpu__

#include <stdio.h>

struct dict;
struct array;
struct var;

struct var *slp(struct array *);
void cpu_register(struct dict *);

#endif /* defined(__pewter_lang__cpu__) */
115 dict.c
@@ -0,0 +1,115 @@
/*
dict.c
foundation
Created by Christopher Loonam on 11/8/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "hash.h"
#include "dict.h"

struct item {
struct item *next;
unsigned hash;
char *key;
void *o;
};

struct dict {
struct item *head;
unsigned cnt;
};

struct item * dictitem(dict_t *d, unsigned h);
void itemfree(struct item *);

dict_t * dictnew(void *o, const char *k, ...) {
dict_t *dic;
va_list lst;

dic = calloc(1, sizeof(struct dict));
dic->head = NULL;
if (!o || !k)
return dic;

va_start(lst, k);

do dictadd(dic, o, k);
while ((o = va_arg(lst, void *)) && (k = va_arg(lst, char *)));

va_end(lst);

return dic;
}

void * dictobj(dict_t *d, const char *k) {
struct item *i;

i = dictitem(d, (unsigned)hash(k));

return (i)?i->o:NULL;
}

struct item * dictitem(dict_t *d, unsigned h) {
struct item *i;

i = d->head;
if (!i)
return NULL;

do {
if (i->hash == h)
return i;
} while ((i = i->next));

return NULL;
}

void dictadd(dict_t *d, void *o, const char *k) {
struct item *i;

if ((i = dictitem(d, (unsigned)hash(k)))) {
i->o = o;
return;
}

d->cnt++;
i = d->head;
if (i) {
while (i->next) i = i->next;
i->next = calloc(1, sizeof(struct item));
i->next->hash = (unsigned)hash(k);
i->next->o = o;
i->next->key = strdup(k);
return;
}
d->head = calloc(1, sizeof(struct item));
d->head->hash = (unsigned)hash(k);
d->head->o = o;
d->head->key = strdup(k);
}

unsigned dictcnt(dict_t *d) {
return d->cnt;
}

void itemfree(struct item *i) {
struct item *tmp;

while (i) {
tmp = i;
i = i->next;

free(tmp->key);
free(tmp);
}
}

void dictfree(dict_t *d) {
itemfree(d->head);
free(d);
}
56 dict.h
@@ -0,0 +1,56 @@
/*
dict.h
foundation
Created by Christopher Loonam on 11/8/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __foundation__dict__
#define __foundation__dict__

#include <stdio.h>

/**
@brief @c dict_t is a structure that holds a set of keys, each with an associated object. The implementation utilizes a hash table to improve the speed.
*/
typedef struct dict dict_t;

/**
@brief Creates and returns a dictionary object, containing the keys and their associated objects that are passed as arguments. The arguments
@param obj The objects to be stored in the dictionary.
@param key The key to associate with @c obj, which is the argument that immediately precedes it.
@return A new dictionary object whose memory is dynamically allocated using @c calloc(). This should be freed after usage.
*/
dict_t * dictnew(void *obj, const char *key, ...); /* obj, key, terminate with NULL */

/**
@brief Returns the object associated with the key @c key that is located in the dictionary @c dict. The search is performed using a hash table, thereby increasing the speed of the search.
@param dict The dictionary which will be searched for the key.
@param key The key to match in the dictionary.
@return The object associated with @c key, if one exists. If one does not exist, @c NULL is returned.
*/
void * dictobj(dict_t *dict, const char *key);

/**
@brief Adds the object @c obj to the dictionary @c dict and associates it with the key @c key. If that key is already associated with a different object in the dictionary, it is changed to be associated with @c obj.
@param dict The dictionary to which the object will be added.
@param obj The object which will be added to the dictionary.
@param key The key to associate with @c obj.
*/
void dictadd(dict_t *dict, void *obj, const char *key); /* obj, key */

/**
@brief Returns the number of unique key/value pairs contained in the dictionary.
@param dict The dictionary whose count will be returned.
@return The number of unique key/value pairs located in @c dict.
*/
unsigned dictcnt(dict_t *dict);

/**
@brief Frees the memory occupied by the dictionary @c dict and the memory occupied by the hash table it uses to store its values.
@param dict The dictionary whose memory will be freed.
*/
void dictfree(dict_t *dict);

#endif /* defined(__foundation__dict__) */
546 eval.c

Large diffs are not rendered by default.

16 eval.h
@@ -0,0 +1,16 @@
/*
eval.h
pewter_lang
Created by Christopher Loonam on 11/16/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__eval__
#define __pewter_lang__eval__

#include <stdio.h>

int eval(const char *, int, char **);

#endif /* defined(__pewter_lang__eval__) */
9 expr.c
@@ -0,0 +1,9 @@
/*
expr.c
pewter_lang
Created by Christopher Loonam on 11/22/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdio.h>
24 expr.h
@@ -0,0 +1,24 @@
/*
// expr.h
// pewter_lang
//
// Created by Christopher Loonam on 11/16/15.
// Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef pewter_lang_expr_h
#define pewter_lang_expr_h

struct token;

struct expr {
char *expr;
struct token *tok;
struct expr *next;
enum {
E_NORM,
E_DECL
} type;
};

#endif
9 func.c
@@ -0,0 +1,9 @@
/*
func.c
pewter_lang
Created by Christopher Loonam on 11/22/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdio.h>
32 func.h
@@ -0,0 +1,32 @@
/*
// func.h
// pewter_lang
//
// Created by Christopher Loonam on 11/16/15.
// Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef pewter_lang_func_h
#define pewter_lang_func_h

struct expr;
struct var;
struct dict;
struct array;

struct func {
char *name;
struct array *args;
struct array *argnms;
struct dict *scope;
struct expr *expr;
struct func *next;
enum {
F_NORM,
F_SPEC,
F_CTL
} type;
struct var *(*spec)(struct array *args);
};

#endif
19 hash.c
@@ -0,0 +1,19 @@
/*
hash.c
foundation
Created by Christopher Loonam on 11/8/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include "hash.h"

uint32_t hash(const char *str) {
unsigned long hash = 5381;
int c;

while ((c = *str++))
hash = ((hash << 5) + hash) + (unsigned long)c; /* hash * 33 + c */

return (uint32_t)hash;
}
17 hash.h
@@ -0,0 +1,17 @@
/*
hash.h
foundation
Created by Christopher Loonam on 11/8/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __foundation__hash__
#define __foundation__hash__

#include <stdio.h>
#include <stdint.h>

uint32_t hash(const char *);

#endif /* defined(__foundation__hash__) */
@@ -0,0 +1,5 @@
#!/usr/local/bin/lang

func main()
(output "Hello, " (input))
end
125 io.c
@@ -0,0 +1,125 @@
/*
io.c
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "var.h"
#include "array.h"
#include "io.h"
#include "dict.h"
#include "func.h"

struct var *fiopen(struct array *args) {
struct var *ret;

if (arrcnt(args) < 1)
return NULL;
ret = calloc(1, sizeof(struct var));

ret->type = V_FILE;
ret->val.sval = ((struct var *)arrobj(args, 0))->val.sval;

return ret;
}

struct var *output(struct array *args) {
struct var *v;
unsigned i, j;
FILE *f;

f = stdout;
for (j = i = 0; i < arrcnt(args); i++) {
v = arrobj(args, i);
if (v->type == V_FILE)
f = fopen(v->val.sval, "a+"), j = 1;
}

for (i = 0; i < arrcnt(args); i++) {
v = arrobj(args, i);
switch (v->type) {
case V_DOUB:
fprintf(f, "%.6Lf", v->val.fval);
break;

case V_INT:
fprintf(f, "%ld", v->val.ival);
break;

case V_STR:
if (strcmp(v->val.sval, "\\n") == 0) {
putc('\n', f);
break;
}
fprintf(f, "%s", v->val.sval);
break;

default:
break;
}
}
fflush(f);
if (j)
fclose(f);
return NULL;
}

struct var *input(struct array *args) {
char *buf, c;
size_t i, j;
struct var *v;
FILE *f;

f = stdin;
for (j = i = 0; i < arrcnt(args); i++) {
v = arrobj(args, (unsigned)i);
if (v->type == V_FILE)
f = fopen(v->val.sval, "r"), j = 1;
}

i = 0;
buf = malloc(1);
args = NULL;
while ((c = (char)getc(f)) != '\n') {
buf = realloc(buf, ++i);
buf[i-1] = c;
}
buf = realloc(buf, ++i);
buf[i-1] = 0;

v = calloc(1, sizeof(struct var));
v->type = V_STR;
v->val.sval = buf;
v->name = "__input__";

if (j)
fclose(f);
return v;
}

void io_register(struct dict *funcs) {
struct func *f;

f = calloc(1, sizeof(struct func));
f->name = "open";
f->type = F_SPEC;
f->spec = fiopen;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "write";
f->type = F_SPEC;
f->spec = output;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "input";
f->type = F_SPEC;
f->spec = input;
dictadd(funcs, f, f->name);
}
23 io.h
@@ -0,0 +1,23 @@
/*
io.h
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__io__
#define __pewter_lang__io__

#include <stdio.h>

struct dict;
struct var;
struct array;

struct var *fiopen(struct array *);
struct var *input(struct array *);
struct var *output(struct array *);
void io_register(struct dict *);

#endif /* defined(__pewter_lang__io__) */
27 main.c
@@ -0,0 +1,27 @@
/*
// main.c
// pewter_lang
//
// Created by Christopher Loonam on 11/16/15.
// Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdio.h>
#include "eval.h"

int main(int argc, char **argv) {
FILE *f;
size_t n;
char buf[1024];

f = fopen(argv[1], "r");
if (!f) {
f = stdin;
}
n = fread(buf, 1, 1024, f);
buf[n] = 0;

eval(buf, argc, argv);

fclose(f);
}
@@ -0,0 +1,84 @@
/*
array.c
foundation
Created by Christopher Loonam on 11/8/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdlib.h>
#include <stdarg.h>
#include "array.h"

struct array {
void **objs;
unsigned cnt;
unsigned long sz;
};

array_t * arrnew(void *o, ...) {
array_t *ret;
va_list lst;

ret = calloc(1, sizeof(struct array));
ret->objs = malloc(1);
ret->cnt = 0;

if (!o)
return ret;

va_start(lst, o);

do arradd(ret, o);
while ((o = va_arg(lst, void *)));

va_end(lst);

return ret;
}

void * arrobj(array_t *arr, unsigned idx) {
if (idx >= arr->cnt)
return NULL;
return arr->objs[idx];
}

void arradd(array_t *arr, void *o) {
if (!o)
return;
arr->cnt++;
arr->sz += sizeof(o);
arr->objs = realloc(arr->objs, arr->sz);
arr->objs[arr->cnt - 1] = o;
}

void arrrm(array_t *arr, unsigned idx) {
array_t *new;
unsigned i;

if (idx >= arr->cnt)
return;

new = arrnew(NULL);

i = 0;
while (i < arr->cnt) {
if (i != idx)
arradd(new, arrobj(arr, i));
i++;
}
free(arr->objs);
arr->objs = new->objs;
arr->cnt = new->cnt;
arr->sz = new->sz;
free(new);
}

unsigned arrcnt(array_t *arr) {
return arr->cnt;
}

void arrfree(array_t *arr) {
free(arr->objs);
free(arr);
}
@@ -0,0 +1,61 @@
/*
array.h
foundation
Created by Christopher Loonam on 11/8/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __foundation__array__
#define __foundation__array__

#include <stdio.h>

/**
@brief @c array_t is a structure that holds an ordered collection of objects of any type.
*/
typedef struct array array_t;

/**
@brief Creates a new zero-indexed array.
@param o The objects the array will hold. This list must be terminated with @c NULL; if this is not done, the behavior is undefined.
@return A newly allocated array containing the objects passed as arguments; if no objects are passed in the function call, an empty array is returned. This array is dynamically allocated and should be freed with a call to @c arrfree()
*/
array_t * arrnew(void *o, ...);

/**
@brief Returns the object located at index @c idx.
@param arr The array from which the object will be returned.
@param idx The index of the object to be returned.
@return If @c idx is less than the count of the array, the object at that index will be returned. If @c idx is greater than or equal to the count of the array, @c NULL will be returned, as the index will be out of the range of the array.
*/
void * arrobj(array_t *arr, unsigned idx);

/**
@brief Appends an object to the end of an array.
@param arr The array to which the object will be added.
@param o The object to append to the array. If this argument is @c NULL, the array will go unmodified.
*/
void arradd(array_t *arr, void *o);

/**
@brief Removes the object located at index @c idx from the array.
@param arr The array from which the object will be removed.
@param idx The index of the object to be removed. If the index is outside of the bounds of the array, the array will go unmodified.
*/
void arrrm(array_t *arr, unsigned idx);

/**
@brief Returns the number of objects that are contained in the array @c arr.
@param arr The array whose count will be returned.
@return The count of the array @c arr.
*/
unsigned arrcnt(array_t *arr);

/**
@brief Frees the memory pointed to by the array.
@param arr The array pointer whose memory will be freed.
*/
void arrfree(array_t *arr);

#endif /* defined(__foundation__array__) */
@@ -0,0 +1,115 @@
/*
dict.c
foundation
Created by Christopher Loonam on 11/8/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "hash.h"
#include "dict.h"

struct item {
struct item *next;
unsigned hash;
char *key;
void *o;
};

struct dict {
struct item *head;
unsigned cnt;
};

struct item * dictitem(dict_t *d, unsigned h);
void itemfree(struct item *);

dict_t * dictnew(void *o, const char *k, ...) {
dict_t *dic;
va_list lst;

dic = calloc(1, sizeof(struct dict));
dic->head = NULL;
if (!o || !k)
return dic;

va_start(lst, k);

do dictadd(dic, o, k);
while ((o = va_arg(lst, void *)) && (k = va_arg(lst, char *)));

va_end(lst);

return dic;
}

void * dictobj(dict_t *d, const char *k) {
struct item *i;

i = dictitem(d, (unsigned)hash(k));

return (i)?i->o:NULL;
}

struct item * dictitem(dict_t *d, unsigned h) {
struct item *i;

i = d->head;
if (!i)
return NULL;

do {
if (i->hash == h)
return i;
} while ((i = i->next));

return NULL;
}

void dictadd(dict_t *d, void *o, const char *k) {
struct item *i;

if ((i = dictitem(d, (unsigned)hash(k)))) {
i->o = o;
return;
}

d->cnt++;
i = d->head;
if (i) {
while (i->next) i = i->next;
i->next = calloc(1, sizeof(struct item));
i->next->hash = (unsigned)hash(k);
i->next->o = o;
i->next->key = strdup(k);
return;
}
d->head = calloc(1, sizeof(struct item));
d->head->hash = (unsigned)hash(k);
d->head->o = o;
d->head->key = strdup(k);
}

unsigned dictcnt(dict_t *d) {
return d->cnt;
}

void itemfree(struct item *i) {
struct item *tmp;

while (i) {
tmp = i;
i = i->next;

free(tmp->key);
free(tmp);
}
}

void dictfree(dict_t *d) {
itemfree(d->head);
free(d);
}
@@ -0,0 +1,56 @@
/*
dict.h
foundation
Created by Christopher Loonam on 11/8/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __foundation__dict__
#define __foundation__dict__

#include <stdio.h>

/**
@brief @c dict_t is a structure that holds a set of keys, each with an associated object. The implementation utilizes a hash table to improve the speed.
*/
typedef struct dict dict_t;

/**
@brief Creates and returns a dictionary object, containing the keys and their associated objects that are passed as arguments. The arguments
@param obj The objects to be stored in the dictionary.
@param key The key to associate with @c obj, which is the argument that immediately precedes it.
@return A new dictionary object whose memory is dynamically allocated using @c calloc(). This should be freed after usage.
*/
dict_t * dictnew(void *obj, const char *key, ...); /* obj, key, terminate with NULL */

/**
@brief Returns the object associated with the key @c key that is located in the dictionary @c dict. The search is performed using a hash table, thereby increasing the speed of the search.
@param dict The dictionary which will be searched for the key.
@param key The key to match in the dictionary.
@return The object associated with @c key, if one exists. If one does not exist, @c NULL is returned.
*/
void * dictobj(dict_t *dict, const char *key);

/**
@brief Adds the object @c obj to the dictionary @c dict and associates it with the key @c key. If that key is already associated with a different object in the dictionary, it is changed to be associated with @c obj.
@param dict The dictionary to which the object will be added.
@param obj The object which will be added to the dictionary.
@param key The key to associate with @c obj.
*/
void dictadd(dict_t *dict, void *obj, const char *key); /* obj, key */

/**
@brief Returns the number of unique key/value pairs contained in the dictionary.
@param dict The dictionary whose count will be returned.
@return The number of unique key/value pairs located in @c dict.
*/
unsigned dictcnt(dict_t *dict);

/**
@brief Frees the memory occupied by the dictionary @c dict and the memory occupied by the hash table it uses to store its values.
@param dict The dictionary whose memory will be freed.
*/
void dictfree(dict_t *dict);

#endif /* defined(__foundation__dict__) */
@@ -0,0 +1,19 @@
/*
hash.c
foundation
Created by Christopher Loonam on 11/8/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include "hash.h"

uint32_t hash(const char *str) {
unsigned long hash = 5381;
int c;

while ((c = *str++))
hash = ((hash << 5) + hash) + (unsigned long)c; /* hash * 33 + c */

return (uint32_t)hash;
}
@@ -0,0 +1,17 @@
/*
hash.h
foundation
Created by Christopher Loonam on 11/8/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __foundation__hash__
#define __foundation__hash__

#include <stdio.h>
#include <stdint.h>

uint32_t hash(const char *);

#endif /* defined(__foundation__hash__) */
@@ -0,0 +1,27 @@
/*
// main.c
// pewter_lang
//
// Created by Christopher Loonam on 11/16/15.
// Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdio.h>
#include "eval.h"

int main(int argc, char **argv) {
FILE *f;
size_t n;
char buf[1024];

f = fopen(argv[1], "r");
if (!f) {
f = stdin;
}
n = fread(buf, 1, 1024, f);
buf[n] = 0;

eval(buf, argc, argv);

fclose(f);
}

Large diffs are not rendered by default.

@@ -0,0 +1,16 @@
/*
eval.h
pewter_lang
Created by Christopher Loonam on 11/16/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__eval__
#define __pewter_lang__eval__

#include <stdio.h>

int eval(const char *, int, char **);

#endif /* defined(__pewter_lang__eval__) */
@@ -0,0 +1,9 @@
/*
expr.c
pewter_lang
Created by Christopher Loonam on 11/22/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdio.h>
@@ -0,0 +1,24 @@
/*
// expr.h
// pewter_lang
//
// Created by Christopher Loonam on 11/16/15.
// Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef pewter_lang_expr_h
#define pewter_lang_expr_h

struct token;

struct expr {
char *expr;
struct token *tok;
struct expr *next;
enum {
E_NORM,
E_DECL
} type;
};

#endif
@@ -0,0 +1,9 @@
/*
func.c
pewter_lang
Created by Christopher Loonam on 11/22/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdio.h>
@@ -0,0 +1,32 @@
/*
// func.h
// pewter_lang
//
// Created by Christopher Loonam on 11/16/15.
// Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef pewter_lang_func_h
#define pewter_lang_func_h

struct expr;
struct var;
struct dict;
struct array;

struct func {
char *name;
struct array *args;
struct array *argnms;
struct dict *scope;
struct expr *expr;
struct func *next;
enum {
F_NORM,
F_SPEC,
F_CTL
} type;
struct var *(*spec)(struct array *args);
};

#endif
@@ -0,0 +1,58 @@
/*
token.c
pewter_lang
Created by Christopher Loonam on 11/18/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "token.h"

struct token *duptok(struct token *);

unsigned char iskey(struct token *tok) {
if (strcmp(tok->tok, "func") == 0 || strcmp(tok->tok, "end") == 0 || strcmp(tok->tok, "stop") == 0 || strcmp(tok->tok, "using") == 0)
return 1;
return 0;
}

unsigned char iswhte(struct token *tok) {
if (*(tok->tok) == ' ' || *(tok->tok) == 0)
return 1;
return 0;
}

unsigned char isctrl(struct token *tok) {
if (strcmp(tok->tok, "if") == 0 || strcmp(tok->tok, "while") == 0)
return 1;
return 0;
}

struct token *duptok(struct token *tok) {
struct token *ret;

ret = calloc(1, sizeof(struct token));
ret->tok = strdup(tok->tok);
ret->type = tok->type;
ret->next = NULL;

return ret;
}

struct token *remwht(struct token *tok) {
struct token *ret, *cpy;

cpy = duptok(tok);
ret = cpy;
tok = tok->next;
while (tok) {
if (tok->type != T_WHT && tok->tok && tok->tok[0])
cpy->next = duptok(tok), cpy = cpy->next;
tok = tok->next;
}

return ret;
}
@@ -0,0 +1,33 @@
/*
// token.h
// pewter_lang
//
// Created by Christopher Loonam on 11/16/15.
// Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef pewter_lang_token_h
#define pewter_lang_token_h

enum tok_type {
T_VAR = 1,
T_FUNC,
T_KEY,
T_LIT,
T_ASS,
T_WHT,
T_CTL
};

struct token {
char *tok;
enum tok_type type;
struct token *next;
};

unsigned char iskey(struct token *);
unsigned char iswhte(struct token *);
unsigned char isctrl(struct token *);
struct token *remwht(struct token *);

#endif
@@ -0,0 +1,9 @@
/*
var.c
pewter_lang
Created by Christopher Loonam on 11/22/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdio.h>
@@ -0,0 +1,37 @@
/*
// var.h
// pewter_lang
//
// Created by Christopher Loonam on 11/16/15.
// Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef pewter_lang_var_h
#define pewter_lang_var_h

struct array;
struct dict;

struct var {
char *name;
enum {
V_STR,
V_INT,
V_DOUB,
V_ARR,
V_DIC,
V_BOOL,
V_FILE
} type;
union {
char *sval;
long double fval;
long ival;
struct array *aval;
struct dict *dval;
unsigned int bval;
void *pval;
} val;
};

#endif
@@ -0,0 +1,223 @@
/*
arithmetic.c
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include "var.h"
#include "dict.h"
#include "array.h"
#include "arithmetic.h"
#include "func.h"

typedef enum {
ADD,
SUB,
MULT,
DIVID,
MOD
} ops;

struct var *arith(struct array *args, ops op);

struct var *arith(struct array *args, ops op) {
struct var *v, *ret;
unsigned i;

ret = calloc(1, sizeof(struct var));
ret->name = "__arith__";
ret->type = ((struct var *)arrobj(args, 0))->type;

for (i = 0; i < arrcnt(args); i++) {
v = arrobj(args, i);
if (i == 0)
ret->val = v->val;
else {
switch (op) {
case ADD:
if (ret->type == V_INT) {
ret->val.ival += (v->type == V_INT) ? v->val.ival : v->val.fval;
}
else {
ret->val.fval += (v->type == V_INT) ? v->val.ival : v->val.fval;
}
break;
case SUB:
if (ret->type == V_INT) {
ret->val.ival -= (v->type == V_INT) ? v->val.ival : v->val.fval;
}
else {
ret->val.fval -= (v->type == V_INT) ? v->val.ival : v->val.fval;
}
break;
case MULT:
if (ret->type == V_INT) {
ret->val.ival *= (v->type == V_INT) ? v->val.ival : v->val.fval;
}
else {
ret->val.fval *= (v->type == V_INT) ? v->val.ival : v->val.fval;
}
break;
case DIVID:
if (ret->type == V_INT) {
ret->val.ival /= (v->type == V_INT) ? v->val.ival : v->val.fval;
}
else {
ret->val.fval /= (v->type == V_INT) ? v->val.ival : v->val.fval;
}
break;

case MOD:
if (ret->type == V_INT) {
ret->val.ival = ret->val.ival % (long)((v->type == V_INT) ? v->val.ival : v->val.fval);
}
else {
ret->val.fval = (long)ret->val.fval % (long)((v->type == V_INT) ? v->val.ival : v->val.fval);
}
break;

default:
break;
}
}
}
return ret;
}

struct var *minus(struct array *args) {
return arith(args, SUB);
}

struct var *divd(struct array *args) {
return arith(args, DIVID);
}

struct var *mult(struct array *args) {
return arith(args, MULT);
}

struct var *add(struct array *args) {
struct var *v, *ret;
unsigned i;

ret = calloc(1, sizeof(struct var));
ret->name = "__add__";
ret->type = ((struct var *)arrobj(args, 0))->type;
if (ret->type == V_INT || ret->type == V_DOUB)
return arith(args, ADD);
else if (ret->type == V_STR) {
for (i = 0; i < arrcnt(args); i++) {
v = arrobj(args, i);

if (!ret->val.sval)
ret->val.sval = calloc(1, 1);
ret->val.sval = realloc(ret->val.sval, strlen(ret->val.sval) + strlen(v->val.sval) + 1);
strcat(ret->val.sval, v->val.sval);
}
}
else if (ret->type == V_ARR) {
ret->val.aval = ((struct var *)arrobj(args, 0))->val.aval;
for (i = 1; i < arrcnt(args); i++) {
v = arrobj(args, i);

arradd(ret->val.aval, v);
}
}

return ret;
}

struct var *mod(struct array *args) {
return arith(args, MOD);
}

struct var *ran(struct array *args) {
struct var *ret, *a;
static long seed;

if (!seed) {
seed = (long)time(NULL);
srand((unsigned int)seed);
}
if (arrcnt(args) > 0) {
a = arrobj(args, 0);
if (a->type == V_INT || a->type == V_DOUB)
seed = (long)((a->type == V_INT) ? a->val.ival : a->val.fval);
}

ret->type = V_INT;
ret->val.ival = (long)rand();

return ret;
}

struct var *power(struct array *args) {
long double num, pow;
struct var *v;

if (arrcnt(args) < 2)
return NULL;
v = arrobj(args, 0);
num = (long)((v->type == V_INT) ? v->val.ival : v->val.fval);
v = arrobj(args, 1);
pow = (long)((v->type == V_INT) ? v->val.ival : v->val.fval);

v = calloc(1, sizeof(struct var));
v->type = V_DOUB;
v->val.fval = powl(num, pow);
v->name = "__pow__";

return v;
}

void arith_register(struct dict *funcs) {
struct func *f;

f = calloc(1, sizeof(struct func));
f->name = "+";
f->type = F_SPEC;
f->spec = add;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "/";
f->type = F_SPEC;
f->spec = divd;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "*";
f->type = F_SPEC;
f->spec = mult;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "-";
f->type = F_SPEC;
f->spec = minus;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "%";
f->type = F_SPEC;
f->spec = mod;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "random";
f->type = F_SPEC;
f->spec = ran;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "^";
f->type = F_SPEC;
f->spec = power;
dictadd(funcs, f, f->name);
}
@@ -0,0 +1,27 @@
/*
arithmetic.h
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__arithmetic__
#define __pewter_lang__arithmetic__

#include <stdio.h>

struct dict;
struct array;
struct var;

struct var *minus(struct array *);
struct var *divd(struct array *);
struct var *mult(struct array *);
struct var *add(struct array *);
struct var *mod(struct array *);
struct var *ran(struct array *);
struct var *power(struct array *);
void arith_register(struct dict *);

#endif /* defined(__pewter_lang__arithmetic__) */
@@ -0,0 +1,187 @@
/*
conditionals.c
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include "conditionals.h"
#include <string.h>
#include <stdlib.h>
#include "var.h"
#include "dict.h"
#include "array.h"
#include "func.h"

typedef enum {
LESS,
GREATER,
LESSEQ,
GREATEREQ,
EQ,
NOTEQ
} comparison;

struct var *compd(struct array *, comparison);
struct var *compf(struct array *, comparison);

struct var *compd(struct array *args, comparison t) {
struct var *ret, *a1, *a2;
a1 = arrobj(args, 0);
a2 = arrobj(args, 1);

ret = calloc(1, sizeof(struct var));
ret->type = V_BOOL;

switch (t) {
case LESS:
ret->val.bval = (a1->val.ival < a2->val.ival);
break;

case LESSEQ:
ret->val.bval = (a1->val.ival <= a2->val.ival);
break;

case GREATER:
ret->val.bval = (a1->val.ival > a2->val.ival);
break;

case GREATEREQ:
ret->val.bval = (a1->val.ival >= a2->val.ival);
break;

case EQ:
ret->val.bval = (a1->val.ival == a2->val.ival);
break;

case NOTEQ:
ret->val.bval = (a1->val.ival != a2->val.ival);
break;

default:
break;
}
return ret;
}

struct var *compf(struct array *args, comparison t) {
struct var *ret, *a1, *a2;
a1 = arrobj(args, 0);
a2 = arrobj(args, 1);

ret = calloc(1, sizeof(struct var));
ret->type = V_BOOL;

switch (t) {
case LESS:
ret->val.bval = (a1->val.fval < a2->val.fval);
break;

case LESSEQ:
ret->val.bval = (a1->val.fval <= a2->val.fval);
break;

case GREATER:
ret->val.bval = (a1->val.fval > a2->val.fval);
break;

case GREATEREQ:
ret->val.bval = (a1->val.fval >= a2->val.fval);
break;

case EQ:
ret->val.bval = (a1->val.fval == a2->val.fval);
break;

case NOTEQ:
ret->val.bval = (a1->val.fval != a2->val.fval);
break;

default:
break;
}
return ret;
}

struct var *grtr(struct array *args) {
if (((struct var *)arrobj(args, 0))->type == V_INT)
return compd(args, GREATER);
else
return compf(args, GREATER);
}

struct var *less(struct array *args) {
if (((struct var *)arrobj(args, 0))->type == V_INT)
return compd(args, LESS);
else
return compf(args, LESS);
}

struct var *grteq(struct array *args) {
if (((struct var *)arrobj(args, 0))->type == V_INT)
return compd(args, GREATEREQ);
else
return compf(args, GREATEREQ);
}

struct var *lesseq(struct array *args) {
if (((struct var *)arrobj(args, 0))->type == V_INT)
return compd(args, LESSEQ);
else
return compf(args, LESSEQ);
}

struct var *eq(struct array *args) {
if (((struct var *)arrobj(args, 0))->type == V_INT)
return compd(args, EQ);
else
return compf(args, EQ);
}

struct var *noteq(struct array *args) {
if (((struct var *)arrobj(args, 0))->type == V_INT)
return compd(args, NOTEQ);
else
return compf(args, NOTEQ);
}

void condit_register(struct dict *funcs) {
struct func *f;

f = calloc(1, sizeof(struct func));
f->name = ">";
f->type = F_SPEC;
f->spec = grtr;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = ">=";
f->type = F_SPEC;
f->spec = grteq;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "<";
f->type = F_SPEC;
f->spec = less;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "<=";
f->type = F_SPEC;
f->spec = lesseq;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "=";
f->type = F_SPEC;
f->spec = eq;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "!=";
f->type = F_SPEC;
f->spec = noteq;
dictadd(funcs, f, f->name);
}
@@ -0,0 +1,26 @@
/*
conditionals.h
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__conditionals__
#define __pewter_lang__conditionals__

#include <stdio.h>

struct dict;
struct var;
struct array;

struct var *grtr(struct array *);
struct var *less(struct array *);
struct var *grteq(struct array *);
struct var *lesseq(struct array *);
struct var *eq(struct array *);
struct var *noteq(struct array *);
void condit_register(struct dict *);

#endif /* defined(__pewter_lang__conditionals__) */
@@ -0,0 +1,44 @@
/*
cpu.c
pewter_lang
Created by Christopher Loonam on 11/20/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdlib.h>
#include <unistd.h>
#include "dict.h"
#include "array.h"
#include "var.h"
#include "func.h"
#include "cpu.h"

struct var *slp(struct array *args) {
unsigned t;
struct var *v;

t = 0;
if (arrcnt(args) > 0) {
v = arrobj(args, 0);
if (v->type == V_INT) {
t = (unsigned)v->val.ival;
}
else if (v->type == V_DOUB) {
t = (unsigned)v->val.fval;
}
}
sleep(t);

return NULL;
}

void cpu_register(struct dict *funcs) {
struct func *f;

f = calloc(1, sizeof(struct func));
f->name = "wait";
f->type = F_SPEC;
f->spec = slp;
dictadd(funcs, f, f->name);
}
@@ -0,0 +1,21 @@
/*
cpu.h
pewter_lang
Created by Christopher Loonam on 11/20/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__cpu__
#define __pewter_lang__cpu__

#include <stdio.h>

struct dict;
struct array;
struct var;

struct var *slp(struct array *);
void cpu_register(struct dict *);

#endif /* defined(__pewter_lang__cpu__) */
@@ -0,0 +1,125 @@
/*
io.c
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "var.h"
#include "array.h"
#include "io.h"
#include "dict.h"
#include "func.h"

struct var *fiopen(struct array *args) {
struct var *ret;

if (arrcnt(args) < 1)
return NULL;
ret = calloc(1, sizeof(struct var));

ret->type = V_FILE;
ret->val.sval = ((struct var *)arrobj(args, 0))->val.sval;

return ret;
}

struct var *output(struct array *args) {
struct var *v;
unsigned i, j;
FILE *f;

f = stdout;
for (j = i = 0; i < arrcnt(args); i++) {
v = arrobj(args, i);
if (v->type == V_FILE)
f = fopen(v->val.sval, "a+"), j = 1;
}

for (i = 0; i < arrcnt(args); i++) {
v = arrobj(args, i);
switch (v->type) {
case V_DOUB:
fprintf(f, "%.6Lf", v->val.fval);
break;

case V_INT:
fprintf(f, "%ld", v->val.ival);
break;

case V_STR:
if (strcmp(v->val.sval, "\\n") == 0) {
putc('\n', f);
break;
}
fprintf(f, "%s", v->val.sval);
break;

default:
break;
}
}
fflush(f);
if (j)
fclose(f);
return NULL;
}

struct var *input(struct array *args) {
char *buf, c;
size_t i, j;
struct var *v;
FILE *f;

f = stdin;
for (j = i = 0; i < arrcnt(args); i++) {
v = arrobj(args, (unsigned)i);
if (v->type == V_FILE)
f = fopen(v->val.sval, "r"), j = 1;
}

i = 0;
buf = malloc(1);
args = NULL;
while ((c = (char)getc(f)) != '\n') {
buf = realloc(buf, ++i);
buf[i-1] = c;
}
buf = realloc(buf, ++i);
buf[i-1] = 0;

v = calloc(1, sizeof(struct var));
v->type = V_STR;
v->val.sval = buf;
v->name = "__input__";

if (j)
fclose(f);
return v;
}

void io_register(struct dict *funcs) {
struct func *f;

f = calloc(1, sizeof(struct func));
f->name = "open";
f->type = F_SPEC;
f->spec = fiopen;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "write";
f->type = F_SPEC;
f->spec = output;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "input";
f->type = F_SPEC;
f->spec = input;
dictadd(funcs, f, f->name);
}
@@ -0,0 +1,23 @@
/*
io.h
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__io__
#define __pewter_lang__io__

#include <stdio.h>

struct dict;
struct var;
struct array;

struct var *fiopen(struct array *);
struct var *input(struct array *);
struct var *output(struct array *);
void io_register(struct dict *);

#endif /* defined(__pewter_lang__io__) */
@@ -0,0 +1,18 @@
/*
standard.h
pewter_lang
Created by Christopher Loonam on 11/17/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__standard__
#define __pewter_lang__standard__

#include "arithmetic.h"
#include "io.h"
#include "types.h"
#include "conditionals.h"
#include "cpu.h"

#endif /* defined(__pewter_lang__speclib__) */
@@ -0,0 +1,147 @@
/*
types.c
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdlib.h>
#include <string.h>
#include "var.h"
#include "array.h"
#include "dict.h"
#include "types.h"
#include "func.h"

struct var *idx(struct array *args) {
struct var *idx, *arr, *v;

arr = arrobj(args, 0);
idx = arrobj(args, 1);

if (arr->type == V_ARR)
return arrobj(arr->val.aval, (idx->type == V_INT) ? (unsigned)idx->val.ival : (unsigned)idx->val.fval);
else if (arr->type == V_DIC)
return dictobj(arr->val.dval, idx->val.sval);
else if (arr->type == V_STR) {
v = calloc(1, sizeof(struct var));
v->type = V_STR;
v->name = "__idx__";
v->val.sval = malloc(2);
strncpy(v->val.sval, &arr->val.sval[(idx->type == V_INT) ? (unsigned)idx->val.ival : (unsigned)idx->val.fval], 1);
v->val.sval[1] = 0;
return v;
}
return NULL;
}

struct var *toint(struct array *args) {
struct var *a;
a = arrobj(args, 0);
if (a->type != V_INT) {
a->type = V_INT;
a->val.ival = strtol(a->val.sval, NULL, 10);
}
return a;
}

struct var *tostr(struct array *args) {
struct var *a;
a = arrobj(args, 0);
if (a->type == V_DOUB) {
a->type = V_STR;
asprintf(&a->val.sval, "%Lf", a->val.fval);
}
else if (a->type == V_DOUB) {
a->type = V_STR;
asprintf(&a->val.sval, "%ld", a->val.ival);
}
return a;
}

struct var *count(struct array *args) {
struct var *a, *ret;

ret = calloc(1, sizeof(struct var));
ret->type = V_INT;
a = arrobj(args, 0);
switch (a->type) {
case V_STR:
ret->val.ival = (long)strlen(a->val.sval);
break;

case V_ARR:
ret->val.ival = (long)arrcnt(a->val.aval);
break;

case V_DIC:
ret->val.ival = (long)dictcnt(a->val.dval);
break;

default:
break;
}

return ret;
}

struct var *copy(struct array *args) {
struct var *a, *ret;


ret = calloc(1, sizeof(struct var));
a = arrobj(args, 0);
ret->type = a->type;
switch (a->type) {
case V_STR:
ret->val.sval = strdup(a->val.sval);
break;

case V_ARR:
/* ret->val.aval = (long)arrcnt(a->val.aval); TODO: implement copy for these */
break;

case V_DIC:
ret->val.ival = (long)dictcnt(a->val.dval);
break;

default:
break;
}
return ret;
}

void types_register(struct dict *funcs) {
struct func *f;

f = calloc(1, sizeof(struct func));
f->name = "obj";
f->type = F_SPEC;
f->spec = idx;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "int";
f->type = F_SPEC;
f->spec = toint;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "str";
f->type = F_SPEC;
f->spec = tostr;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "count";
f->type = F_SPEC;
f->spec = count;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "copy";
f->type = F_SPEC;
f->spec = copy;
dictadd(funcs, f, f->name);
}
@@ -0,0 +1,25 @@
/*
types.h
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__types__
#define __pewter_lang__types__

#include <stdio.h>

struct dict;
struct var;
struct array;

struct var *idx(struct array *);
struct var *toint(struct array *);
struct var *tostr(struct array *);
struct var *copy(struct array *);
struct var *count(struct array *);
void types_register(struct dict *);

#endif /* defined(__pewter_lang__types__) */
@@ -0,0 +1,18 @@
/*
standard.h
pewter_lang
Created by Christopher Loonam on 11/17/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__standard__
#define __pewter_lang__standard__

#include "arithmetic.h"
#include "io.h"
#include "types.h"
#include "conditionals.h"
#include "cpu.h"

#endif /* defined(__pewter_lang__speclib__) */
@@ -0,0 +1,9 @@
func output()
n = 0
while (< n (count args))
a = (obj args n)
(write a)
n = (+ n 1)
(write "\n")
stop
end
@@ -0,0 +1,36 @@
using standard

func split(s)
n = 0
p = ""
a = []
while (< n (count s))
p = (+ p (obj s n))

if (= n (/ (count s) 2))
(+ a (copy p))
p = ""
stop
n = (+ n 1)
stop
a
end

func main()
f = (open "/Users/christopherloonam/Desktop/text.txt")
(output (input f))

#(output (^ 4 -4)) # expressions can be separated by either a newline or semicolon
array = ["key 1" "object 2" ["asfd" "asdasdasd" 0]]
(output (obj array 0))

dict = {"key 1" "object 1" "key 2" "object 2"} # dictionary syntax
k = (obj array 0)
(output (obj dict k))
(output (random))
(wait 010)
(output (random))

p = (split "Hello, world!")
(output (obj p 1))
end
@@ -0,0 +1,5 @@
#!/usr/local/bin/lang

func main()
(output "Hello, " (input))
end
@@ -0,0 +1,9 @@
func output()
n = 0
while (< n (count args))
a = (obj args n)
(write a)
n = (+ n 1)
(write "\n")
stop
end
@@ -0,0 +1,36 @@
using standard

func split(s)
n = 0
p = ""
a = []
while (< n (count s))
p = (+ p (obj s n))

if (= n (/ (count s) 2))
(+ a (copy p))
p = ""
stop
n = (+ n 1)
stop
a
end

func main()
f = (open "/Users/christopherloonam/Desktop/text.txt")
(output (input f))

#(output (^ 4 -4)) # expressions can be separated by either a newline or semicolon
array = ["key 1" "object 2" ["asfd" "asdasdasd" 0]]
(output (obj array 0))

dict = {"key 1" "object 1" "key 2" "object 2"} # dictionary syntax
k = (obj array 0)
(output (obj dict k))
(output (random))
(wait 010)
(output (random))

p = (split "Hello, world!")
(output (obj p 1))
end
58 token.c
@@ -0,0 +1,58 @@
/*
token.c
pewter_lang
Created by Christopher Loonam on 11/18/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "token.h"

struct token *duptok(struct token *);

unsigned char iskey(struct token *tok) {
if (strcmp(tok->tok, "func") == 0 || strcmp(tok->tok, "end") == 0 || strcmp(tok->tok, "stop") == 0 || strcmp(tok->tok, "using") == 0)
return 1;
return 0;
}

unsigned char iswhte(struct token *tok) {
if (*(tok->tok) == ' ' || *(tok->tok) == 0)
return 1;
return 0;
}

unsigned char isctrl(struct token *tok) {
if (strcmp(tok->tok, "if") == 0 || strcmp(tok->tok, "while") == 0)
return 1;
return 0;
}

struct token *duptok(struct token *tok) {
struct token *ret;

ret = calloc(1, sizeof(struct token));
ret->tok = strdup(tok->tok);
ret->type = tok->type;
ret->next = NULL;

return ret;
}

struct token *remwht(struct token *tok) {
struct token *ret, *cpy;

cpy = duptok(tok);
ret = cpy;
tok = tok->next;
while (tok) {
if (tok->type != T_WHT && tok->tok && tok->tok[0])
cpy->next = duptok(tok), cpy = cpy->next;
tok = tok->next;
}

return ret;
}
33 token.h
@@ -0,0 +1,33 @@
/*
// token.h
// pewter_lang
//
// Created by Christopher Loonam on 11/16/15.
// Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef pewter_lang_token_h
#define pewter_lang_token_h

enum tok_type {
T_VAR = 1,
T_FUNC,
T_KEY,
T_LIT,
T_ASS,
T_WHT,
T_CTL
};

struct token {
char *tok;
enum tok_type type;
struct token *next;
};

unsigned char iskey(struct token *);
unsigned char iswhte(struct token *);
unsigned char isctrl(struct token *);
struct token *remwht(struct token *);

#endif
147 types.c
@@ -0,0 +1,147 @@
/*
types.c
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdlib.h>
#include <string.h>
#include "var.h"
#include "array.h"
#include "dict.h"
#include "types.h"
#include "func.h"

struct var *idx(struct array *args) {
struct var *idx, *arr, *v;

arr = arrobj(args, 0);
idx = arrobj(args, 1);

if (arr->type == V_ARR)
return arrobj(arr->val.aval, (idx->type == V_INT) ? (unsigned)idx->val.ival : (unsigned)idx->val.fval);
else if (arr->type == V_DIC)
return dictobj(arr->val.dval, idx->val.sval);
else if (arr->type == V_STR) {
v = calloc(1, sizeof(struct var));
v->type = V_STR;
v->name = "__idx__";
v->val.sval = malloc(2);
strncpy(v->val.sval, &arr->val.sval[(idx->type == V_INT) ? (unsigned)idx->val.ival : (unsigned)idx->val.fval], 1);
v->val.sval[1] = 0;
return v;
}
return NULL;
}

struct var *toint(struct array *args) {
struct var *a;
a = arrobj(args, 0);
if (a->type != V_INT) {
a->type = V_INT;
a->val.ival = strtol(a->val.sval, NULL, 10);
}
return a;
}

struct var *tostr(struct array *args) {
struct var *a;
a = arrobj(args, 0);
if (a->type == V_DOUB) {
a->type = V_STR;
asprintf(&a->val.sval, "%Lf", a->val.fval);
}
else if (a->type == V_DOUB) {
a->type = V_STR;
asprintf(&a->val.sval, "%ld", a->val.ival);
}
return a;
}

struct var *count(struct array *args) {
struct var *a, *ret;

ret = calloc(1, sizeof(struct var));
ret->type = V_INT;
a = arrobj(args, 0);
switch (a->type) {
case V_STR:
ret->val.ival = (long)strlen(a->val.sval);
break;

case V_ARR:
ret->val.ival = (long)arrcnt(a->val.aval);
break;

case V_DIC:
ret->val.ival = (long)dictcnt(a->val.dval);
break;

default:
break;
}

return ret;
}

struct var *copy(struct array *args) {
struct var *a, *ret;


ret = calloc(1, sizeof(struct var));
a = arrobj(args, 0);
ret->type = a->type;
switch (a->type) {
case V_STR:
ret->val.sval = strdup(a->val.sval);
break;

case V_ARR:
/* ret->val.aval = (long)arrcnt(a->val.aval); TODO: implement copy for these */
break;

case V_DIC:
ret->val.ival = (long)dictcnt(a->val.dval);
break;

default:
break;
}
return ret;
}

void types_register(struct dict *funcs) {
struct func *f;

f = calloc(1, sizeof(struct func));
f->name = "obj";
f->type = F_SPEC;
f->spec = idx;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "int";
f->type = F_SPEC;
f->spec = toint;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "str";
f->type = F_SPEC;
f->spec = tostr;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "count";
f->type = F_SPEC;
f->spec = count;
dictadd(funcs, f, f->name);

f = calloc(1, sizeof(struct func));
f->name = "copy";
f->type = F_SPEC;
f->spec = copy;
dictadd(funcs, f, f->name);
}
25 types.h
@@ -0,0 +1,25 @@
/*
types.h
pewter_lang
Created by Christopher Loonam on 11/19/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef __pewter_lang__types__
#define __pewter_lang__types__

#include <stdio.h>

struct dict;
struct var;
struct array;

struct var *idx(struct array *);
struct var *toint(struct array *);
struct var *tostr(struct array *);
struct var *copy(struct array *);
struct var *count(struct array *);
void types_register(struct dict *);

#endif /* defined(__pewter_lang__types__) */
9 var.c
@@ -0,0 +1,9 @@
/*
var.c
pewter_lang
Created by Christopher Loonam on 11/22/15.
Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#include <stdio.h>
37 var.h
@@ -0,0 +1,37 @@
/*
// var.h
// pewter_lang
//
// Created by Christopher Loonam on 11/16/15.
// Copyright (c) 2015 Christopher Loonam. All rights reserved.
*/

#ifndef pewter_lang_var_h
#define pewter_lang_var_h

struct array;
struct dict;

struct var {
char *name;
enum {
V_STR,
V_INT,
V_DOUB,
V_ARR,
V_DIC,
V_BOOL,
V_FILE
} type;
union {
char *sval;
long double fval;
long ival;
struct array *aval;
struct dict *dval;
unsigned int bval;
void *pval;
} val;
};

#endif