git @ Cat's Eye Technologies stringie / 6c91cb0
Import of stringie, previously of the Dipple, now with Makefile. Chris Pressey 4 years ago
3 changed file(s) with 209 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 bin/
1 *.o
0 # GNU Makefile for stringie.
1
2 PROG=../bin/stringie
3 CC?=gcc
4 STRIP?=strip
5 O?=.o
6 EXE?=
7
8 WARNS?=
9
10 ifeq ($(CC),pcc)
11 CFLAGS+=-I/usr/include/linux -I/usr/lib/gcc/x86_64-linux-gnu/4.6/include/
12 else
13 ifdef ANSI
14 CFLAGS+= -ansi -pedantic
15 else
16 CFLAGS+= -std=c99 -D_POSIX_C_SOURCE=200112L
17 endif
18 endif
19
20 CFLAGS+= ${WARNS} ${EXTRA_CFLAGS}
21
22 ifdef DEBUG
23 CFLAGS+= -g
24 endif
25
26 OBJS= stringie${O}
27
28 all: ${PROG}${EXE}
29
30 ${PROG}${EXE}: $(OBJS)
31 mkdir -p ../bin/
32 $(CC) $(OBJS) -o ${PROG} $(LIBS)
33
34 stringie${O}: stringie.c
35 $(CC) $(CFLAGS) -c stringie.c -o stringie${O}
36
37 clean:
38 rm -f *.o *.core *.exe ${PROG}${EXE}
0 /*
1 * stringie.c -- a brain-freezingly pedantic implementation of Underload in C
2 * (with all the limitations that that implies)
3 * Chris Pressey, September 2010
4 * This work is in the public domain.
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 struct stack {
12 char *string;
13 struct stack *next;
14 } *root;
15
16 void run(char *);
17
18 char *pop(void)
19 {
20 char *r;
21 struct stack *old;
22 r = root->string;
23 old = root;
24 root = root->next;
25 free(old);
26 return r;
27 }
28
29 void push(char *string)
30 {
31 struct stack *s;
32 s = malloc(sizeof(struct stack));
33 s->next = root;
34 s->string = string;
35 root = s;
36 }
37
38 void dup(void)
39 {
40 char *e, *f;
41 e = pop();
42 f = strdup(e);
43 push(e);
44 push(f);
45 }
46
47 void swap(void)
48 {
49 char *e, *f;
50 e = pop();
51 f = pop();
52 push(e);
53 push(f);
54 }
55
56 void eval(void)
57 {
58 char *e;
59 e = pop();
60 run(e);
61 }
62
63 void concat(void)
64 {
65 char *e, *f, *g;
66 e = pop();
67 f = pop();
68 g = malloc(strlen(e) + strlen(f) + 1);
69 strcpy(g, f);
70 strcat(g, e);
71 push(g);
72 free(f);
73 free(e);
74 }
75
76 void enclose(void)
77 {
78 char *e, *g;
79 e = pop();
80 g = malloc(strlen(e) + 3);
81 sprintf(g, "(%s)", e);
82 push(g);
83 free(e);
84 }
85
86 void output(void)
87 {
88 char *e;
89 e = pop();
90 printf("%s", e);
91 free(e);
92 }
93
94 void dumpstack(void)
95 {
96 struct stack *s;
97
98 fprintf(stderr, "STACK: ");
99 for (s = root; s != NULL; s = s->next)
100 {
101 fprintf(stderr, "(%s)", s->string);
102 }
103 fprintf(stderr, "!\n");
104 }
105
106 void run(char *program)
107 {
108 int i = 0;
109 int last_pos = strlen(program) - 1;
110 for (i = 0; program[i] != '\0'; i++) {
111 switch (program[i]) {
112 case ':': dup(); break;
113 case '!': pop(); break;
114 case '^':
115 {
116 /* tail recursion */
117 if (i == last_pos) {
118 i = -1;
119 free(program);
120 program = pop();
121 continue;
122 } else {
123 eval();
124 }
125 }
126 break;
127 case '~': swap(); break;
128 case '*': concat(); break;
129 case 'S': output(); break;
130 case 'a': enclose(); break;
131 case '(':
132 {
133 int level = 0;
134 int j = 0;
135 char *t = malloc(256);
136
137 i++;
138 level++;
139 while (level > 0) {
140 if (program[i] == '(')
141 level++;
142 else if (program[i] == ')')
143 level--;
144 if (level > 0) {
145 t[j] = program[i];
146 j++;
147 }
148 i++;
149 }
150 i--;
151 t[j] = '\0';
152 push(t);
153 }
154 break;
155 }
156 /*dumpstack();*/
157 }
158 free(program);
159 }
160
161 int main(int argc, char **argv)
162 {
163 char *program = strdup(argv[1]);
164 root = NULL;
165 run(program);
166 exit(0);
167 }