Initial Commit

This commit is contained in:
2014-05-20 15:32:21 +01:00
commit 46bbd52885
30 changed files with 2029 additions and 0 deletions

5
.dep.inc Normal file
View File

@@ -0,0 +1,5 @@
# This code depends on make tool being used
DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES}))
ifneq (${DEPFILES},)
include ${DEPFILES}
endif

27
.gitignore vendored Normal file
View File

@@ -0,0 +1,27 @@
# Object files
*.o
*.ko
*.obj
*.elf
# Libraries
*.lib
*.a
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
#Other
/dist
/build

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "lib/mpc"]
path = lib/mpc
url = https://github.com/orangeduck/mpc.git

128
Makefile Normal file
View File

@@ -0,0 +1,128 @@
#
# There exist several targets which are by default empty and which can be
# used for execution of your targets. These targets are usually executed
# before and after some main targets. They are:
#
# .build-pre: called before 'build' target
# .build-post: called after 'build' target
# .clean-pre: called before 'clean' target
# .clean-post: called after 'clean' target
# .clobber-pre: called before 'clobber' target
# .clobber-post: called after 'clobber' target
# .all-pre: called before 'all' target
# .all-post: called after 'all' target
# .help-pre: called before 'help' target
# .help-post: called after 'help' target
#
# Targets beginning with '.' are not intended to be called on their own.
#
# Main targets can be executed directly, and they are:
#
# build build a specific configuration
# clean remove built files from a configuration
# clobber remove all built files
# all build all configurations
# help print help mesage
#
# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
# .help-impl are implemented in nbproject/makefile-impl.mk.
#
# Available make variables:
#
# CND_BASEDIR base directory for relative paths
# CND_DISTDIR default top distribution directory (build artifacts)
# CND_BUILDDIR default top build directory (object files, ...)
# CONF name of current configuration
# CND_PLATFORM_${CONF} platform name (current configuration)
# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
#
# NOCDDL
# Environment
MKDIR=mkdir
CP=cp
CCADMIN=CCadmin
# build
build: .build-post
.build-pre:
# Add your pre 'build' code here...
.build-post: .build-impl
# Add your post 'build' code here...
# clean
clean: .clean-post
.clean-pre:
# Add your pre 'clean' code here...
.clean-post: .clean-impl
# Add your post 'clean' code here...
# clobber
clobber: .clobber-post
.clobber-pre:
# Add your pre 'clobber' code here...
.clobber-post: .clobber-impl
# Add your post 'clobber' code here...
# all
all: .all-post
.all-pre:
# Add your pre 'all' code here...
.all-post: .all-impl
# Add your post 'all' code here...
# build tests
build-tests: .build-tests-post
.build-tests-pre:
# Add your pre 'build-tests' code here...
.build-tests-post: .build-tests-impl
# Add your post 'build-tests' code here...
# run tests
test: .test-post
.test-pre: build-tests
# Add your pre 'test' code here...
.test-post: .test-impl
# Add your post 'test' code here...
# help
help: .help-post
.help-pre:
# Add your pre 'help' code here...
.help-post: .help-impl
# Add your post 'help' code here...
# include project implementation makefile
include nbproject/Makefile-impl.mk
# include project make variables
include nbproject/Makefile-variables.mk

BIN
core Normal file

Binary file not shown.

184
functions.c Normal file
View File

@@ -0,0 +1,184 @@
#include <stdlib.h>
#include <float.h>
#include "lang.h"
#include "main.h"
void lenv_add_builtin(lenv* env, char* sym, lbuiltin func) {
lval* symval = lval_sym(sym);
lval* funcval = lval_func(func, sym);
lenv_put(env, symval, funcval);
lval_delete(symval);
lval_delete(funcval);
}
void lenv_add_builtin_funcs(lenv* env) {
//Math functions
lenv_add_builtin(env, "+", builtin_add);
lenv_add_builtin(env, "-", builtin_sub);
lenv_add_builtin(env, "/", builtin_div);
lenv_add_builtin(env, "*", builtin_mul);
lenv_add_builtin(env, "^", builtin_pow);
//List/Util functions
lenv_add_builtin(env, "list", builtin_list);
lenv_add_builtin(env, "eval", builtin_eval);
lenv_add_builtin(env, "join", builtin_join);
lenv_add_builtin(env, "head", builtin_head);
lenv_add_builtin(env, "tail", builtin_tail);
//ENV Functions
lenv_add_builtin(env, "def", builtin_def);
lenv_add_builtin(env, "listenv", builtin_listenv);
lenv_add_builtin(env, "exit", builtin_exit);
}
lval* builtin_add(lenv* env, lval* val) {
return builtin_op(env, val, "+");
}
lval* builtin_sub(lenv* env, lval* val) {
return builtin_op(env, val, "-");
}
lval* builtin_div(lenv* env, lval* val) {
return builtin_op(env, val, "+");
}
lval* builtin_mul(lenv* env, lval* val) {
return builtin_op(env, val, "*");
}
lval* builtin_pow(lenv* env, lval* val){
return builtin_op(env, val, "^");
}
lval* builtin_op(lenv* env, lval* val, char* op) {
//Ensure numbers only
for(int i = 0; i < val->cell_count; i++) {
if (val->cell_list[i]->type != LVAL_NUM) {
lval_delete(val);
return lval_err(LERR_BAD_NUM);
}
}
//Get the first element
lval* x = lval_pop(val, 0);
if (strcmp(op, "-") == 0 && val->cell_count == 0) {
x->data.num = -x->data.num;
}
while(val->cell_count > 0) {
//Get next to process
lval* y = lval_pop(val, 0);
if (strcmp(op, "+") == 0) { x->data.num += y->data.num; }
if (strcmp(op, "-") == 0) { x->data.num -= y->data.num; }
if (strcmp(op, "*") == 0) { x->data.num *= y->data.num; }
if (strcmp(op, "^") == 0) { x->data.num = pow(x->data.num,y->data.num); }
if (strcmp(op, "/") == 0) {
int zero = 0;
if (y->type == LVAL_NUM && fabs(y->data.num) <= DBL_EPSILON) {zero = 1;}
if (zero) {
lval_delete(x);
lval_delete(y);
x = lval_err(LERR_DIV_ZERO);
break;
}
x->data.num /= y->data.num;
}
lval_delete(y);
}
lval_delete(val);
return x;
}
lval* builtin_list(lenv* env, lval* val){
val->type = LVAL_Q_EXPR;
return val;
}
lval* builtin_eval(lenv* env, lval* val){
LASSERT_ARG_COUNT("eval", val, val, 1);
LASSERT_TYPE("eval", val, val->cell_list[0], LVAL_Q_EXPR);
lval* x = lval_take(val, 0);
x->type = LVAL_S_EXPR;
return eval(env, x);
}
lval* builtin_join(lenv* env, lval* val){
LASSERT_MIN_ARG_COUNT("join", val, val, 1);
for(int i = 0; i < val->cell_count; i++) {
LASSERT_TYPE("join", val, val->cell_list[i], LVAL_Q_EXPR);
}
lval* x = lval_pop(val,0);
while(val->cell_count > 0) {
x = lval_join(x, lval_pop(val, 0));
}
return x;
}
lval* builtin_head(lenv* env, lval* val){
LASSERT_ARG_COUNT("head",val , val, 1);
LASSERT_TYPE("head",val , val->cell_list[0], LVAL_Q_EXPR);
LASSERT_MIN_ARG_COUNT("head", val, val->cell_list[0], 1);
lval* x = lval_take(val, 0);
while(x->cell_count > 1) { lval_delete(lval_pop(x, 1)); }
return x;
}
lval* builtin_tail(lenv* env, lval* val){
LASSERT_ARG_COUNT("tail",val , val, 1);
LASSERT_TYPE("tail", val, val->cell_list[0], LVAL_Q_EXPR);
LASSERT_MIN_ARG_COUNT("tail", val, val->cell_list[0], 1);
lval* x = lval_take(val, 0);
lval_delete(lval_pop(x, 0));
return x;
}
lval* builtin_def(lenv* env, lval* val) {
LASSERT_MIN_ARG_COUNT("def", val, val, 1);
LASSERT_TYPE("def", val, val->cell_list[0], LVAL_Q_EXPR);
lval* symbols = val->cell_list[0];
for(int i = 0; i < symbols->cell_count; i++) {
LASSERT_TYPE("def", val, symbols->cell_list[i], LVAL_SYM);
}
LASSERT(val, symbols->cell_count == val->cell_count -1,
LERR_OTHER, "def: incorrect number of definitions for symbols");
for(int i = 0; i < symbols->cell_count; i++) {
lenv_put(env, symbols->cell_list[i], val->cell_list[i+1]);
}
lval_delete(val);
return lval_s_expr();
}
lval* builtin_listenv(lenv* env, lval* val) {
for(int i=0; i< env->count; i++) {
printf("%s: ", env->syms[i]->sym);
lval_println(env->syms[i]->lval);
}
lval_delete(val);
return lval_s_expr();
}
lval* builtin_exit(lenv* env, lval* val) {
lval* args = lval_q_expr();
for(int i=0; i<val->cell_count; i++) {
lval_add(args, lval_copy(val->cell_list[i]));
}
lval* sym = lval_sym("exitcode");
lenv_put(env, sym, args);
lval_delete(args);
lval_delete(sym);
lval_delete(val);
return lval_exit();
}

46
functions.h Normal file
View File

@@ -0,0 +1,46 @@
/*
* File: functions.h
* Author: sam
*
* Created on 18 May 2014, 22:41
*/
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "lang.h"
void lenv_add_builtin(lenv* env, char* sym, lbuiltin func);
void lenv_add_builtin_funcs(lenv* env);
//Math functions
lval* builtin_add(lenv* env, lval* val);
lval* builtin_sub(lenv* env, lval* val);
lval* builtin_div(lenv* env, lval* val);
lval* builtin_mul(lenv* env, lval* val);
lval* builtin_pow(lenv* env, lval* val);
lval* builtin_op(lenv* env, lval* val, char* op);
//List/Util functions
lval* builtin_list(lenv* env, lval* val);
lval* builtin_eval(lenv* env, lval* val);
lval* builtin_join(lenv* env, lval* val);
lval* builtin_head(lenv* env, lval* val);
lval* builtin_tail(lenv* env, lval* val);
//ENV Functions
lval* builtin_def(lenv* env, lval* val);
lval* builtin_listenv(lenv* env, lval* val);
lval* builtin_exit(lenv* env, lval* val);
#ifdef __cplusplus
}
#endif
#endif /* FUNCTIONS_H */

121
lang.c Normal file
View File

@@ -0,0 +1,121 @@
#include <float.h>
#include <stdio.h>
#include "mpc.h"
#include "lang.h"
mpc_ast_t* tokenize(char *input) {
mpc_parser_t* Number = mpc_new("number");
mpc_parser_t* Symbol = mpc_new("symbol");
mpc_parser_t* S_Expr = mpc_new("s_expr");
mpc_parser_t* Q_Expr = mpc_new("q_expr");
mpc_parser_t* Expr = mpc_new("expr");
mpc_parser_t* Lispy = mpc_new("lispy");
mpca_lang(MPCA_LANG_DEFAULT,
" \
number : /-?[0-9]+(\\.[0-9]+)?/ ; \
symbol : /[a-zA-Z0-9_+\\-*\\/\\\\=<>!&]+/ ; \
s_expr : '(' <expr>* ')' ; \
q_expr : '{' <expr>* '}' ; \
expr : <number> | <symbol> | <s_expr> | <q_expr> ; \
lispy : /^/ <expr>+ /$/ ; \
",
Number, Symbol, Expr, S_Expr, Q_Expr, Lispy);
mpc_result_t result;
int success = 1;
if (!mpc_parse("<stdin>", input,Lispy, &result)) {
success = 0;
mpc_err_print(result.error);
mpc_err_delete(result.error);
}
mpc_cleanup(6, Number, Symbol, S_Expr, Expr, Lispy, Q_Expr);
return success ? (mpc_ast_t*)result.output : NULL;
}
lval* parse(mpc_ast_t *t) {
if (strstr(t->tag, "number")) {
errno = 0;
double_t d = strtod(t->contents, NULL);
return errno != 0 ? lval_err_detail(LERR_BAD_NUM, strerror(errno)) : lval_num(d);
}
if (strstr(t->tag, "symbol")) {
return lval_sym(t->contents);
}
lval* result = NULL;
if (strcmp(t->tag, ">") == 0) { result = lval_s_expr(); }
if (result == NULL && strstr(t->tag, "s_expr")) { result = lval_s_expr(); }
if (result == NULL && strstr(t->tag, "q_expr")) { result = lval_q_expr(); }
for (int i = 0; i < t->children_num; i++) {
if (strcmp(t->children[i]->contents, "(") == 0) { continue; }
if (strcmp(t->children[i]->contents, ")") == 0) { continue; }
if (strcmp(t->children[i]->contents, "}") == 0) { continue; }
if (strcmp(t->children[i]->contents, "{") == 0) { continue; }
if (strcmp(t->children[i]->tag, "regex") == 0) { continue; }
result = lval_add(result, parse(t->children[i]));
}
return result;
}
lval* eval_s_expr(lenv* env, lval* val) {
//Eval children
for(int i = 0; i < val->cell_count; i++) {
val->cell_list[i] = eval(env, val->cell_list[i]);
}
//Check for errors or exit
for(int i = 0; i < val->cell_count; i++) {
if (val->cell_list[i]->type == LVAL_ERR) {
return lval_take(val, i);
}
if (val->cell_list[i]->type == LVAL_EXIT) {
lval* exit = lval_copy(val->cell_list[i]);
lval_delete(val);
return exit;
}
}
//empty
if (val->cell_count == 0) {
return val;
}
//single
if (val->cell_count == 1) {
return lval_take(val, 0);
}
//Ensure first is symbol
lval* func = lval_pop(val, 0);
if (func->type != LVAL_FUNC) {
VAL_TYPE type = func->type;
lval_delete(func);
lval_delete(val);
return lval_err_detail(LERR_BAD_OP, "First element is not %s got %s", lval_str_name(LVAL_FUNC), lval_str_name(type));
}
//Call builtin
lval* result = func->data.func.call(env, val);
lval_delete(func);
return result;
}
lval* eval(lenv* env, lval* val) {
if (val->type == LVAL_SYM) {
lval* x = lenv_get(env, val);
lval_delete(val);
return x;
}
if (val->type == LVAL_S_EXPR) {
return eval_s_expr(env, val);
}
return val;
}

49
lang.h Normal file
View File

@@ -0,0 +1,49 @@
/*
* File: lang.h
* Author: sam
*
* Created on 18 May 2014, 21:19
*/
#ifndef LANG_H
#define LANG_H
#ifdef __cplusplus
extern "C" {
#endif
#include "mpc.h"
#include "lval.h"
#include "lenv.h"
#include "functions.h"
#define LASSERT(val, cond, errnum, errdetail, ...) \
if (!(cond)) { \
lval * err = lval_err_detail(errnum, errdetail, ##__VA_ARGS__); \
lval_delete(val); \
return err; \
}
#define LASSERT_TYPE(name, val, subject, expectedType) \
LASSERT(val, subject->type == expectedType, \
LERR_SYNTAX, "%s Expected type %s got %s", name, lval_str_name(expectedType), lval_str_name(subject->type))
#define LASSERT_ARG_COUNT(name, val, subject, expectedNum) \
LASSERT(val, subject->cell_count == expectedNum, \
LERR_SYNTAX, "%s Expected %ld arguments got %ld", name, expectedNum, subject->cell_count )
#define LASSERT_MIN_ARG_COUNT(name, val, subject, expectedNum) \
LASSERT(val, subject->cell_count >= expectedNum, \
LERR_SYNTAX, "%s Expected %ld or more arguments got %ld", name, expectedNum, subject->cell_count )
mpc_ast_t* tokenize(char *input);
lval* parse(mpc_ast_t *t);
lval* eval_builtin_op(lval* val, char* op);
lval* eval_s_expr(lenv* env, lval* val);
lval* eval(lenv* env, lval* val);
#ifdef __cplusplus
}
#endif
#endif /* LANG_H */

92
lenv.c Normal file
View File

@@ -0,0 +1,92 @@
#include <stdlib.h>
#include <bits/stdlib-bsearch.h>
#include "lang.h"
#include "util.h"
lenv* lenv_new() {
lenv* env = calloc(1, sizeof(lenv));
env->count = 0;
env->syms = NULL;
return env;
}
void lenv_delete(lenv* env) {
for(int i = 0; i < env->count; i++) {
lval_delete(env->syms[i]->lval);
free(env->syms[i]->sym);
free(env->syms[i]);
}
free(env->syms);
free(env);
}
int lenv_compare_symtabs(const void *lhs, const void *rhs) {
const struct symtab* l = *(const struct symtab**)lhs;
const struct symtab* r = *(const struct symtab**)rhs;
return strcmp(l->sym, r->sym);
}
void lenv_sort(lenv* env) {
qsort(env->syms, env->count, sizeof(symtab*), lenv_compare_symtabs);
}
symtab* lenv_search(lenv* env, char* sym) {
if (env->count == 0) {
return NULL;
}
symtab* searchElem = symtab_new(sym, NULL);
symtab** searchComp = calloc(1, sizeof(symtab*));
searchComp[0] = searchElem;
symtab** result = bsearch(searchComp, env->syms, env->count, sizeof(symtab*), lenv_compare_symtabs);
free(searchComp);
symtab_delete(searchElem);
if (result == NULL) {
return NULL;
}
return *result;
}
lval* lenv_get(lenv* env, lval* sym) {
LASSERT(sym, sym->type == LVAL_SYM, LERR_BAD_OP, "Expected symbol");
symtab* result = lenv_search(env, sym->data.sym);
return result != NULL ? lval_copy(result->lval) : lval_err(LERR_BAD_SYM);
}
void lenv_put(lenv* env, lval* key, lval* val) {
symtab* result = lenv_search(env, key->data.sym);
if (result != NULL) {
lval_delete(result->lval);
result->lval = lval_copy(val);
lenv_sort(env);
return;
}
env->count ++;
env->syms = realloc(env->syms, sizeof(symtab*) * env->count);
env->syms[env->count-1] = symtab_new(key->data.sym, val);
lenv_sort(env);
}
symtab* symtab_new(char* sym, lval* lval) {
symtab* new = calloc(1, sizeof(symtab));
new->lval = lval == NULL ? NULL : lval_copy(lval);
new->sym = strdup(sym);
return new;
}
void symtab_delete(symtab* symtab) {
if (symtab->lval != NULL) {
lval_delete(symtab->lval);
}
free(symtab->sym);
free(symtab);
}

49
lenv.h Normal file
View File

@@ -0,0 +1,49 @@
/*
* File: lenv.h
* Author: sam
*
* Created on 18 May 2014, 21:36
*/
#ifndef LENV_H
#define LENV_H
#ifdef __cplusplus
extern "C" {
#endif
struct lenv;
typedef struct lenv lenv;
struct symtab;
typedef struct symtab symtab;
struct symtab {
char* sym;
lval* lval;
};
struct lenv {
size_t count;
struct symtab** syms;
};
lenv* lenv_new();
void lenv_delete(lenv* env);
int lenv_compare_symtabs(const void *a, const void *b);
void lenv_sort(lenv* env);
symtab* lenv_search(lenv* env, char* sym);
lval* lenv_get(lenv* env, lval* sym);
void lenv_put(lenv* env, lval* key, lval* val);
symtab* symtab_new(char* sym, lval* lval);
void symtab_delete(symtab* symtab);
#ifdef __cplusplus
}
#endif
#endif /* LENV_H */

1
lib/mpc Submodule

Submodule lib/mpc added at 6af8360517

190
lval.c Normal file
View File

@@ -0,0 +1,190 @@
#include <stdlib.h>
#include "lang.h"
#include "util.h"
lval* lval_new(int type) {
lval* val = calloc(1,sizeof(lval));
val->type = type;
return val;
}
lval* lval_num(double_t x) {
lval* val = lval_new(LVAL_NUM);
val->data.num = x;
return val;
}
lval* lval_sym(char* x) {
lval* val = lval_new(LVAL_SYM);
val->data.sym = strdup(x);
return val;
}
lval* lval_s_expr() {
lval* val = lval_new(LVAL_S_EXPR);
val->cell_count = 0;
val->cell_list = NULL;
return val;
}
lval* lval_q_expr() {
lval* val = lval_new(LVAL_Q_EXPR);
val->cell_count = 0;
val->cell_list = NULL;
return val;
}
lval* lval_func(lbuiltin func, char* name) {
lval* val = lval_new(LVAL_FUNC);
val->data.func.call = func;
val->data.func.name = strdup(name);
return val;
}
lval* lval_exit() {
lval* val = lval_new(LVAL_EXIT);
return val;
}
lval* lval_add(lval* val, lval* x) {
val->cell_count++;
val->cell_list = realloc(val->cell_list, sizeof(lval*)*val->cell_count);
val->cell_list[val->cell_count-1] = x;
return val;
}
lval* lval_pop(lval* val, int index) {
//Get the item
lval* x = val->cell_list[index];
//Re-create the list ignoring the index we are extracting
lval** newList = NULL;
if (val->cell_count-1 > 0) {
newList = calloc(val->cell_count-1, sizeof(lval*));
int k = 0;
for(int i=0; i < val->cell_count; i++) {
if (i == index) {
continue;
}
newList[k++] = val->cell_list[i];
}
}
val->cell_count--;
free(val->cell_list);
val->cell_list = newList;
return x;
}
lval* lval_take(lval* val, int i) {
lval* x = lval_pop(val, i);
lval_delete(val);
return x;
}
lval* lval_join(lval* a, lval* b) {
while(b->cell_count > 0) {
lval_add(a, lval_pop(b,0));
}
lval_delete(b);
return a;
}
void lval_delete(lval* val) {
switch(val->type) {
case LVAL_NUM: break;
case LVAL_EXIT: break;
case LVAL_FUNC: free(val->data.func.name); break;
case LVAL_SYM: free(val->data.sym); break;
case LVAL_ERR:
if (val->data.err.detail != NULL) {
free(val->data.err.detail);
}
break;
case LVAL_Q_EXPR:
case LVAL_S_EXPR:
for (int i = 0; i < val->cell_count; i++) {
lval_delete(val->cell_list[i]);
}
if (val->cell_count > 0) {
free(val->cell_list);
}
break;
}
free(val);
}
lval* lval_copy(lval* current) {
lval* new = lval_new(current->type);
switch(current->type) {
case LVAL_FUNC:
new->data.func.call = current->data.func.call;
new->data.func.name = strdup(current->data.func.name);
break;
case LVAL_NUM: new->data.num = current->data.num; break;
case LVAL_EXIT: break;
case LVAL_SYM: new->data.sym = strdup(current->data.sym); break;
case LVAL_ERR:
new->data.err.num = current->data.err.num;
new->data.err.detail = current->data.err.detail == NULL ? NULL : strdup(current->data.err.detail);
break;
case LVAL_Q_EXPR:
case LVAL_S_EXPR:
new->cell_count = current->cell_count;
if (new->cell_count == 0) {
new->cell_list = NULL;
} else {
new->cell_list = calloc(new->cell_count, sizeof(lval*));
for(int i=0; i < new->cell_count; i++) {
new->cell_list[i] = lval_copy(current->cell_list[i]);
}
}
break;
}
return new;
}
lval* lval_err(VAL_ERROR err){
return lval_err_detail(err, NULL);
}
lval* lval_err_detail(VAL_ERROR err, char* format, ...){
lval* val = lval_new(LVAL_ERR);
val->data.err.num = err;
va_list va;
va_start(va, format);
val->data.err.detail = calloc(512, sizeof(char));
vsnprintf(val->data.err.detail, 511, format, va);
if (strlen(val->data.err.detail) == 0) {
free(val->data.err.detail);
val->data.err.detail = NULL;
} else {
val->data.err.detail = realloc(val->data.err.detail, strlen(val->data.err.detail)+1);
}
va_end(va);
return val;
}
char* lval_str_name(VAL_TYPE type) {
switch(type) {
case LVAL_ERR: return "Error";
case LVAL_FUNC: return "Function";
case LVAL_NUM: return "Numeric";
case LVAL_Q_EXPR: return "Q-Expression";
case LVAL_SYM: return "Symbol";
case LVAL_S_EXPR: return "S-Expression";
default: return "UNKNOWN";
}
}

72
lval.h Normal file
View File

@@ -0,0 +1,72 @@
/*
* File: lval.h
* Author: sam
*
* Created on 18 May 2014, 21:22
*/
#ifndef LVAL_H
#define LVAL_H
#ifdef __cplusplus
extern "C" {
#endif
struct lval;
typedef struct lval lval;
#include "lenv.h"
enum VAL_TYPE { LVAL_ERR, LVAL_NUM, LVAL_SYM, LVAL_FUNC, LVAL_S_EXPR, LVAL_Q_EXPR, LVAL_EXIT };
enum VAL_ERROR { LERR_DIV_ZERO, LERR_BAD_OP, LERR_BAD_NUM, LERR_BAD_SYM, LERR_OTHER, LERR_SYNTAX };
typedef enum VAL_TYPE VAL_TYPE;
typedef enum VAL_ERROR VAL_ERROR;
typedef lval*(*lbuiltin)(lenv*, lval*);
typedef struct lval {
enum VAL_TYPE type;
union {
double_t num;
char* sym;
struct {
enum VAL_ERROR num;
char* detail;
} err;
struct {
char* name;
lbuiltin call;
} func;
} data;
int cell_count;
struct lval** cell_list;
} lval;
lval* lval_new(int type);
lval* lval_num(double_t x);
lval* lval_sym(char* x);
lval* lval_s_expr();
lval* lval_q_expr();
lval* lval_func(lbuiltin func, char* name);
lval* lval_exit();
lval* lval_add(lval* val, lval* x);
lval* lval_pop(lval* val, int i);
lval* lval_take(lval* val, int i);
lval* lval_join(lval* a, lval* b);
void lval_delete(lval* val);
lval* lval_copy(lval* current);
lval* lval_err(VAL_ERROR x);
lval* lval_err_detail(VAL_ERROR x, char* format, ...);
char* lval_str_name(VAL_TYPE type);
#ifdef __cplusplus
}
#endif
#endif /* LVAL_H */

124
main.c Normal file
View File

@@ -0,0 +1,124 @@
/*
* File: main.c
* Author: sam
*
* Created on 17 May 2014, 11:49
*/
#include <stdio.h>
#include <stdlib.h>
#include <editline/readline.h>
#include <editline/history.h>
#include "mpc.h"
#include "lang.h"
#include "main.h"
/*
*
*/
int main(int argc, char** argv) {
printf("KLisp Version %s\n", VERSION);
//Init environment
lenv* env = lenv_new();
lenv_add_builtin_funcs(env);
while(1) {
char *input = readline("> ");
if (NULL == input) {
break;
}
add_history(input);
mpc_ast_t* ast_result = tokenize(input);
free(input);
if (ast_result != NULL) {
//Parse the ast
lval* result = parse(ast_result);
if (result == NULL) {
result = lval_err(LERR_OTHER);
}
//Evaluate
result = eval(env, result);
int exit = 0;
if (result != NULL && result->type == LVAL_EXIT) {
exit = 1;
} else {
//print the result
lval_println(result);
}
//Cleanup
lval_delete(result);
mpc_ast_delete(ast_result);
if (exit == 1) {
printf("Program Terminated: ");
lval* sym = lval_sym("exitcode");
lval* exitcode = lenv_get(env, sym);
lval_println(exitcode);
lval_delete(exitcode);
lval_delete(sym);
break;
}
}
}
lenv_delete(env);
return (EXIT_SUCCESS);
}
void lval_expr_print(lval* val, char* open, char* close) {
printf("%s", open);
for(int i = 0; i < val->cell_count ; i++) {
lval_print(val->cell_list[i]);
if (i != val->cell_count-1) {
putchar(' ');
}
}
printf("%s", close);
}
void lval_print(lval* val) {
switch(val->type) {
case LVAL_NUM: printf("%g", val->data.num); break;
case LVAL_SYM: printf("%s", val->data.sym); break;
case LVAL_S_EXPR: lval_expr_print(val, "(", ")"); break;
case LVAL_Q_EXPR: lval_expr_print(val, "{", "}"); break;
case LVAL_FUNC: printf("<%s>", val->data.func.name); break;
case LVAL_EXIT: printf("exit"); break;
case LVAL_ERR:
printf("Error: ");
switch(val->data.err.num) {
case LERR_DIV_ZERO: printf("Divide By Zero"); break;
case LERR_BAD_NUM: printf("Bad Number"); break;
case LERR_BAD_OP: printf("Invalid Operator"); break;
case LERR_BAD_SYM: printf("Unknown/Invalid Symbol"); break;
case LERR_OTHER: printf("Unknown Error"); break;
case LERR_SYNTAX: printf("Syntax Error"); break;
default: printf("Unknown Error"); break;
}
if (val->data.err.detail != NULL) {
printf(", %s", val->data.err.detail);
}
break;
}
}
void lval_println(lval* val) {
lval_print(val);
putchar('\n');
}

28
main.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* File: main.h
* Author: sam
*
* Created on 17 May 2014, 16:15
*/
#ifndef MAIN_H
#define MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
#define VERSION "0.1"
int main(int argc, char** argv);
void lval_expr_print(lval* val, char* open, char* close);
void lval_print(lval* val);
void lval_println(lval* val);
#ifdef __cplusplus
}
#endif
#endif /* MAIN_H */

120
nbproject/Makefile-Debug.mk Normal file
View File

@@ -0,0 +1,120 @@
#
# Generated Makefile - do not edit!
#
# Edit the Makefile in the project folder instead (../Makefile). Each target
# has a -pre and a -post target defined where you can add customized code.
#
# This makefile implements configuration specific macros and targets.
# Environment
MKDIR=mkdir
CP=cp
GREP=grep
NM=nm
CCADMIN=CCadmin
RANLIB=ranlib
CC=gcc
CCC=g++
CXX=g++
FC=gfortran
AS=as
# Macros
CND_PLATFORM=GNU-Linux-x86
CND_DLIB_EXT=so
CND_CONF=Debug
CND_DISTDIR=dist
CND_BUILDDIR=build
# Include project Makefile
include Makefile
# Object Directory
OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
# Object Files
OBJECTFILES= \
${OBJECTDIR}/_ext/1360931409/mpc.o \
${OBJECTDIR}/functions.o \
${OBJECTDIR}/lang.o \
${OBJECTDIR}/lenv.o \
${OBJECTDIR}/lval.o \
${OBJECTDIR}/main.o \
${OBJECTDIR}/util.o
# C Compiler Flags
CFLAGS=-O0
# CC Compiler Flags
CCFLAGS=
CXXFLAGS=
# Fortran Compiler Flags
FFLAGS=
# Assembler Flags
ASFLAGS=
# Link Libraries and Options
LDLIBSOPTIONS=`pkg-config --libs libedit` -lm
# Build Targets
.build-conf: ${BUILD_SUBPROJECTS}
"${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/klisp
${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/klisp: ${OBJECTFILES}
${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
${LINK.c} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/klisp ${OBJECTFILES} ${LDLIBSOPTIONS}
${OBJECTDIR}/_ext/1360931409/mpc.o: ../mpc/mpc.c
${MKDIR} -p ${OBJECTDIR}/_ext/1360931409
${RM} "$@.d"
$(COMPILE.c) -g -Wall -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1360931409/mpc.o ../mpc/mpc.c
${OBJECTDIR}/functions.o: functions.c
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.c) -g -Wall -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/functions.o functions.c
${OBJECTDIR}/lang.o: lang.c
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.c) -g -Wall -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lang.o lang.c
${OBJECTDIR}/lenv.o: lenv.c
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.c) -g -Wall -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lenv.o lenv.c
${OBJECTDIR}/lval.o: lval.c
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.c) -g -Wall -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lval.o lval.c
${OBJECTDIR}/main.o: main.c
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.c) -g -Wall -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.c
${OBJECTDIR}/util.o: util.c
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.c) -g -Wall -Ilib/mpc `pkg-config --cflags libedit` -std=c99 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/util.o util.c
# Subprojects
.build-subprojects:
# Clean Targets
.clean-conf: ${CLEAN_SUBPROJECTS}
${RM} -r ${CND_BUILDDIR}/${CND_CONF}
${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/klisp
# Subprojects
.clean-subprojects:
# Enable dependency checking
.dep.inc: .depcheck-impl
include .dep.inc

View File

@@ -0,0 +1,120 @@
#
# Generated Makefile - do not edit!
#
# Edit the Makefile in the project folder instead (../Makefile). Each target
# has a -pre and a -post target defined where you can add customized code.
#
# This makefile implements configuration specific macros and targets.
# Environment
MKDIR=mkdir
CP=cp
GREP=grep
NM=nm
CCADMIN=CCadmin
RANLIB=ranlib
CC=gcc
CCC=g++
CXX=g++
FC=gfortran
AS=as
# Macros
CND_PLATFORM=GNU-Linux-x86
CND_DLIB_EXT=so
CND_CONF=Release
CND_DISTDIR=dist
CND_BUILDDIR=build
# Include project Makefile
include Makefile
# Object Directory
OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
# Object Files
OBJECTFILES= \
${OBJECTDIR}/_ext/1360931409/mpc.o \
${OBJECTDIR}/functions.o \
${OBJECTDIR}/lang.o \
${OBJECTDIR}/lenv.o \
${OBJECTDIR}/lval.o \
${OBJECTDIR}/main.o \
${OBJECTDIR}/util.o
# C Compiler Flags
CFLAGS=
# CC Compiler Flags
CCFLAGS=
CXXFLAGS=
# Fortran Compiler Flags
FFLAGS=
# Assembler Flags
ASFLAGS=
# Link Libraries and Options
LDLIBSOPTIONS=
# Build Targets
.build-conf: ${BUILD_SUBPROJECTS}
"${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/klisp
${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/klisp: ${OBJECTFILES}
${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
${LINK.c} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/klisp ${OBJECTFILES} ${LDLIBSOPTIONS}
${OBJECTDIR}/_ext/1360931409/mpc.o: ../mpc/mpc.c
${MKDIR} -p ${OBJECTDIR}/_ext/1360931409
${RM} "$@.d"
$(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/1360931409/mpc.o ../mpc/mpc.c
${OBJECTDIR}/functions.o: functions.c
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/functions.o functions.c
${OBJECTDIR}/lang.o: lang.c
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lang.o lang.c
${OBJECTDIR}/lenv.o: lenv.c
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lenv.o lenv.c
${OBJECTDIR}/lval.o: lval.c
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/lval.o lval.c
${OBJECTDIR}/main.o: main.c
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.c
${OBJECTDIR}/util.o: util.c
${MKDIR} -p ${OBJECTDIR}
${RM} "$@.d"
$(COMPILE.c) -O2 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/util.o util.c
# Subprojects
.build-subprojects:
# Clean Targets
.clean-conf: ${CLEAN_SUBPROJECTS}
${RM} -r ${CND_BUILDDIR}/${CND_CONF}
${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/klisp
# Subprojects
.clean-subprojects:
# Enable dependency checking
.dep.inc: .depcheck-impl
include .dep.inc

133
nbproject/Makefile-impl.mk Normal file
View File

@@ -0,0 +1,133 @@
#
# Generated Makefile - do not edit!
#
# Edit the Makefile in the project folder instead (../Makefile). Each target
# has a pre- and a post- target defined where you can add customization code.
#
# This makefile implements macros and targets common to all configurations.
#
# NOCDDL
# Building and Cleaning subprojects are done by default, but can be controlled with the SUB
# macro. If SUB=no, subprojects will not be built or cleaned. The following macro
# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
# and .clean-reqprojects-conf unless SUB has the value 'no'
SUB_no=NO
SUBPROJECTS=${SUB_${SUB}}
BUILD_SUBPROJECTS_=.build-subprojects
BUILD_SUBPROJECTS_NO=
BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
CLEAN_SUBPROJECTS_=.clean-subprojects
CLEAN_SUBPROJECTS_NO=
CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
# Project Name
PROJECTNAME=KLisp
# Active Configuration
DEFAULTCONF=Debug
CONF=${DEFAULTCONF}
# All Configurations
ALLCONFS=Debug Release
# build
.build-impl: .build-pre .validate-impl .depcheck-impl
@#echo "=> Running $@... Configuration=$(CONF)"
"${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf
# clean
.clean-impl: .clean-pre .validate-impl .depcheck-impl
@#echo "=> Running $@... Configuration=$(CONF)"
"${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf
# clobber
.clobber-impl: .clobber-pre .depcheck-impl
@#echo "=> Running $@..."
for CONF in ${ALLCONFS}; \
do \
"${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \
done
# all
.all-impl: .all-pre .depcheck-impl
@#echo "=> Running $@..."
for CONF in ${ALLCONFS}; \
do \
"${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \
done
# build tests
.build-tests-impl: .build-impl .build-tests-pre
@#echo "=> Running $@... Configuration=$(CONF)"
"${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf
# run tests
.test-impl: .build-tests-impl .test-pre
@#echo "=> Running $@... Configuration=$(CONF)"
"${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf
# dependency checking support
.depcheck-impl:
@echo "# This code depends on make tool being used" >.dep.inc
@if [ -n "${MAKE_VERSION}" ]; then \
echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \
echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
echo "include \$${DEPFILES}" >>.dep.inc; \
echo "endif" >>.dep.inc; \
else \
echo ".KEEP_STATE:" >>.dep.inc; \
echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
fi
# configuration validation
.validate-impl:
@if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
then \
echo ""; \
echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \
echo "See 'make help' for details."; \
echo "Current directory: " `pwd`; \
echo ""; \
fi
@if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
then \
exit 1; \
fi
# help
.help-impl: .help-pre
@echo "This makefile supports the following configurations:"
@echo " ${ALLCONFS}"
@echo ""
@echo "and the following targets:"
@echo " build (default target)"
@echo " clean"
@echo " clobber"
@echo " all"
@echo " help"
@echo ""
@echo "Makefile Usage:"
@echo " make [CONF=<CONFIGURATION>] [SUB=no] build"
@echo " make [CONF=<CONFIGURATION>] [SUB=no] clean"
@echo " make [SUB=no] clobber"
@echo " make [SUB=no] all"
@echo " make help"
@echo ""
@echo "Target 'build' will build a specific configuration and, unless 'SUB=no',"
@echo " also build subprojects."
@echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no',"
@echo " also clean subprojects."
@echo "Target 'clobber' will remove all built files from all configurations and,"
@echo " unless 'SUB=no', also from subprojects."
@echo "Target 'all' will will build all configurations and, unless 'SUB=no',"
@echo " also build subprojects."
@echo "Target 'help' prints this message."
@echo ""

View File

@@ -0,0 +1,35 @@
#
# Generated - do not edit!
#
# NOCDDL
#
CND_BASEDIR=`pwd`
CND_BUILDDIR=build
CND_DISTDIR=dist
# Debug configuration
CND_PLATFORM_Debug=GNU-Linux-x86
CND_ARTIFACT_DIR_Debug=dist/Debug/GNU-Linux-x86
CND_ARTIFACT_NAME_Debug=klisp
CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux-x86/klisp
CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux-x86/package
CND_PACKAGE_NAME_Debug=klisp.tar
CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux-x86/package/klisp.tar
# Release configuration
CND_PLATFORM_Release=GNU-Linux-x86
CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux-x86
CND_ARTIFACT_NAME_Release=klisp
CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux-x86/klisp
CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux-x86/package
CND_PACKAGE_NAME_Release=klisp.tar
CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux-x86/package/klisp.tar
#
# include compiler specific variables
#
# dmake command
ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \
(mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)
#
# gmake command
.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk))
#
include nbproject/private/Makefile-variables.mk

View File

@@ -0,0 +1,76 @@
#!/bin/bash -x
#
# Generated - do not edit!
#
# Macros
TOP=`pwd`
CND_PLATFORM=GNU-Linux-x86
CND_CONF=Debug
CND_DISTDIR=dist
CND_BUILDDIR=build
CND_DLIB_EXT=so
NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
TMPDIRNAME=tmp-packaging
OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/klisp
OUTPUT_BASENAME=klisp
PACKAGE_TOP_DIR=klisp/
# Functions
function checkReturnCode
{
rc=$?
if [ $rc != 0 ]
then
exit $rc
fi
}
function makeDirectory
# $1 directory path
# $2 permission (optional)
{
mkdir -p "$1"
checkReturnCode
if [ "$2" != "" ]
then
chmod $2 "$1"
checkReturnCode
fi
}
function copyFileToTmpDir
# $1 from-file path
# $2 to-file path
# $3 permission
{
cp "$1" "$2"
checkReturnCode
if [ "$3" != "" ]
then
chmod $3 "$2"
checkReturnCode
fi
}
# Setup
cd "${TOP}"
mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
rm -rf ${NBTMPDIR}
mkdir -p ${NBTMPDIR}
# Copy files and create directories and links
cd "${TOP}"
makeDirectory "${NBTMPDIR}/klisp/bin"
copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755
# Generate tar file
cd "${TOP}"
rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/klisp.tar
cd ${NBTMPDIR}
tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/klisp.tar *
checkReturnCode
# Cleanup
cd "${TOP}"
rm -rf ${NBTMPDIR}

View File

@@ -0,0 +1,76 @@
#!/bin/bash -x
#
# Generated - do not edit!
#
# Macros
TOP=`pwd`
CND_PLATFORM=GNU-Linux-x86
CND_CONF=Release
CND_DISTDIR=dist
CND_BUILDDIR=build
CND_DLIB_EXT=so
NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
TMPDIRNAME=tmp-packaging
OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/klisp
OUTPUT_BASENAME=klisp
PACKAGE_TOP_DIR=klisp/
# Functions
function checkReturnCode
{
rc=$?
if [ $rc != 0 ]
then
exit $rc
fi
}
function makeDirectory
# $1 directory path
# $2 permission (optional)
{
mkdir -p "$1"
checkReturnCode
if [ "$2" != "" ]
then
chmod $2 "$1"
checkReturnCode
fi
}
function copyFileToTmpDir
# $1 from-file path
# $2 to-file path
# $3 permission
{
cp "$1" "$2"
checkReturnCode
if [ "$3" != "" ]
then
chmod $3 "$2"
checkReturnCode
fi
}
# Setup
cd "${TOP}"
mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
rm -rf ${NBTMPDIR}
mkdir -p ${NBTMPDIR}
# Copy files and create directories and links
cd "${TOP}"
makeDirectory "${NBTMPDIR}/klisp/bin"
copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755
# Generate tar file
cd "${TOP}"
rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/klisp.tar
cd ${NBTMPDIR}
tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/klisp.tar *
checkReturnCode
# Cleanup
cd "${TOP}"
rm -rf ${NBTMPDIR}

View File

@@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<configurationDescriptor version="94">
<logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
<logicalFolder name="HeaderFiles"
displayName="Header Files"
projectFiles="true">
<itemPath>functions.h</itemPath>
<itemPath>lang.h</itemPath>
<itemPath>lenv.h</itemPath>
<itemPath>lval.h</itemPath>
<itemPath>main.h</itemPath>
<itemPath>../mpc/mpc.h</itemPath>
<itemPath>util.h</itemPath>
</logicalFolder>
<logicalFolder name="ResourceFiles"
displayName="Resource Files"
projectFiles="true">
</logicalFolder>
<logicalFolder name="SourceFiles"
displayName="Source Files"
projectFiles="true">
<itemPath>functions.c</itemPath>
<itemPath>lang.c</itemPath>
<itemPath>lenv.c</itemPath>
<itemPath>lval.c</itemPath>
<itemPath>main.c</itemPath>
<itemPath>../mpc/mpc.c</itemPath>
<itemPath>util.c</itemPath>
</logicalFolder>
<logicalFolder name="TestFiles"
displayName="Test Files"
projectFiles="false"
kind="TEST_LOGICAL_FOLDER">
</logicalFolder>
<logicalFolder name="ExternalFiles"
displayName="Important Files"
projectFiles="false"
kind="IMPORTANT_FILES_FOLDER">
<itemPath>Makefile</itemPath>
</logicalFolder>
</logicalFolder>
<projectmakefile>Makefile</projectmakefile>
<confs>
<conf name="Debug" type="1">
<toolsSet>
<compilerSet>default</compilerSet>
<dependencyChecking>true</dependencyChecking>
<rebuildPropChanged>false</rebuildPropChanged>
</toolsSet>
<compileType>
<cTool>
<standard>3</standard>
<commandlineTool>gcc</commandlineTool>
<incDir>
<pElem>lib/mpc</pElem>
</incDir>
<commandLine>-O0</commandLine>
<warningLevel>2</warningLevel>
</cTool>
<asmTool>
<warningLevel>2</warningLevel>
</asmTool>
<linkerTool>
<linkerLibItems>
<linkerOptionItem>`pkg-config --libs libedit`</linkerOptionItem>
<linkerLibStdlibItem>Mathematics</linkerLibStdlibItem>
</linkerLibItems>
</linkerTool>
</compileType>
<item path="../mpc/mpc.c" ex="false" tool="0" flavor2="0">
</item>
<item path="../mpc/mpc.h" ex="false" tool="3" flavor2="0">
</item>
<item path="functions.c" ex="false" tool="0" flavor2="0">
</item>
<item path="functions.h" ex="false" tool="3" flavor2="0">
</item>
<item path="lang.c" ex="false" tool="0" flavor2="0">
</item>
<item path="lang.h" ex="false" tool="3" flavor2="0">
</item>
<item path="lenv.c" ex="false" tool="0" flavor2="0">
</item>
<item path="lenv.h" ex="false" tool="3" flavor2="0">
</item>
<item path="lval.c" ex="false" tool="0" flavor2="0">
</item>
<item path="lval.h" ex="false" tool="3" flavor2="0">
</item>
<item path="main.c" ex="false" tool="0" flavor2="0">
</item>
<item path="main.h" ex="false" tool="3" flavor2="0">
</item>
<item path="util.c" ex="false" tool="0" flavor2="0">
</item>
<item path="util.h" ex="false" tool="3" flavor2="0">
</item>
</conf>
<conf name="Release" type="1">
<toolsSet>
<compilerSet>default</compilerSet>
<dependencyChecking>true</dependencyChecking>
<rebuildPropChanged>false</rebuildPropChanged>
</toolsSet>
<compileType>
<cTool>
<developmentMode>5</developmentMode>
</cTool>
<ccTool>
<developmentMode>5</developmentMode>
</ccTool>
<fortranCompilerTool>
<developmentMode>5</developmentMode>
</fortranCompilerTool>
<asmTool>
<developmentMode>5</developmentMode>
</asmTool>
</compileType>
<item path="../mpc/mpc.c" ex="false" tool="0" flavor2="0">
</item>
<item path="../mpc/mpc.h" ex="false" tool="3" flavor2="0">
</item>
<item path="functions.c" ex="false" tool="0" flavor2="0">
</item>
<item path="functions.h" ex="false" tool="3" flavor2="0">
</item>
<item path="lang.c" ex="false" tool="0" flavor2="0">
</item>
<item path="lang.h" ex="false" tool="3" flavor2="0">
</item>
<item path="lenv.c" ex="false" tool="0" flavor2="0">
</item>
<item path="lenv.h" ex="false" tool="3" flavor2="0">
</item>
<item path="lval.c" ex="false" tool="0" flavor2="0">
</item>
<item path="lval.h" ex="false" tool="3" flavor2="0">
</item>
<item path="main.c" ex="false" tool="0" flavor2="0">
</item>
<item path="main.h" ex="false" tool="3" flavor2="0">
</item>
<item path="util.c" ex="false" tool="0" flavor2="0">
</item>
<item path="util.h" ex="false" tool="3" flavor2="0">
</item>
</conf>
</confs>
</configurationDescriptor>

View File

@@ -0,0 +1,7 @@
#
# Generated - do not edit!
#
# NOCDDL
#
# Debug configuration
# Release configuration

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<configurationDescriptor version="94">
<projectmakefile>Makefile</projectmakefile>
<confs>
<conf name="Debug" type="1">
<toolsSet>
<developmentServer>localhost</developmentServer>
<platform>2</platform>
</toolsSet>
<dbx_gdbdebugger version="1">
<gdb_pathmaps>
</gdb_pathmaps>
<gdb_interceptlist>
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
</gdb_interceptlist>
<gdb_options>
<DebugOptions>
</DebugOptions>
</gdb_options>
<gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
</dbx_gdbdebugger>
<nativedebugger version="1">
<engine>gdb</engine>
</nativedebugger>
<runprofile version="9">
<runcommandpicklist>
<runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
</runcommandpicklist>
<runcommand>"${OUTPUT_PATH}"</runcommand>
<rundir></rundir>
<buildfirst>true</buildfirst>
<terminal-type>0</terminal-type>
<remove-instrumentation>0</remove-instrumentation>
<environment>
</environment>
</runprofile>
</conf>
<conf name="Release" type="1">
<toolsSet>
<developmentServer>localhost</developmentServer>
<platform>2</platform>
</toolsSet>
<dbx_gdbdebugger version="1">
<gdb_pathmaps>
</gdb_pathmaps>
<gdb_interceptlist>
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
</gdb_interceptlist>
<gdb_options>
<DebugOptions>
</DebugOptions>
</gdb_options>
<gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
</dbx_gdbdebugger>
<nativedebugger version="1">
<engine>gdb</engine>
</nativedebugger>
<runprofile version="9">
<runcommandpicklist>
<runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
</runcommandpicklist>
<runcommand>"${OUTPUT_PATH}"</runcommand>
<rundir></rundir>
<buildfirst>true</buildfirst>
<terminal-type>0</terminal-type>
<remove-instrumentation>0</remove-instrumentation>
<environment>
</environment>
</runprofile>
</conf>
</confs>
</configurationDescriptor>

View File

@@ -0,0 +1,40 @@
# Launchers File syntax:
#
# [Must-have property line]
# launcher1.runCommand=<Run Command>
# [Optional extra properties]
# launcher1.displayName=<Display Name, runCommand by default>
# launcher1.buildCommand=<Build Command, Build Command specified in project properties by default>
# launcher1.runDir=<Run Directory, ${PROJECT_DIR} by default>
# launcher1.symbolFiles=<Symbol Files loaded by debugger, ${OUTPUT_PATH} by default>
# launcher1.env.<Environment variable KEY>=<Environment variable VALUE>
# (If this value is quoted with ` it is handled as a native command which execution result will become the value)
# [Common launcher properties]
# common.runDir=<Run Directory>
# (This value is overwritten by a launcher specific runDir value if the latter exists)
# common.env.<Environment variable KEY>=<Environment variable VALUE>
# (Environment variables from common launcher are merged with launcher specific variables)
# common.symbolFiles=<Symbol Files loaded by debugger>
# (This value is overwritten by a launcher specific symbolFiles value if the latter exists)
#
# In runDir, symbolFiles and env fields you can use these macroses:
# ${PROJECT_DIR} - project directory absolute path
# ${OUTPUT_PATH} - linker output path (relative to project directory path)
# ${OUTPUT_BASENAME}- linker output filename
# ${TESTDIR} - test files directory (relative to project directory path)
# ${OBJECTDIR} - object files directory (relative to project directory path)
# ${CND_DISTDIR} - distribution directory (relative to project directory path)
# ${CND_BUILDDIR} - build directory (relative to project directory path)
# ${CND_PLATFORM} - platform name
# ${CND_CONF} - configuration name
# ${CND_DLIB_EXT} - dynamic library extension
#
# All the project launchers must be listed in the file!
#
# launcher1.runCommand=...
# launcher2.runCommand=...
# ...
# common.runDir=...
# common.env.KEY=VALUE
# launcher1.runCommand=<type your run command here>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
<data xmlns="http://www.netbeans.org/ns/make-project-private/1">
<activeConfTypeElem>1</activeConfTypeElem>
<activeConfIndexElem>0</activeConfIndexElem>
</data>
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
<group>
<file>file:/home/sam/NetBeansProjects/CppApplication_1/lval.c</file>
<file>file:/home/sam/NetBeansProjects/CppApplication_1/main.c</file>
<file>file:/home/sam/NetBeansProjects/CppApplication_1/lval.h</file>
<file>file:/home/sam/NetBeansProjects/CppApplication_1/lang.c</file>
<file>file:/home/sam/NetBeansProjects/CppApplication_1/functions.c</file>
<file>file:/home/sam/NetBeansProjects/CppApplication_1/main.h</file>
<file>file:/home/sam/NetBeansProjects/CppApplication_1/functions.h</file>
<file>file:/home/sam/NetBeansProjects/CppApplication_1/lang.h</file>
<file>file:/home/sam/NetBeansProjects/CppApplication_1/lenv.c</file>
</group>
</open-files>
</project-private>

28
nbproject/project.xml Normal file
View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.cnd.makeproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/make-project/1">
<name>KLisp</name>
<c-extensions>c</c-extensions>
<cpp-extensions/>
<header-extensions>h</header-extensions>
<sourceEncoding>UTF-8</sourceEncoding>
<make-dep-projects/>
<sourceRootList/>
<confList>
<confElem>
<name>Debug</name>
<type>1</type>
</confElem>
<confElem>
<name>Release</name>
<type>1</type>
</confElem>
</confList>
<formatting>
<project-formatting-style>false</project-formatting-style>
</formatting>
</data>
</configuration>
</project>

11
util.c Normal file
View File

@@ -0,0 +1,11 @@
#include <string.h>
#include <stdlib.h>
#include "util.h"
char * strdup(char* s) {
char *d = calloc(1, strlen (s) + 1);
if (d == NULL) return NULL;
strcpy (d,s);
return d;
}

22
util.h Normal file
View File

@@ -0,0 +1,22 @@
/*
* File: util.h
* Author: sam
*
* Created on 18 May 2014, 21:29
*/
#ifndef UTIL_H
#define UTIL_H
#ifdef __cplusplus
extern "C" {
#endif
char * strdup(char* s);
#ifdef __cplusplus
}
#endif
#endif /* UTIL_H */