changeset 45:9cec88f4c98b

Merged changes in
author Jonathan Pevarnek <pevarnj@gmail.com>
date Fri, 08 Apr 2011 09:56:20 -0400
parents 03c6618b2c24 (diff) 3d69c66b2610 (current diff)
children a6be89bc4b04
files .hgignore Makefile arch/io.c include/system.h src/dynamic.c src/fs.c src/init.c src/sarpn.c
diffstat 20 files changed, 932 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Fri Apr 08 09:44:57 2011 -0400
+++ b/.hgignore	Fri Apr 08 09:56:20 2011 -0400
@@ -3,6 +3,8 @@
 \.rto$
 ^ipl/ipl_ccws\.S$
 ^sarpn$
+^dynamic$
+^fs$
 ^loader\.bin$
 ^cscope\.out$
 \.swp$
--- a/Makefile	Fri Apr 08 09:44:57 2011 -0400
+++ b/Makefile	Fri Apr 08 09:56:20 2011 -0400
@@ -11,9 +11,11 @@
 CXXFLAGS=$(CFLAGS)
 LDFLAGS=-m elf64_s390
 
-BINS=sarpn
+BINS=sarpn dynamic fs
 
-sarpn_OBJS=src/init.o arch/arch.a
+sarpn_OBJS=src/sarpn.o arch/arch.a src/std.o src/stack.o src/operations.o src/math.o
+dynamic_OBJS=src/dynamic.o arch/arch.a src/std.o src/stack.o
+fs_OBJS=src/fs.o arch/arch.a src/std.o
 
 ARCH_OBJS=arch/io.o arch/cons.o arch/ebcdic.o arch/fba.o arch/ioint.o
 
@@ -25,15 +27,22 @@
 
 clean:
 	rm -f $(sarpn_OBJS)
+	rm -f $(dynamic_OBJS)
+	rm -f $(fs_OBJS)
 	rm -f $(ARCH_OBJS)
 	rm -f $(BINS)
 	rm -f loader.bin ipl/*.o ipl/*.rto ipl/ipl_ccws.S cscope.out
 
 tags:
 	cscope -R -b
+	ctags -R
 
 sarpn: $(sarpn_OBJS)
 	$(LD) $(LDFLAGS) -T scripts/linker.script -o $@ $^
+dynamic: $(dynamic_OBJS)
+	$(LD) $(LDFLAGS) -T scripts/linker.script -o $@ $^
+fs: $(fs_OBJS)
+	$(LD) $(LDFLAGS) -T scripts/linker.script -o $@ $^
 
 arch/arch.a: $(ARCH_OBJS)
 	$(AR) rc $@ $^
@@ -78,3 +87,17 @@
 
 ipl/%.o: ipl/%.S
 	$(AS) -m64 -o $@ $<
+
+depend:
+	makedepend -I include src/*.c
+
+# DO NOT DELETE
+
+src/date.o: include/tod.h include/std.h
+src/dynamic.o: include/std.h include/operations.h include/stack.h
+src/fs.o: include/std.h
+src/operations.o: include/operations.h include/std.h include/stack.h
+src/operations.o: include/math.h
+src/sarpn.o: include/std.h include/operations.h include/stack.h
+src/stack.o: include/stack.h include/std.h
+src/std.o: include/std.h
--- a/arch/io.c	Fri Apr 08 09:44:57 2011 -0400
+++ b/arch/io.c	Fri Apr 08 09:56:20 2011 -0400
@@ -1,3 +1,4 @@
+
 #include "channel.h"
 #include <die.h>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hercules/dynamic.cnf	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,20 @@
+CPUSERIAL 314359        # CPU serial number
+CPUMODEL  2097          # CPU model number
+MAINSIZE  128           # Main storage size in megabytes
+XPNDSIZE  0             # Expanded storage size in megabytes
+CNSLPORT  3270          # TCP port number to which consoles connect
+NUMCPU    1             # Number of CPUs
+#OSTAILOR  QUIET         # OS tailoring
+OSTAILOR  NULL          # OS tailoring
+PANRATE   SLOW          # Panel refresh rate
+
+# .-----------------------Device number
+# |     .-----------------Device type
+# |     |       .---------File name and parameters
+# |     |       |
+# V     V       V
+#---    ----    --------------------
+0009	3215	
+000C    3505	../loader.bin ../dynamic ebcdic multifile eof
+
+0100	9336	disk.img
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hercules/fs.cnf	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,20 @@
+CPUSERIAL 314359        # CPU serial number
+CPUMODEL  2097          # CPU model number
+MAINSIZE  128           # Main storage size in megabytes
+XPNDSIZE  0             # Expanded storage size in megabytes
+CNSLPORT  3270          # TCP port number to which consoles connect
+NUMCPU    1             # Number of CPUs
+#OSTAILOR  QUIET         # OS tailoring
+OSTAILOR  NULL          # OS tailoring
+PANRATE   SLOW          # Panel refresh rate
+
+# .-----------------------Device number
+# |     .-----------------Device type
+# |     |       .---------File name and parameters
+# |     |       |
+# V     V       V
+#---    ----    --------------------
+0009	3215	
+000C    3505	../loader.bin ../fs ebcdic multifile eof
+
+0100	9336	disk.img
--- a/hercules/herc.cnf	Fri Apr 08 09:44:57 2011 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-CPUSERIAL 314359        # CPU serial number
-CPUMODEL  2097          # CPU model number
-MAINSIZE  128           # Main storage size in megabytes
-XPNDSIZE  0             # Expanded storage size in megabytes
-CNSLPORT  3270          # TCP port number to which consoles connect
-NUMCPU    1             # Number of CPUs
-#OSTAILOR  QUIET         # OS tailoring
-OSTAILOR  NULL          # OS tailoring
-PANRATE   SLOW          # Panel refresh rate
-
-# .-----------------------Device number
-# |     .-----------------Device type
-# |     |       .---------File name and parameters
-# |     |       |
-# V     V       V
-#---    ----    --------------------
-0009	3215	
-000C    3505	../loader.bin ../sarpn ebcdic multifile eof
-
-0100	9336	disk.img
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hercules/sarpn.cnf	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,20 @@
+CPUSERIAL 314359        # CPU serial number
+CPUMODEL  2097          # CPU model number
+MAINSIZE  128           # Main storage size in megabytes
+XPNDSIZE  0             # Expanded storage size in megabytes
+CNSLPORT  3270          # TCP port number to which consoles connect
+NUMCPU    1             # Number of CPUs
+#OSTAILOR  QUIET         # OS tailoring
+OSTAILOR  NULL          # OS tailoring
+PANRATE   SLOW          # Panel refresh rate
+
+# .-----------------------Device number
+# |     .-----------------Device type
+# |     |       .---------File name and parameters
+# |     |       |
+# V     V       V
+#---    ----    --------------------
+0009	3215	
+000C    3505	../loader.bin ../sarpn ebcdic multifile eof
+
+0100	9336	disk.img
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/math.h	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,14 @@
+#ifndef __MATH_H
+#define __MATH_H
+
+double iPow(double base, int exponent);
+double exp(double exp);
+double log(double num);
+double pow(double base, double exponent);
+
+double math_add(double first, double sec);
+double math_sub(double first, double sec);
+double math_mult(double first, double sec);
+double math_div(double first, double sec);
+
+#endif //__MATH_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/operations.h	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,26 @@
+#ifndef __OPERATIONS_H
+#define __OPERATIONS_H
+
+#include <std.h>
+#include <stack.h>
+
+enum Operation {PRINT, ADD, SUB, MULT, DIV, POW, DUP, DROP, LOG, EXP, SWAP, MAXOP};
+extern const char operationNames[MAXOP][10];
+extern void (*operation[MAXOP])(Stack*);
+
+void op_math1(Stack *stack, eltType (*mathop)(eltType));
+void op_math2(Stack *stack, eltType (*mathop)(eltType, eltType));
+
+void op_print(Stack *stack);
+void op_add(Stack *stack);
+void op_sub(Stack *stack);
+void op_mult(Stack *stack);
+void op_div(Stack *stack);
+void op_pow(Stack *stack);
+void op_dup(Stack *stack);
+void op_drop(Stack *stack);
+void op_log(Stack *stack);
+void op_exp(Stack *stack);
+void op_swap(Stack *stack);
+
+#endif //__OPERATIONS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/stack.h	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,25 @@
+#ifndef __STACK_H
+#define __STACK_H
+
+typedef double eltType;
+
+struct STACKELT {
+	eltType elt;
+	struct STACKELT *next;
+};
+typedef struct STACKELT StackElt;
+
+struct STACK {
+	StackElt* top;
+	unsigned int size;
+};
+typedef struct STACK Stack;
+
+short pop(Stack *stack, eltType *value);
+//pop returns 0 on success and -1 on failure.  If the function call is
+//successful, *value will be the value removed from the stack
+void push(Stack *stack, eltType val);
+Stack* stack_init();
+void stack_destroy(Stack *stack);
+
+#endif //__STACK_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/std.h	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,37 @@
+#ifndef __STD_H
+#define __STD_H
+
+double abs(double num);
+
+char* ftoa(double x, char *a, unsigned int prec);
+char* itoa(long long n, char *a, unsigned short base);
+s64 atoi(char *a);
+double atof(char *a);
+
+void sPrint(char *a);
+char* sGet(char *a, unsigned int n);
+
+void strcpy(char *dest, const char *src);
+int strcmp(const char *a, const char *b);
+
+int arrayLookup(char *text, const char array[][10], int last);
+
+char* append(char *dest, char *src);
+
+//MALLOC CODE
+
+struct header{
+	struct header *next;
+	size_t size;
+};
+typedef struct header Header;
+
+typedef Header blockUnit;
+
+void malloc_init(size_t memSize);
+void* malloc(size_t size);
+void free(void *ptr);
+void printHeader(Header* head);
+void printMem();
+
+#endif
--- a/include/system.h	Fri Apr 08 09:44:57 2011 -0400
+++ b/include/system.h	Fri Apr 08 09:56:20 2011 -0400
@@ -5,6 +5,14 @@
 #define CON_DEV 0x0009
 
 #define NULL	((void*) 0)
+#define CON_LEN 132
+#define HEAP_START 0x200000
+
+#define INF __builtin_inff()
+#define NAN __builtin_nanf("")
+
+typedef unsigned long long size_t;
+typedef unsigned long long intptr_t;
 
 typedef unsigned long long u64;
 typedef signed long long s64;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dynamic.c	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,76 @@
+/*
+ * This is where everything starts
+ */
+
+#include <std.h>
+#include <operations.h>
+#include <stack.h>
+
+void dumpBuffer(char *a, int b)
+{
+	int i;
+	for(i = 0; i < b; i++) {
+		int foo = (int) a[i];
+		char c[10];
+		itoa(foo, c, 16);
+		sPrint(c);
+		sPrint(" ");
+		if(!((i + 1)%20)) sPrint("\n");
+	}
+}
+
+void start(u64 __memsize)
+{
+	init_io_int();
+	init_console();
+	malloc_init(__memsize - HEAP_START);
+	size_t n;
+	char *buffer;
+	char input[30];
+
+	while(0) {
+		sPrint("How long do you want the string? ");
+		n = atoi(sGet(input, 30));
+		buffer = (char*) malloc(n);
+		if (!buffer) { //allocation failed, too large
+			sPrint("ERROR\n");
+			break;
+		}
+//		size_t i;
+//		for (i = 0; i < n - 1; i++)
+//			buffer[i]='a'; //I need to make rand...
+//		buffer[n - 1]='\0';
+//		sPrint(buffer), sPrint("\n");
+//		dumpBuffer(buffer, n);
+		sPrint(append(itoa((unsigned long)buffer, input, 16), "\n"));
+		free(buffer);
+	}
+
+	printMem();
+
+	Stack *stack = stack_init();
+
+	for(n = 0; n < 1000; n++) {
+		push(stack, n);
+	}
+	stack_destroy(stack);
+
+
+	printMem();
+	void *a = malloc(1223);
+	void *b = malloc(352);
+	void *c = malloc(3539);
+	void *d = malloc(325);
+	printMem();
+	free(b);
+	printMem();
+	b = malloc(400);
+	printMem();
+	sPrint("DONE\n");
+	free(a);
+	free(c);
+	free(d);
+
+	for(;;)
+		sGet(input, 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/fs.c	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,150 @@
+#include <std.h>
+
+struct SUPERBLOCK {
+	u32 magic;              // == 0x42420374
+	u32 root_inode;         // the disk block containing the root inode
+	u32 nblocks;            // number of block on the disk
+	u32 _pad[253];          // unused (should be '\0' filled)
+};
+typedef struct SUPERBLOCK Superblock;
+
+struct INODE {
+	u32 size;               // file length in bytes
+	u32 _pad0;              // unused (should be 0)
+	u64 ctime;              // creation time stamp
+	u64 mtime;              // last modification time stamp
+	u16 nblocks;            // number of data blocks in this file
+	u16 _pad1;              // unused (should be 0)
+	u32 _pad2;              // unused (should be 0)
+	u32 blocks[248];        // file block ptrs
+};
+typedef struct INODE Inode;
+
+struct DIRENTRY { //32 bytes
+	char fname[28];
+	u32 inode;
+};
+typedef struct DIRENTRY Direntry;
+
+//REQUIRES:   fsBlock points to an object with size at least 1024
+//EFFECTS:    Sets fsBlock to be equal
+int readFSBlock(u32 dev, u32 blkno, void *fsBlock)
+{
+	if(fba_read_blk(dev, blkno*2, fsBlock)) return 1;
+	if(fba_read_blk(dev, blkno*2 + 1, fsBlock + 512)) return 1;
+	return 0;
+}
+
+void printFname(char *name)
+{
+	putline(name, 28);
+}
+
+//Sets name to contain a filename entered by the user
+//REQUIRES:   name is 28 characters long
+void getFname(char *fname)
+{
+	int chars = getline(fname, 28);
+	for(;chars < 28; chars++) {
+		fname[chars] = ' ';
+	}
+}
+
+//Checks whether two file names are equal
+int fnameCmp(const char *a, const char *b)
+{
+	int i;
+	for(i = 0; i < 28; i++, a++, b++) {
+		if(*a - *b) return *a - *b;
+	}
+	return 0;
+}
+
+//Finds the item within an array of filenames with the same name as fname
+int fnameLookup(char *fname, const Direntry array[], int last)
+{
+	int i;
+	for(i = 0; i < last; i++)
+		if(!fnameCmp(fname, array[i].fname)) return i;
+	return last;
+}
+
+void dumpText(char *text, int size)
+{
+	do {
+		putline(text, (size > CON_LEN)?CON_LEN:size);
+		size -= CON_LEN;
+		text += CON_LEN;
+	} while(size > 0);
+}
+
+void start(u64 __memsize)
+{
+	init_io_int();
+	init_console();
+	char buffer[256];
+	int i;
+	
+	u32 dev = find_dev(0x100);
+	Superblock sb;
+	if(readFSBlock(dev, 1, &sb)) { //get the super block
+		sPrint("ERROR\n");
+		goto END;
+	}
+	Inode root;
+	if(readFSBlock(dev, sb.root_inode, &root)) { //get the root inode
+		sPrint("ERROR\n");
+		goto END;
+	}
+	int nFiles = root.size/sizeof(Direntry);
+		//calculate how many files (assume less than 32 for the moment)
+		//TODO get rid of assumption
+	Direntry direntries[32];
+	if(readFSBlock(dev, root.blocks[0], direntries)) { //get the "first 32" files
+		sPrint("ERROR\n");
+		goto END;
+	}
+
+	while(1) {
+		
+		//Prints off the name of each file
+		Direntry *dp;
+		for(dp = direntries; dp - direntries < nFiles; dp++) {
+			printFname(dp->fname), sPrint("\n");
+		}
+		char fname[28];
+		sPrint("Please enter the file to read: ");
+		getFname(fname);
+		int file = fnameLookup(fname, direntries, nFiles);
+
+		u32 fileLoc = direntries[file].inode;
+		if(fileLoc == nFiles) continue;
+
+		Inode fileToRead;
+		if(readFSBlock(dev, fileLoc, &fileToRead)) {
+			sPrint("ERROR\n");
+			goto END;
+		}
+
+		u32 fileSize = fileToRead.size;
+
+		for(i = 0; i < fileToRead.nblocks; i++) {
+			char text[1024];
+			if(readFSBlock(dev, fileToRead.blocks[i], text)) {
+				sPrint("ERROR\n");
+				goto END;
+			}
+			dumpText(text, (fileSize > 1024)?1024:fileSize);
+			fileSize -= 1024;
+		}
+	}
+
+
+END:
+	sPrint("DONE\n");
+	for(;;) {
+		char buffer[1];
+		sGet(buffer, 0);
+	}
+}
+
--- a/src/init.c	Fri Apr 08 09:44:57 2011 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-/*
- * This is where everything starts
- */
-void start(u64 __memsize)
-{
-	init_io_int();
-	init_console();
-
-	putline("Hello\n", 6);
-
-	for(;;)
-		;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/math.c	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,84 @@
+double iPow(double base, int exponent)
+{
+	double ans = 1;
+	short isNeg = 0;
+	if(exponent < 0) {
+		isNeg = 1;
+		exponent *= -1;
+	}
+	while(exponent > 0) {
+		if(exponent%2) {
+			exponent -= 1;
+			ans *= base;
+		} else {
+			exponent /= 2;
+			base *= base;
+		}
+	}
+	return isNeg ? 1/ans : ans;
+}
+
+double exp(double exp)
+{
+	unsigned int i; //a counter for the loop
+	double ans = 1;
+	double prev = -1;
+	double term = 1;
+	short isNeg = 0;
+	if(exp < 0) {
+		isNeg = 1;
+		exp *= -1;
+	}
+	for(i = 1; ans - prev; i++) {
+		prev = ans;
+		term *= exp/i;
+		ans += term;
+	}
+	return isNeg ? 1/ans : ans;
+}
+
+double log(double num)
+{
+	unsigned int denom = 1;
+	double euler = 2.71828182845904;
+	double ans = 0;
+	double prev = -1;
+	double term = -1;
+	while(num <= -1 || num >= 1) {
+		num /= euler;
+		ans += 1;
+	}
+	for(; ans - prev; denom++) {
+		prev = ans;
+		term *= (-1*(num - 1));
+		ans += term/denom;
+	}
+	return ans;
+}
+
+double pow(double base, double exponent)
+{
+	if(exponent == (int) exponent)
+		return iPow(base, (int) exponent);
+	return exp(exponent*log(base));
+}
+
+double math_add(double first, double sec)
+{
+	return first + sec;
+}
+
+double math_sub(double first, double sec)
+{
+	return first - sec;
+}
+
+double math_mult(double first, double sec)
+{
+	return first*sec;
+}
+
+double math_div(double first, double sec)
+{
+	return first/sec;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/operations.c	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,113 @@
+#include <operations.h>
+#include <std.h>
+#include <stack.h>
+#include <math.h>
+
+const char operationNames[MAXOP][10] = {".", "+", "-", "*", "/", "**", "dup", "drop", "log", "exp", "swap"};
+void (*operation[MAXOP])(Stack*) = {op_print, op_add, op_sub, op_mult,
+	op_div, op_pow, op_dup, op_drop, op_log, op_exp, op_swap};
+
+static void error_unk()
+{
+	sPrint("ERROR: CAUSE UNKNOWN\n");
+}
+
+static void error_small()
+{
+	sPrint("ERROR: STACK TOO SMALL\n");
+}
+
+void op_math1(Stack *stack, eltType (*mathop)(eltType))
+{
+	if(stack->size >= 1) {
+		eltType val;
+		if(pop(stack, &val)) error_unk();
+		else push(stack, mathop(val));
+	} else error_small();
+}
+
+void op_math2(Stack *stack, eltType (*mathop)(eltType, eltType))
+{
+	if(stack->size >= 2) {
+		eltType val1, val2;
+		if(pop(stack, &val2) || pop(stack, &val1)) error_unk();
+		else push(stack, mathop(val1, val2));
+	} else error_small();
+}
+
+void op_print(Stack *stack)
+{
+	if(stack->size >= 1) {
+		char output[30];
+		eltType val;
+		if(pop(stack, &val)) error_unk();
+		else sPrint(append(ftoa(val, output, 10), "\n"));
+	} else error_small();
+}
+
+void op_add(Stack *stack)
+{
+	op_math2(stack, math_add);
+}
+
+void op_sub(Stack *stack)
+{
+	op_math2(stack, math_sub);
+}
+
+void op_mult(Stack *stack)
+{
+	op_math2(stack, math_mult);
+}
+
+void op_div(Stack *stack)
+{
+	op_math2(stack, math_div);
+}
+
+void op_pow(Stack *stack)
+{
+	op_math2(stack, pow);
+}
+
+void op_dup(Stack *stack)
+{
+	if(stack->size >= 1) {
+		eltType val;
+		if(pop(stack, &val)) error_unk();
+		else {
+			push(stack, val);
+			push(stack, val);
+		}
+	} else error_small();
+}
+
+void op_drop(Stack *stack)
+{
+	if(stack->size >= 1) {
+		eltType val;
+		pop(stack, &val);
+	} else error_small();
+}
+
+void op_log(Stack *stack)
+{
+	op_math1(stack, log);
+}
+
+void op_exp(Stack *stack)
+{
+	op_math1(stack, exp);
+}
+
+void op_swap(Stack *stack)
+{
+	if(stack->size >= 2) {
+		eltType val1, val2;
+		if(pop(stack, &val2) || pop(stack, &val1)) error_unk();
+		else {
+			push(stack, val2);
+			push(stack, val1);
+		}
+	} else error_small();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sarpn.c	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,31 @@
+/*
+ * This is where everything starts
+ */
+
+#include <std.h>
+#include <operations.h>
+#include <stack.h>
+
+void start(u64 __memsize)
+{
+	init_io_int();
+	init_console();
+	malloc_init(__memsize - HEAP_START);
+
+	Stack *stack = stack_init();
+	while(1) {
+		int opVal;
+		char input[30];
+		sPrint("Please enter an operation or value: ");
+		opVal = arrayLookup(sGet(input, 30), operationNames, MAXOP);
+		if(opVal != MAXOP) {
+			(*operation[opVal]) (stack); //call the function array
+		} else {
+			push(stack, atof(input));
+		}
+	}
+	stack_destroy(stack);
+
+	for(;;)
+		;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stack.c	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,40 @@
+#include <stack.h>
+#include <std.h>
+
+short pop(Stack *stack, eltType *value)
+{
+	if(stack->top == NULL) {
+		return -1; //failure
+	} else {
+		StackElt *tip = stack->top;
+		*value = tip->elt;
+		stack->top = tip->next;
+		free(tip);
+		stack->size--;
+		return 0; //success
+	}
+}
+
+void push(Stack *stack, eltType val)
+{
+	StackElt *new = malloc(sizeof(StackElt));
+	new->elt = val;
+	new->next = stack->top;
+	stack->top = new;
+	stack->size++;
+}
+
+Stack* stack_init()
+{
+	Stack *new = malloc(sizeof(Stack));
+	new->top = NULL;
+	return new;
+}
+
+void stack_destroy(Stack *stack)
+{
+	eltType *val = malloc(sizeof(eltType));
+	while(stack->top) pop(stack, val);
+	free(stack);
+	free(val);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/std.c	Fri Apr 08 09:56:20 2011 -0400
@@ -0,0 +1,240 @@
+#include <std.h>
+
+double abs(double num)
+{
+	if(num < 0) return num*-1;
+	else return num;
+}
+
+char* itoa(s64 n, char *a, unsigned short base)
+{
+	char *ret = a;
+	if(n < 0) {
+		*a++ = '-';
+		n *= -1;
+	}
+	char *b = a;
+	if(!n) *b++ = '0';
+	for(; n; b++) {
+		int temp = n%base;
+		if(temp < 10) *b = '0' + temp;
+		else *b = 'a' + temp - 10;
+		n = n/base;
+	}
+	*b-- = '\0';
+	for(; a < b; a++, b--) { //reverse
+		char temp = *b;
+		*b = *a;
+		*a = temp;
+	}
+	return ret;
+}
+
+char* ftoa(double x, char *a, unsigned int prec)
+{
+	char *ret = a;
+	if(x == INF || x == -INF) {
+		strcpy(a, "INF");
+	} else if(x != x) { //NAN != NAN
+		strcpy(a, "NAN");
+	} else {
+		s64 n = (s64) x; //integer part
+		double d = abs(x - (double) n); //fractional part;
+		itoa(n, a, 10);
+		if(prec) { //only do the decimal part if decimal parts were asked for
+			while(*a && *++a); //get to the null character from itoa
+			int i; //counter variable for the for loop
+			*a++ = '.'; //put the decimal in place
+			for(i = 0; i < prec; i++) {
+				d *= 10; //the integer part is the decimal digit
+				*a++ = ((int) d) + '0'; //add the integer part of d to the string
+				d -= (int) d; //chop off the integer part
+			} a--; //move back to the last digit
+			while(*a != '.') {
+				if(*a == '0') {
+					a--;
+					continue;
+				} else if(*a > '0' && *a <= '9') {
+					a++;
+					break;
+				} else {
+					sPrint("ERROR: SOMETHING IS VERY WRONG\n");
+					break;
+				}
+			}
+			*a = '\0';
+		}
+	}
+	return ret;
+}
+
+s64 atoi(char *a)
+{
+	short neg = 0;
+	s64 n = 0;
+	if(*a == '-') {
+		neg = 1;
+		a++;
+	} else if(*a == '+') a++;
+	while(*a >= '0' && *a <= '9')
+		n = n*10 + (*a++ - '0');
+	if(neg) n *= -1;
+	return n;
+}
+
+double atof(char *a)
+{
+	s64 n = atoi(a);
+	double x = 0;
+	double dec = .1;
+	short neg = 0;
+	if(*a == '-') {
+		neg = 1;
+		a++;
+	}
+	while(*a != '.') {
+		if(!(*a >= '0' && *a <= '9') && *a != '-') return n;
+		a++;
+	} a++; //a will be immediately after the decimal point
+	while(*a >= '0' && *a <= '9') { //goes through the decimal part
+		x += (*a - '0')*dec;
+		dec *= .1;
+		a++;
+	}
+	if(neg) x*=-1;
+	return n + x;
+}
+
+void sPrint(char *a)
+{
+	char *b = a;
+	while(*b && *++b);
+	do {
+		putline(a, (b - a > CON_LEN)?CON_LEN:(b - a));
+		a += CON_LEN;
+	} while(a < b);
+}
+
+void strcpy(char *dest, const char *src)
+{
+	while((*dest++ = *src++));
+}
+
+int strcmp(const char *a, const char *b)
+{
+	while(1) {
+		if(*a - *b) return *a - *b;
+		if(*a == '\0') return 0;
+		a++;
+		b++;
+	}
+	return -1;
+}
+
+char* sGet(char *a, unsigned int n)
+{
+	int length = getline(a, n);
+	a[(length < n)?length:n - 1] = '\0';
+	return a;
+}
+
+int arrayLookup(char *text, const char array[][10], int last)
+{
+	int i;
+	for(i = 0; i < last; i++)
+		if(!strcmp(array[i], text)) return i;
+	return last;
+}
+
+char* append(char *dest, char *src)
+{
+	char *ret = dest;
+	while(*dest&& *++dest); //get to null in first string
+	while((*dest++ = *src++));
+	return ret;
+}
+
+static Header base;
+static Header *allocp = NULL; //the location of the last known free block
+
+void malloc_init(size_t memSize)
+{
+	allocp = &base;
+	allocp->size = 0;
+	allocp->next = (void*)HEAP_START;
+	allocp->next->next = &base;
+	allocp->next->size = memSize/sizeof(blockUnit);
+	if((sizeof(blockUnit)%sizeof(u64))) {
+		sPrint("WARNING: MEMORY NOT 8-BYTE ALIGNED\n");
+		char foo[40];
+		sPrint(append("MEMORY BLOCK SIZE IS: ", append(itoa(sizeof(Header), foo, 10), "\n")));
+	}
+}
+
+void* malloc(size_t size)
+{
+	if(allocp == NULL) return NULL;
+	size_t nUnits = ((size + sizeof(Header)) + sizeof(blockUnit) - 1)/sizeof(blockUnit);
+	Header *prev = allocp;
+	Header *cur, *temp;
+	for(cur = prev->next;; prev = cur, cur = cur->next) {
+		if(cur->size >= nUnits) {
+			if(cur->size == nUnits) {
+				prev->next = cur->next;
+			} else {
+				temp = cur + nUnits; //This requires sizeof(blockUnit) == sizeof(Header).  TODO fix
+				temp->size = cur->size - nUnits;
+				temp->next = cur->next;
+				prev->next = temp;
+				cur->size = nUnits;
+			}
+			allocp = prev;
+			return (void*)(cur + 1);
+		} else if(cur == allocp) { //We went back to the start...
+			return NULL;
+		}
+	}
+}
+
+void free(void *ptr)
+{
+	Header *toFree = (Header *)ptr - 1;
+	Header *scan;
+	for(scan = allocp; !(toFree > scan && toFree < scan->next); scan = scan->next)
+		if(scan->next < scan && (toFree > scan || toFree < scan->next)) break;
+	toFree->next = scan->next;
+	scan->next = toFree;
+	if(scan + scan->size == toFree) {
+		scan->size += toFree->size;
+		scan->next = toFree->next;
+		toFree = scan;
+	}
+	if(toFree + toFree->size == toFree->next) {
+		toFree->size += toFree->next->size;
+		toFree->next = toFree->next->next;
+	}
+}
+
+void printHeader(Header* head)
+{
+	char buffer[20];
+	sPrint("Memory address is: ");
+	sPrint(itoa((intptr_t)head, buffer, 16));
+	sPrint("\n");
+	sPrint("The size of the block is: ");
+	sPrint(itoa(head->size, buffer, 10));
+	sPrint("\n");
+	sPrint("Next memory address is: ");
+	sPrint(itoa((intptr_t)head->next, buffer, 16));
+	sPrint("\n\n");
+}
+
+void printMem()
+{
+	Header *cur = allocp;
+	do {
+		printHeader(cur);
+		cur = cur->next;
+	} while(cur != allocp);
+	sPrint("PRINTOUT DONE\n\n");
+}