(defun initialize-buffer (nodes builder) (insert-c++-comment-prefix nodes builder) (insert "#include \n" "\n" "#include \"AST.h\"\n" "#include \"code-commonsub.h\"\n" "#include \"streq.h\"\n")) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun defnode* (name parents fields methods states) (let* ((details (resolve-fields fields)) (flds (aref details 2)) (states (resolve-states states))) (insert (format "\n\nbool %s::compare (const TreeNode *t) const\n" name) "{\n" " if (!streq(oper_name(), t->oper_name())) return false;\n" (format " const %s *u;\n u = (const %s *) t;\n" name name) " return true ") (loop for f in flds do (insert (format "\n && // fld=%s\n" f)) (create-comparison (to-c++-node-type (cadr f)) (to-c++-type (cadr f)) (format "%s()" (basic-field-name (car f))))) (loop for info in states do (unless (string-prefix-p "static " (cadr info)) (insert (format "\n && // state=%s\n" info)) (create-comparison (cadr info) (cadr info) (car info)))) (insert ";\n}\n"))) ;;; type is the C type. var is the name of the variable or accessor method, ;;; e.g., "imports()" (defun create-comparison (nodetype type var) (insert (format " // nodetype=%s, type=%s, var=%s\n" nodetype type var)) (cond ((string-match "TreeListNode" nodetype) (insert (format "COMPARE(%s, u->%s)" var var))) ((and (string-match "TreeNode *\\*" type) (string-match "list" type)) (insert (format "compareLists(%s, u->%s)" var var))) ((eq 0 (string-match "TreeNode *\\*" type)) (insert (format "(%s->absent() == u->%s->absent()) && (%s->absent() || COMPARE(%s, u->%s))" var var var var var))) ((and (string-match "TypeNode *\\*" type) (not (string-match "list" type))) (insert (format "(%s->cType() == u->%s->cType())" var var))) ((string-match "Literal" type) (insert (format "(%s.asString() == u->%s.asString())" var var))) ((string-match "string *\\*" type) (insert (format "(*%s == *u->%s)" var var))) (t (insert (format "(%s == u->%s)" var var)))))