| 1 : |
anton
|
1.1
|
;;$Id: primitives2c.el,v 1.12 1994/01/31 15:43:38 pazsan Exp $ |
| 2 : |
|
|
;;Copyright 1992 by the ANSI figForth Development Group |
| 3 : |
|
|
|
| 4 : |
|
|
;; To Do: |
| 5 : |
|
|
;; rewrite in Forth (using regexp) |
| 6 : |
|
|
;; cleanup wrt. float vs. cell and load vs. store |
| 7 : |
|
|
|
| 8 : |
|
|
;Optimizations: |
| 9 : |
|
|
;superfluous stores are removed. GCC removes the superfluous loads by itself |
| 10 : |
|
|
;TOS and FTOS can be kept in register( variable)s. |
| 11 : |
|
|
; |
| 12 : |
|
|
;Problems: |
| 13 : |
|
|
;The TOS optimization is somewhat hairy. The problems by example: |
| 14 : |
|
|
;1) dup ( w -- w w ): w=TOS; sp-=1; sp[1]=w; TOS=w; |
| 15 : |
|
|
; The store is not superfluous although the earlier opt. would think so |
| 16 : |
|
|
; Alternatively: sp[0]=TOS; w=TOS; sp-=1; TOS=w; |
| 17 : |
|
|
;2) ( -- .. ): sp[0] = TOS; ... /* This additional store is necessary */ |
| 18 : |
|
|
;3) ( .. -- ): ... TOS = sp[0]; /* as well as this load */ |
| 19 : |
|
|
;4) ( -- ): /* but here they are unnecessary */ |
| 20 : |
|
|
;5) Words that call NEXT themselves have to be done very carefully. |
| 21 : |
|
|
|
| 22 : |
|
|
(setq max-lisp-eval-depth 1000) |
| 23 : |
|
|
|
| 24 : |
|
|
(defun filter-primitives (source destination filter) |
| 25 : |
|
|
"convert source into destination using filter" |
| 26 : |
|
|
(switch-to-buffer (generate-new-buffer destination)) |
| 27 : |
|
|
(insert-file source) |
| 28 : |
|
|
(insert (format "/* File generated by $RCSfile: primitives2c.el,v $ (%s) from %s */\n" filter source)) |
| 29 : |
|
|
(filter-primitives1 filter) |
| 30 : |
|
|
(write-file destination)) |
| 31 : |
|
|
|
| 32 : |
|
|
(defun match-string (N) |
| 33 : |
|
|
"Returns the string of the Nth match" |
| 34 : |
|
|
(let ((b (match-beginning N)) |
| 35 : |
|
|
(e (match-end N))) |
| 36 : |
|
|
(cond (b (buffer-substring b e)) |
| 37 : |
|
|
(t "")))) |
| 38 : |
|
|
|
| 39 : |
|
|
(defun filter-primitives1 (filter) |
| 40 : |
|
|
"replace primitives in the rest of the buffer with filtered primitives" |
| 41 : |
|
|
(cond ((re-search-forward "^\\([^ \t\n]+\\)\t+\\([^\t\n]*--[^\t\n]*\\)\t+\\([^\t\n]+\\)\t*\\([^ \t\n]+\\)?\n\\(\"\"[^\"]*\"\"\n\\)?\\(\\([^:\n].*\n\\)*\\)\\(:\n\\(\\(.+\n\\)*\\)\\)?$" nil t) |
| 42 : |
|
|
;\\(:\n\\(\\(.+\n\\)*\\)\\)? |
| 43 : |
|
|
(replace-match |
| 44 : |
|
|
(funcall filter |
| 45 : |
|
|
(match-string 1) |
| 46 : |
|
|
(match-string 2) |
| 47 : |
|
|
(match-string 3) |
| 48 : |
|
|
(cond ((equal (match-string 4) "") (match-string 1)) |
| 49 : |
|
|
(t (match-string 4))) |
| 50 : |
|
|
(match-string 5) |
| 51 : |
|
|
(match-string 7) |
| 52 : |
|
|
(match-string 9) |
| 53 : |
|
|
)) |
| 54 : |
|
|
(filter-primitives1 filter)))) |
| 55 : |
|
|
|
| 56 : |
|
|
(defun list-filter (forth-name stack-effect standards c-name doku code forth-code) |
| 57 : |
|
|
(format "&&I_%s," c-name)) |
| 58 : |
|
|
|
| 59 : |
|
|
(defvar primitive-number 0) |
| 60 : |
|
|
|
| 61 : |
|
|
(defun alias-filter (forth-name stack-effect standards c-name doku code forth-code) |
| 62 : |
|
|
(setq primitive-number (+ 1 primitive-number)) |
| 63 : |
|
|
(format "%s Alias %s" (- -5 primitive-number) forth-name)) |
| 64 : |
|
|
|
| 65 : |
|
|
(defun c-filter (forth-name stack-effect standards c-name doku code forth-code) |
| 66 : |
|
|
"c code for the primitive" |
| 67 : |
|
|
(let ((effects (parse-stack-effect stack-effect))) |
| 68 : |
|
|
(format "I_%s: /* %s ( %s ) */\n/* %s */\n{\n%s\nNAME(\"%s\")\n{\n%s}\nNEXT_P1;\n%s}\nNEXT1_P2;\n" |
| 69 : |
|
|
c-name forth-name stack-effect doku |
| 70 : |
|
|
(prefix effects) forth-name code (suffix effects)))) |
| 71 : |
|
|
|
| 72 : |
|
|
(defun forth-filter (forth-name stack-effect standards c-name doku code forth-code) |
| 73 : |
|
|
"forth equivalent for the primitive" |
| 74 : |
|
|
;should other info be included? |
| 75 : |
|
|
(cond ((equal forth-code "") "") |
| 76 : |
|
|
(t (format ": %s ( %s )\n%s" forth-name stack-effect forth-code)))) |
| 77 : |
|
|
|
| 78 : |
|
|
(defun prefix (effects) |
| 79 : |
|
|
"c-code for declaring vars and getting them from the stack" |
| 80 : |
|
|
(format "%s%s%ssp += %s;\nfp += %s;\n" |
| 81 : |
|
|
(declarations (unique (append (effect-in effects) (effect-out effects)))) |
| 82 : |
|
|
(store-tos effects) |
| 83 : |
|
|
(loads (effect-in effects)) |
| 84 : |
|
|
(effect-cells effects) |
| 85 : |
|
|
(effect-floats effects))) |
| 86 : |
|
|
|
| 87 : |
|
|
(defun suffix (effects) |
| 88 : |
|
|
"c code for storing vars to the stack" |
| 89 : |
|
|
(format "%s%s" |
| 90 : |
|
|
(stores (effect-out effects) effects) |
| 91 : |
|
|
(load-tos effects))) |
| 92 : |
|
|
|
| 93 : |
|
|
(defun unique (set) |
| 94 : |
|
|
"the set with duplicates removed" |
| 95 : |
|
|
(cond ((null set) nil) |
| 96 : |
|
|
((memq (car set) (cdr set)) (unique (cdr set))) |
| 97 : |
|
|
(t (cons (car set) (unique (cdr set)))))) |
| 98 : |
|
|
|
| 99 : |
|
|
(defun cells (vars) |
| 100 : |
|
|
"the number of stack cells needed by vars" |
| 101 : |
|
|
(cond ((null vars) 0) |
| 102 : |
|
|
(t (+ (cond ((float-type (car vars)) 0) |
| 103 : |
|
|
((double-type (car vars)) 2) |
| 104 : |
|
|
(t 1)) |
| 105 : |
|
|
(cells (cdr vars)))))) |
| 106 : |
|
|
|
| 107 : |
|
|
(defun floats (vars) |
| 108 : |
|
|
"the number of floating-point stack items needed by vars" |
| 109 : |
|
|
(cond ((null vars) 0) |
| 110 : |
|
|
(t (+ (cond ((float-type (car vars)) 1) |
| 111 : |
|
|
(t 0)) |
| 112 : |
|
|
(floats (cdr vars)))))) |
| 113 : |
|
|
|
| 114 : |
|
|
(defun declarations (vars) |
| 115 : |
|
|
"C declarations for vars" |
| 116 : |
|
|
(mapconcat '(lambda (var) (format "%s %s;\n" (type var) var)) vars "")) |
| 117 : |
|
|
|
| 118 : |
|
|
(defun regexp-assoc (var ralist) |
| 119 : |
|
|
(cond ((null ralist) (error "%s does not match" var)) |
| 120 : |
|
|
((string-match (caar ralist) var) (cadar ralist)) |
| 121 : |
|
|
(t (regexp-assoc var (cdr ralist))))) |
| 122 : |
|
|
|
| 123 : |
|
|
|
| 124 : |
|
|
(defun type (var) |
| 125 : |
|
|
"a declaration for var" |
| 126 : |
|
|
(let ((data (match-data))) |
| 127 : |
|
|
(unwind-protect |
| 128 : |
|
|
(regexp-assoc (format "%s" var) |
| 129 : |
|
|
'(("^a_" "Cell *") |
| 130 : |
|
|
("^c_" "Char *") |
| 131 : |
|
|
("^df_" "DFloat *") |
| 132 : |
|
|
("^sf_" "SFloat *") |
| 133 : |
|
|
("^f_" "Float *") |
| 134 : |
|
|
("^xt" Xt) |
| 135 : |
|
|
("^wid" Wid) |
| 136 : |
|
|
("^f83name" "F83Name *") |
| 137 : |
|
|
("^ud" UDCell) |
| 138 : |
|
|
("^r" Float) |
| 139 : |
|
|
("^f" Bool) |
| 140 : |
|
|
("^c" Char) |
| 141 : |
|
|
("^[nw]" Cell) |
| 142 : |
|
|
("^u" UCell) |
| 143 : |
|
|
("^d" DCell))) |
| 144 : |
|
|
(store-match-data data)))) |
| 145 : |
|
|
|
| 146 : |
|
|
(defun double-type (var) |
| 147 : |
|
|
(memq (type var) '(UDCell DCell))) |
| 148 : |
|
|
|
| 149 : |
|
|
(defun float-type (var) |
| 150 : |
|
|
(equal (type var) 'Float)) |
| 151 : |
|
|
|
| 152 : |
|
|
(defun loads (vars) |
| 153 : |
|
|
"C code for loading vars from the stack" |
| 154 : |
|
|
(cond ((null vars) "") |
| 155 : |
|
|
((double-type (car vars)) (format "{Double_Store _d; _d.cells.low = %s; _d.cells.high = %s; %s = _d.dcell;}\n%s" |
| 156 : |
|
|
(stack (+ 1 (cells (cdr vars)))) |
| 157 : |
|
|
(stack (cells (cdr vars))) |
| 158 : |
|
|
(car vars) |
| 159 : |
|
|
(loads (cdr vars)))) |
| 160 : |
|
|
((float-type (car vars)) (format "%s = %s;\n%s" |
| 161 : |
|
|
(car vars) |
| 162 : |
|
|
(fstack (floats (cdr vars))) |
| 163 : |
|
|
(loads (cdr vars)))) |
| 164 : |
|
|
(t (format "%s = (%s) %s;\n%s" |
| 165 : |
|
|
(car vars) |
| 166 : |
|
|
(type (car vars)) |
| 167 : |
|
|
(stack (cells (cdr vars))) |
| 168 : |
|
|
(loads (cdr vars)))))) |
| 169 : |
|
|
|
| 170 : |
|
|
(defun stores (vars effects) |
| 171 : |
|
|
"C code for storing vars on the stack" |
| 172 : |
|
|
(cond ((null vars) "") |
| 173 : |
|
|
((redundantq vars effects) (format "/* store redundant */\n%s" |
| 174 : |
|
|
(stores (cdr vars) effects))) |
| 175 : |
|
|
((double-type (car vars)) (format "{Double_Store _d; _d.dcell = %s; %s = _d.cells.low; %s = _d.cells.high;}\n%s" |
| 176 : |
|
|
(car vars) |
| 177 : |
|
|
(stack (+ 1 (cells (cdr vars)))) |
| 178 : |
|
|
(stack (cells (cdr vars))) |
| 179 : |
|
|
(stores (cdr vars) effects))) |
| 180 : |
|
|
((float-type (car vars)) (format "%s = %s;\n%s" |
| 181 : |
|
|
(fstack (floats (cdr vars))) |
| 182 : |
|
|
(car vars) |
| 183 : |
|
|
(stores (cdr vars) effects))) |
| 184 : |
|
|
(t (format "%s = (Cell)%s ;\n%s" |
| 185 : |
|
|
(stack (cells (cdr vars))) |
| 186 : |
|
|
(car vars) |
| 187 : |
|
|
(stores (cdr vars) effects))))) |
| 188 : |
|
|
|
| 189 : |
|
|
(defun redundantq (vars effects) |
| 190 : |
|
|
"Is the store of (car vars) redundant?" |
| 191 : |
|
|
(let ((in-vars (memq (car vars) (effect-in effects)))) |
| 192 : |
|
|
(and in-vars |
| 193 : |
|
|
(cond ((float-type (car vars)) (= (effect-floats effects) |
| 194 : |
|
|
(- (floats in-vars) (floats vars)))) |
| 195 : |
|
|
(t (= (effect-cells effects) |
| 196 : |
|
|
(- (cells in-vars) (cells vars)))))))) |
| 197 : |
|
|
|
| 198 : |
|
|
(defun load-tos (effects) |
| 199 : |
|
|
"TOS-loading code, if necessary" |
| 200 : |
|
|
(format "%s%s" |
| 201 : |
|
|
(cond ((and (= 0 (cells (effect-out effects))) |
| 202 : |
|
|
(< 0 (cells (effect-in effects)))) |
| 203 : |
|
|
"IF_TOS(TOS = sp[0]);\n") |
| 204 : |
|
|
(t "")) |
| 205 : |
|
|
(cond ((and (= 0 (floats (effect-out effects))) |
| 206 : |
|
|
(< 0 (floats (effect-in effects)))) |
| 207 : |
|
|
"IF_FTOS(FTOS = fp[0]);\n") |
| 208 : |
|
|
(t "")))) |
| 209 : |
|
|
|
| 210 : |
|
|
(defun store-tos (effects) |
| 211 : |
|
|
"TOS-storing code, if necessary" |
| 212 : |
|
|
(format "%s%s" |
| 213 : |
|
|
(cond ((or (redundant-tos effects) |
| 214 : |
|
|
(and (= 0 (cells (effect-in effects))) |
| 215 : |
|
|
(< 0 (cells (effect-out effects))))) |
| 216 : |
|
|
"IF_TOS(sp[0] = TOS);\n") |
| 217 : |
|
|
(t "")) |
| 218 : |
|
|
(cond ((or (redundant-ftos effects) |
| 219 : |
|
|
(and (= 0 (floats (effect-in effects))) |
| 220 : |
|
|
(< 0 (floats (effect-out effects))))) |
| 221 : |
|
|
"IF_FTOS(fp[0] = FTOS);\n") |
| 222 : |
|
|
(t "")))) |
| 223 : |
|
|
|
| 224 : |
|
|
(defun redundant-tos (effects) |
| 225 : |
|
|
"Does redundantq consider storing into the original TOS location redundant?" |
| 226 : |
|
|
(red-tos1 (effect-out effects) effects)) |
| 227 : |
|
|
|
| 228 : |
|
|
(defun red-tos1 (vars effects) |
| 229 : |
|
|
(cond ((null vars) nil) |
| 230 : |
|
|
((and (not (float-type (car vars))) |
| 231 : |
|
|
(redundantq vars effects)) |
| 232 : |
|
|
(or (= (- (effect-cells effects)) |
| 233 : |
|
|
(cells (cdr vars))) |
| 234 : |
|
|
(red-tos1 (cdr vars) effects))))) |
| 235 : |
|
|
|
| 236 : |
|
|
(defun redundant-ftos (effects) |
| 237 : |
|
|
"Does redundantq consider storing into the original FTOS location redundant?" |
| 238 : |
|
|
(red-ftos1 (effect-out effects) effects)) |
| 239 : |
|
|
|
| 240 : |
|
|
(defun red-ftos1 (vars effects) |
| 241 : |
|
|
(cond ((null vars) nil) |
| 242 : |
|
|
((and (float-type (car vars)) |
| 243 : |
|
|
(redundantq vars effects)) |
| 244 : |
|
|
(or (= (- (effect-floats effects)) |
| 245 : |
|
|
(floats (cdr vars))) |
| 246 : |
|
|
(red-ftos1 (cdr vars) effects))))) |
| 247 : |
|
|
|
| 248 : |
|
|
(defun stack (n) |
| 249 : |
|
|
"the stack entry at depth n" |
| 250 : |
|
|
(cond ((= n 0) "TOS") |
| 251 : |
|
|
(t (format "sp[%d]" n)))) |
| 252 : |
|
|
|
| 253 : |
|
|
(defun fstack (n) |
| 254 : |
|
|
"the float stack entry at depth n" |
| 255 : |
|
|
(cond ((= n 0) "FTOS") |
| 256 : |
|
|
(t (format "fp[%d]" n)))) |
| 257 : |
|
|
|
| 258 : |
|
|
(defun parse-stack-effect (stack-effect) |
| 259 : |
|
|
"lists of items before and after --" |
| 260 : |
|
|
(let ((effect-list (read (format "(%s)" stack-effect)))) |
| 261 : |
|
|
(let ((in (stack-before effect-list)) |
| 262 : |
|
|
(out (stack-after effect-list))) |
| 263 : |
|
|
(list in |
| 264 : |
|
|
out |
| 265 : |
|
|
(- (cells in) (cells out)) |
| 266 : |
|
|
(- (floats in) (floats out)))))) |
| 267 : |
|
|
|
| 268 : |
|
|
(defun effect-in (effects) |
| 269 : |
|
|
(car effects)) |
| 270 : |
|
|
|
| 271 : |
|
|
(defun effect-out (effects) |
| 272 : |
|
|
(cadr effects)) |
| 273 : |
|
|
|
| 274 : |
|
|
(defun effect-cells (effects) |
| 275 : |
|
|
"the number of input - output cells" |
| 276 : |
|
|
(cadr (cdr effects))) |
| 277 : |
|
|
|
| 278 : |
|
|
(defun effect-floats (effects) |
| 279 : |
|
|
(cadr (cddr effects))) |
| 280 : |
|
|
|
| 281 : |
|
|
(defun stack-before (effect-list) |
| 282 : |
|
|
(cond ((equal (car effect-list) '--) nil) |
| 283 : |
|
|
(t (cons (car effect-list) (stack-before (cdr effect-list)))))) |
| 284 : |
|
|
|
| 285 : |
|
|
(defun stack-after (effect-list) |
| 286 : |
|
|
(cdr (memq '-- effect-list))) |
| 287 : |
|
|
|
| 288 : |
|
|
(defun cadr (list) |
| 289 : |
|
|
(car (cdr list))) |
| 290 : |
|
|
|
| 291 : |
|
|
(defun caar (list) |
| 292 : |
|
|
(car (car list))) |
| 293 : |
|
|
|
| 294 : |
|
|
(defun cddr (list) |
| 295 : |
|
|
(cdr (cdr list))) |
| 296 : |
|
|
|
| 297 : |
|
|
(defun cadar (list) |
| 298 : |
|
|
(car (cdr (car list)))) |
| 299 : |
|
|
|
| 300 : |
|
|
(defun make-c () |
| 301 : |
|
|
(filter-primitives "primitives.b" "primitives.i" 'c-filter)) |
| 302 : |
|
|
|
| 303 : |
|
|
(defun make-list () |
| 304 : |
|
|
(filter-primitives "primitives.b" "prim_labels.i" 'list-filter)) |
| 305 : |
|
|
|
| 306 : |
|
|
(defun make-alias () |
| 307 : |
|
|
(filter-primitives "primitives.b" "prim_alias.4th" 'alias-filter)) |
| 308 : |
|
|
|
| 309 : |
|
|
(defun make-forth () |
| 310 : |
|
|
(filter-primitives "primitives.b" "primitives.4th" 'forth-filter)) |