45 static char *last_string_seen
;
46 static int lss_sz
= 0, token_pushed
= 0, lineno
= 1;
47 static TOKEN forced_token
;
49 void was_expecting(const char *s
)
51 fprintf(stderr
, "Line %d: Fatal: was expecting %s\n", lineno
, s
);
55 void unexpected(const char *s
)
57 fprintf(stderr
, "Line %d: Fatal: unexpected %s\n", lineno
, s
);
71 if (c
>= 'A' && c
<= 'Z')
73 if (c
== '\t' || c
== '\n')
79 static TOKEN
nt_varname(const char *prefix
, char first
)
81 int pre_len
= strlen(prefix
);
82 int min_len
= ((31 > pre_len
) ? 31 : (2 * pre_len
)) + 1;
86 if (!((c
<= 'z' && c
>= 'a') || (c
<= '9' && c
>= '0') || c
== '_')) {
90 if (last_string_seen
== NULL
) {
91 last_string_seen
= malloc(sizeof (char) * min_len
);
93 } else if (min_len
> lss_sz
) {
94 last_string_seen
= realloc(last_string_seen
, sizeof (char) * min_len
);
98 strcpy(last_string_seen
, prefix
);
99 ip
= last_string_seen
+ pre_len
;
102 if (!((c
<= 'z' && c
>= 'a') || (c
<= '9' && c
>= '0') || c
== '_'))
106 if (++slen
>= lss_sz
) {
108 last_string_seen
= realloc(last_string_seen
, sizeof (char) * lss_sz
);
109 ip
= last_string_seen
+ slen
;
125 switch (c
= next_char()) {
127 switch (c
= next_char()) {
132 return nt_varname("as", c
);
135 switch (c
= next_char()) {
137 switch (c
= next_char()) {
142 return nt_varname("all", c
);
145 return nt_varname("al", c
);
148 return nt_varname("a", c
);
156 switch (c
= next_char()) {
158 switch (c
= next_char()) {
160 switch (c
= next_char()) {
162 switch (c
= next_char()) {
167 return nt_varname("bool", c
);
170 return nt_varname("boo", c
);
173 return nt_varname("bo", c
);
176 switch (c
= next_char()) {
178 switch (c
= next_char()) {
183 return nt_varname("but", c
);
186 return nt_varname("bu", c
);
189 return nt_varname("b", c
);
197 switch (c
= next_char()) {
199 switch (c
= next_char()) {
201 switch (c
= next_char()) {
203 switch (c
= next_char()) {
208 return nt_varname("char", c
);
211 return nt_varname("cha", c
);
214 return nt_varname("ch", c
);
217 return nt_varname("c", c
);
225 switch (c
= next_char()) {
227 switch (c
= next_char()) {
232 switch (c
= next_char()) {
234 switch (c
= next_char()) {
239 return nt_varname("done", c
);
242 return nt_varname("don", c
);
245 return nt_varname("do", c
);
248 return nt_varname("d", c
);
256 switch (c
= next_char()) {
258 switch (c
= next_char()) {
260 switch (c
= next_char()) {
265 return nt_varname("for", c
);
268 return nt_varname("fo", c
);
271 switch (c
= next_char()) {
273 switch (c
= next_char()) {
275 switch (c
= next_char()) {
277 switch (c
= next_char()) {
282 return nt_varname("false", c
);
285 return nt_varname("fals", c
);
288 return nt_varname("fal", c
);
291 return nt_varname("fa", c
);
294 return nt_varname("f", c
);
302 switch (c
= next_char()) {
304 switch (c
= next_char()) {
306 switch (c
= next_char()) {
308 switch (c
= next_char()) {
310 switch (c
= next_char()) {
312 switch (c
= next_char()) {
317 return nt_varname("inputc", c
);
320 switch (c
= next_char()) {
325 return nt_varname("inputn", c
);
328 return nt_varname("input", c
);
331 return nt_varname("inpu", c
);
334 return nt_varname("inp", c
);
337 return nt_varname("in", c
);
340 return nt_varname("i", c
);
348 switch (c
= next_char()) {
350 switch (c
= next_char()) {
352 switch (c
= next_char()) {
357 return nt_varname("max", c
);
360 return nt_varname("ma", c
);
363 switch (c
= next_char()) {
365 switch (c
= next_char()) {
370 return nt_varname("min", c
);
373 return nt_varname("mi", c
);
376 return nt_varname("m", c
);
384 switch (c
= next_char()) {
386 switch (c
= next_char()) {
388 switch (c
= next_char()) {
390 switch (c
= next_char()) {
395 return nt_varname("next", c
);
398 return nt_varname("nex", c
);
401 return nt_varname("ne", c
);
404 switch (c
= next_char()) {
406 switch (c
= next_char()) {
411 return nt_varname("not", c
);
414 return nt_varname("no", c
);
417 return nt_varname("n", c
);
425 switch (c
= next_char()) {
427 switch (c
= next_char()) {
429 switch (c
= next_char()) {
431 switch (c
= next_char()) {
436 return nt_varname("prev", c
);
439 return nt_varname("pre", c
);
442 switch (c
= next_char()) {
444 switch (c
= next_char()) {
446 switch (c
= next_char()) {
451 return nt_varname("print", c
);
454 return nt_varname("prin", c
);
457 return nt_varname("pri", c
);
460 return nt_varname("pr", c
);
463 switch (c
= next_char()) {
465 switch (c
= next_char()) {
467 switch (c
= next_char()) {
472 return nt_varname("push", c
);
475 return nt_varname("pus", c
);
478 return nt_varname("pu", c
);
481 return nt_varname("p", c
);
489 switch (c
= next_char()) {
491 switch (c
= next_char()) {
493 switch (c
= next_char()) {
495 switch (c
= next_char()) {
500 return nt_varname("true", c
);
503 return nt_varname("tru", c
);
506 return nt_varname("tr", c
);
509 return nt_varname("t", c
);
517 switch (c
= next_char()) {
519 switch (c
= next_char()) {
521 switch (c
= next_char()) {
523 switch (c
= next_char()) {
525 switch (c
= next_char()) {
530 return nt_varname("while", c
);
533 return nt_varname("whil", c
);
536 return nt_varname("whi", c
);
539 return nt_varname("wh", c
);
542 return nt_varname("w", c
);
546 static TOKEN
nt_lparen()
548 char c
= next_char();
557 static TOKEN
nt_asterisk()
559 if (next_char() == ')')
567 if (next_char() == '-')
596 return nt_asterisk();
622 return nt_varname("", c
);
626 void push_back_token(TOKEN t
)
635 int comment_depth
= 0;
644 if (t
== T_COMBEGIN
) {
650 else if (t
== T_COMEND
) {
651 if (comment_depth
== 0) {
655 } else if (t
== T_EOF
) {
656 fprintf(stderr
, "Line %d: Fatal: unterminated comment\n", lineno
);
660 } while (comment_depth
> 0 || t
== T_COMBEGIN
);
666 /* binding levels. 5 is tightest binding (parens, vars), 0 is loosest
679 TOKEN t
= next_token();
682 to_return
= malloc(sizeof (ast
));
683 to_return
->type
= A_DUAL
;
684 to_return
->adata
.adual
= malloc(sizeof (ast_dual
));
685 to_return
->adata
.adual
->operator = EQ
;
686 to_return
->adata
.adual
->arg_1
= e1
;
687 to_return
->adata
.adual
->arg_2
= expr_1();
698 TOKEN t
= next_token();
701 if (t
== T_MINUS
|| t
== T_TRUE
|| t
== T_FALSE
|| t
== T_VARNAME
707 to_return
= malloc(sizeof (ast
));
708 if (t
== T_MIN
|| t
== T_MAX
) {
709 to_return
->type
= A_DUAL
;
710 to_return
->adata
.adual
= malloc(sizeof (ast_dual
));
711 to_return
->adata
.adual
->operator =(t
== T_MIN
) ? MIN
: MAX
;
712 to_return
->adata
.adual
->arg_1
= expr_2();
713 to_return
->adata
.adual
->arg_2
= expr_2();
714 } else if (t
== T_NOT
|| t
== T_BOOL
|| t
== T_CHAR
|| t
== T_NEXT
716 to_return
->type
= A_UNARY
;
717 to_return
->adata
.aunary
= malloc(sizeof (ast_unary
));
720 to_return
->adata
.aunary
->operator = NOT
;
723 to_return
->adata
.aunary
->operator = CBOOL
;
726 to_return
->adata
.aunary
->operator = CCHAR
;
729 to_return
->adata
.aunary
->operator = NEXT
;
732 to_return
->adata
.aunary
->operator = PREV
;
735 to_return
->adata
.aunary
->arg
= expr_2();
737 was_expecting("operator, -, constant, variable name, or (");
746 TOKEN t
= next_token();
748 while (t
== T_PLUS
|| t
== T_MINUS
) {
750 to_return
= malloc(sizeof (ast
));
751 to_return
->type
= A_DUAL
;
752 to_return
->adata
.adual
= malloc(sizeof (ast_dual
));
753 to_return
->adata
.adual
->operator =(t
== T_PLUS
) ? SUM
: DIFF
;
754 to_return
->adata
.adual
->arg_1
= e1
;
755 to_return
->adata
.adual
->arg_2
= expr_3();
766 TOKEN t
= next_token();
768 while (t
== T_PROD
|| t
== T_DIV
) {
770 to_return
= malloc(sizeof (ast
));
771 to_return
->type
= A_DUAL
;
772 to_return
->adata
.adual
= malloc(sizeof (ast_dual
));
773 to_return
->adata
.adual
->operator =(t
== T_PROD
) ? PRODUCT
: DIV
;
774 to_return
->adata
.adual
->arg_1
= e1
;
775 to_return
->adata
.adual
->arg_2
= expr_4();
784 TOKEN t
= next_token();
788 to_return
= malloc(sizeof (ast
));
789 to_return
->type
= A_UNARY
;
790 to_return
->adata
.aunary
= malloc(sizeof (ast_unary
));
791 to_return
->adata
.aunary
->operator = NEGATION
;
792 to_return
->adata
.aunary
->arg
= expr_5();
802 TOKEN t
= next_token();
809 if (t
== T_VARNAME
) {
810 to_return
= malloc(sizeof (ast
));
811 to_return
->type
= A_VAR
;
812 to_return
->adata
.avar
= find_var(last_string_seen
);
816 to_return
= expr_0();
817 if (next_token() != T_RPAREN
)
821 was_expecting("expression");
830 ast_func
*build_func(TOKEN first
)
832 ast_func
*to_return
= malloc(sizeof (ast_func
));
836 to_return
->operator = PUSH
;
837 to_return
->arg_1
= build_expr(0);
840 to_return
->operator = PRINT
;
841 to_return
->arg_1
= build_expr(0);
844 to_return
->operator = INPUTC
;
847 to_return
->operator = INPUTN
;
850 to_return
->operator = ASSIGN
;
851 to_return
->arg_1
= malloc(sizeof (ast
));
852 if (next_token() != T_GETS
)
853 was_expecting("assignment");
854 to_return
->arg_1
->type
= A_VAR
;
855 to_return
->arg_1
->adata
.avar
= find_var(last_string_seen
);
856 to_return
->arg_2
= build_expr(0);
859 was_expecting("known function");
865 ast_seq
*build_seq();
867 ast_while
*build_while()
869 ast_while
*to_return
= malloc(sizeof (ast_while
));
871 to_return
->condition
= build_expr(0);
873 if (next_token() != T_DO
)
876 to_return
->commands
= build_seq(1);
881 int stoi(const char *s
)
883 if (!strcmp(s
, "one"))
885 if (!strcmp(s
, "two"))
887 if (!strcmp(s
, "three"))
889 if (!strcmp(s
, "four"))
891 if (!strcmp(s
, "five"))
893 if (!strcmp(s
, "six"))
895 if (!strcmp(s
, "seven"))
897 if (!strcmp(s
, "eight"))
899 if (!strcmp(s
, "nine"))
904 const char *itos(int i
)
932 ast_for
*to_return
= malloc(sizeof (ast_for
));
933 int k1
= -1, k2
= -1, ktmp
, is_range
, is_remove
= 0;
934 const char *kref
= NULL
;
935 int max_knights
= 8, max_knights_remove
= 8;
939 to_return
->num_knights
= 0;
940 to_return
->num_knights_remove
= 0;
941 to_return
->iterable_knights
= malloc(max_knights
* sizeof (char *));
942 to_return
->removable_knights
= malloc(max_knights_remove
* sizeof (char *));
957 k1
= stoi(last_string_seen
);
958 if ((c
= next_char()) == '.') {
960 was_expecting("literal knight name");
961 if ((c
= next_char()) == '.') {
965 was_expecting("range-ending knight reference");
966 k2
= stoi(last_string_seen
);
968 was_expecting("literal knight reference ('one', 'eight', etc)");
973 kref
= last_string_seen
;
979 was_expecting("variable name, all, but, or as");
982 if (t
!= T_AS
&& t
!= T_BUT
) {
985 fprintf(stderr
, "Line %d: Fatal: range %d..%d is invalid\n", lineno
,
991 if (to_return
->num_knights
+ (k2
- k1
+ 1) >= max_knights
) {
992 max_knights
+= k2
- k1
;
993 to_return
->iterable_knights
= realloc(to_return
->iterable_knights
,
998 if (to_return
->num_knights_remove
+ (k2
- k1
+ 1) >=
999 max_knights_remove
) {
1000 max_knights_remove
+= k2
- k1
;
1001 to_return
->removable_knights
= realloc(to_return
->removable_knights
,
1002 max_knights_remove
*
1008 for (ktmp
= k1
; ktmp
<= k2
; ++ktmp
) {
1010 to_return
->iterable_knights
[to_return
->num_knights
] =
1011 malloc(sizeof (char) * (strlen(kref
) + 1));
1012 strcpy(to_return
->iterable_knights
[to_return
->num_knights
], kref
);
1013 to_return
->num_knights
++;
1015 max_knights
+= (k2
- k1
+ 1);
1017 for (ktmp
= k1
; ktmp
<= k2
; ++ktmp
) {
1019 to_return
->removable_knights
[to_return
->num_knights_remove
] =
1020 malloc(sizeof (char) * (strlen(kref
) + 1));
1021 strcpy(to_return
->removable_knights
[to_return
->num_knights_remove
],
1023 to_return
->num_knights_remove
++;
1025 max_knights_remove
+= (k2
- k1
+ 1);
1030 if (to_return
->num_knights
+ 1 >= max_knights
) {
1032 to_return
->iterable_knights
= realloc(to_return
->iterable_knights
,
1036 to_return
->iterable_knights
[to_return
->num_knights
] =
1037 malloc(sizeof (char) * (strlen(kref
) + 1));
1038 strcpy(to_return
->iterable_knights
[to_return
->num_knights
], kref
);
1039 to_return
->num_knights
++;
1041 if (to_return
->num_knights_remove
+ 1 >= max_knights_remove
) {
1042 max_knights_remove
*= 2;
1043 to_return
->removable_knights
= realloc(to_return
->removable_knights
,
1044 max_knights_remove
*
1047 to_return
->removable_knights
[to_return
->num_knights_remove
] =
1048 malloc(sizeof (char) * (strlen(kref
) + 1));
1049 strcpy(to_return
->removable_knights
[to_return
->num_knights_remove
],
1051 to_return
->num_knights_remove
++;
1055 } while (t
!= T_AS
);
1059 was_expecting("variable");
1061 to_return
->variable
= find_var(last_string_seen
);
1065 was_expecting("do");
1067 to_return
->commands
= build_seq(1);
1072 ast_seq
*build_seq(int expect_done
)
1074 ast_seq
*to_return
= calloc(1, sizeof (ast_seq
));
1075 ast_seq
*current
= to_return
;
1080 if (t
== T_DONE
|| t
== T_EOF
) {
1081 if (expect_done
== (t
== T_DONE
)) {
1084 unexpected("done or EOF");
1087 current
->data
= calloc(1, sizeof (ast
));
1089 current
->data
->type
= A_WHILE
;
1090 current
->data
->adata
.awhile
= build_while();
1091 } else if (t
== T_FOR
) {
1092 current
->data
->type
= A_FOR
;
1093 current
->data
->adata
.afor
= build_for();
1095 current
->data
->type
= A_FUNC
;
1096 current
->data
->adata
.afunc
= build_func(t
);
1098 current
->next
= calloc(1, sizeof (ast_seq
));
1099 current
= current
->next
;
1103 ast
*build(FILE * input
)
1105 ast
*to_return
= malloc(sizeof (ast
));
1108 fprintf(stderr
, "Could not open input file\n");
1114 to_return
->type
= A_SEQ
;
1115 to_return
->adata
.aseq
= build_seq(0);