1 #include <string.h>
2 #include <stdbool.h>
3 #include "term.h"
4 
5 #define NELEM(X) (sizeof(X) / sizeof((X)[0]))
6 
7 // special form token
8 static const char *special[] = {
9     "defun", "defmacro", "defglobal", "defdynamic", "defconstant",
10     "let", "let*", "case", "while", "progn",
11 };
12 
13 // syntax token
14 static const char *syntax[] = {
15     "lambda", "labels", "flet", "let", "let*", "setq", "setf",
16     "defconstant", "defun", "defmacro", "defglobal", "defdynamic",
17     "dynamic", "set-dynamic", "function", "function*", "symbol-function",
18     "class",
19     "and", "or", "if", "cond", "while", "for", "block", "return-from",
20     "case", "case-using", "progn", "defclass", "defgeneric", "defgeneric*",
21     "defmethod", "dynamic-let", "ignore-errors", "catch", "throw",
22     "tagbody", "go", "unwind-protect", "with-standard-input",
23     "with-standard-output", "with-error-output", "with-handler",
24     "convert", "with-open-input-file", "with-open-output-file",
25     "with-open-io-file", "the", "assure", "time", "trace", "untrace",
26     "defmodule", "defpublic", "modulesubst",
27 };
28 
29 // builtin token
30 static const char *builtin[] = {
31     "-", "*", "/=", "+", "<", "<=", "=", ">", ">=",
32     "abs", "append", "apply", "aref", "arithmetic-error-operands",
33     "arithmetic-error-operation", "array-dimensions", "assoc", "atan",
34     "atan2", "atanh", "atom", "basic-array-p", "basic-array*-p",
35     "basic-vector-p", "call-next-method", "car", "cdr", "ceiling",
36     "cerror", "char-index", "char/=", "char<", "char<=", "char=",
37     "char>", "char>=", "characterp", "class-of", "close",
38     "condition-continuable", "cons", "consp", "continue-condition",
39     "cos", "cosh", "create-array", "create-list",
40     "create-string-input-stream",
41     "create-string-output-stream", "create-string", "create-vector",
42     "create",
43     "div", "domain-error-object", "domain-error-expected-class",
44     "dummyp", "elt", "eq", "eql", "equal", "error-output", "error",
45     "eval", "exp", "expt", "file-length", "file-position", "finish-output",
46     "float", "floatp", "floor", "format-char", "format-fresh-line",
47     "format-float", "format-integer", "format-object", "format-tab",
48     "format",
49     "funcall", "functionp", "garef", "gbc", "gcd", "general-array*-p",
50     "general-vector-p", "generic-function-p", "gensym",
51     "get-internal-real-time",
52     "get-internal-run-time",
53     "get-output-stream-string", "get-universal-time", "hdmp", "identity",
54     "initialize-object*", "input-stream-p", "instancep", "integerp",
55     "internal-time-units-per-second", "isqrt", "lcm", "length", "list",
56     "listp", "load", "log", "map-into", "mapc", "mapcar", "mapcan",
57     "mapcon", "mapl", "maplist", "max", "member", "min", "mod",
58     "next-method-p", "not", "nreverse", "null", "numberp",
59     "open-input-file", "open-io-file", "open-output-file", "open-stream-p",
60     "output-stream-p", "parse-error-string", "parse-error-expected-class",
61     "parse-number", "preview-char", "prin1", "print", "probe-file",
62     "property", "quit", "quotient", "read-byte", "read-char", "read-line",
63     "read", "reciprocal", "remove-property", "reverse", "round",
64     "set-aref",
65     "set-car", "set-cdr", "set-elt", "set-file-position", "set-garef",
66     "set-property", "signal-condition", "simple-error-format-argument",
67     "simple-error-format-string", "sin", "sinh", "slot-value", "sqrt",
68     "standard-input", "standard-output", "stream-error-stream", "streamp",
69     "stream-ready-p", "string-append", "string-index", "string/=",
70     "string<", "string<=", "string=", "string>", "string>=", "stringp",
71     "subclassp",
72     "subseq", "symbolp", "tan", "tanh", "truncate",
73     "undefined-entity-name",
74     "undefined-entity-namespace", "vector", "write-byte", "import",
75 };
76 
77 // extended function
78 static const char *extended[] = {
79     "random-real", "random", "heapdump", "instance",
80     "nconc", "fast-address", "macroexpand-1", "macroexpand-all",
81     "backtrace",
82     "break", "edit", "set-editor", "wiringpi-setup-gpio",
83     "delay-microseconds",
84     "wiringpi-spi-setup-ch-speed", "pwm-set-mode", "pwm-set-range",
85     "pwm-set-clock", "pin-mode", "digital-write", "digital-read",
86     "pwm-write", "pull-up-dn-control", "delay", "compile-file",
87     "formatter", "line-argument", "getenv",
88     "c-include", "c-define", "c-lang", "c-option",
89 };
90 
91 static bool
in_syntax_table(const char * str)92 in_syntax_table(const char *str)
93 {
94     int             i;
95 
96     for (i = 0; i < (int) NELEM(syntax); i++) {
97 	if (strcmp(syntax[i], str) == 0) {
98 	    return true;
99 	}
100     }
101     return false;
102 }
103 
104 static bool
in_builtin_table(const char * str)105 in_builtin_table(const char *str)
106 {
107     int             i;
108 
109     for (i = 0; i < (int) NELEM(builtin); i++) {
110 	if (strcmp(builtin[i], str) == 0) {
111 	    return true;
112 	}
113     }
114     return false;
115 }
116 
117 static bool
in_extended_table(const char * str)118 in_extended_table(const char *str)
119 {
120     int             i;
121 
122     for (i = 0; i < (int) NELEM(extended); i++) {
123 	if (strcmp(extended[i], str) == 0) {
124 	    return true;
125 	}
126     }
127     return false;
128 }
129 
130 bool
in_special_table(const char * str)131 in_special_table(const char *str)
132 {
133     int             i;
134 
135     for (i = 0; i < (int) NELEM(special); i++) {
136 	if (strcmp(special[i], str) == 0) {
137 	    return true;
138 	}
139     }
140     return false;
141 }
142 
143 enum HighlightToken
maybe_match(const char * str)144 maybe_match(const char *str)
145 {
146     if (in_syntax_table(str)) {
147 	return HIGHLIGHT_SYNTAX;
148     }
149     if (in_builtin_table(str)) {
150 	return HIGHLIGHT_BUILTIN;
151     }
152     if (in_extended_table(str)) {
153 	return HIGHLIGHT_EXTENDED;
154     }
155     return HIGHLIGHT_NONE;
156 }
157 
158 void
gather_fuzzy_matches(const char * str,const char * candidates[],int * candidate_pt)159 gather_fuzzy_matches(const char *str, const char *candidates[],
160 		     int *candidate_pt)
161 {
162     int             i;
163 
164     for (i = 0; i < (int) NELEM(syntax); i++) {
165 	if (strstr(syntax[i], str) != NULL && syntax[i][0] == str[0]) {
166 	    candidates[*candidate_pt] = syntax[i];
167 	    *candidate_pt = (*candidate_pt) + 1;
168 	}
169     }
170     for (i = 0; i < (int) NELEM(builtin); i++) {
171 	if (strstr(builtin[i], str) != NULL && builtin[i][0] == str[0]) {
172 	    candidates[*candidate_pt] = builtin[i];
173 	    *candidate_pt = (*candidate_pt) + 1;
174 	}
175     }
176     for (i = 0; i < (int) NELEM(extended); i++) {
177 	if (strstr(extended[i], str) != NULL && extended[i][0] == str[0]) {
178 	    candidates[*candidate_pt] = extended[i];
179 	    *candidate_pt = (*candidate_pt) + 1;
180 	}
181     }
182 }
183