! Copyright (C) 2004, 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. IN: compiler USING: arrays assembler errors generic hashtables inference kernel kernel-internals math namespaces sequences words ; GENERIC: stack-reserve* ( node -- n ) M: object stack-reserve* drop 0 ; : stack-reserve ( node -- n ) 0 swap [ stack-reserve* max ] each-node ; : intrinsic ( #call -- quot ) node-param "intrinsic" word-prop ; : if-intrinsic ( #call -- quot ) node-param "if-intrinsic" word-prop ; DEFER: #terminal? PREDICATE: #merge #terminal-merge node-successor #terminal? ; PREDICATE: #values #terminal-values node-successor #terminal? ; PREDICATE: #call #terminal-call dup node-successor #if? over node-successor node-successor #terminal? and swap if-intrinsic and ; UNION: #terminal POSTPONE: f #return #terminal-values #terminal-merge ; : tail-call? ( -- ? ) node-stack get [ dup #terminal-call? swap node-successor #terminal? or ] all? ; : generate-code ( node quot -- ) over stack-reserve %prologue call ; inline : init-generator ( -- ) V{ } clone relocation-table set V{ } clone literal-table set V{ } clone label-table set V{ } clone word-table set ; : generate-1 ( word node quot -- ) #! Generate the code, then dump three vectors to pass to #! add-compiled-block. pick f save-xt [ init-generator init-templates generate-code generate-labels relocation-table get literal-table get word-table get ] V{ } make code-format add-compiled-block save-xt ; GENERIC: generate-node ( node -- ) : generate-nodes ( node -- ) [ node@ generate-node ] iterate-nodes end-basic-block ; : generate-branch ( node -- ) [ generate-nodes ] keep-templates ; : generate ( word node -- ) [ [ generate-nodes ] with-node-iterator ] generate-1 ; ! node M: node generate-node drop iterate-next ; ! #label : generate-call ( label -- next ) end-basic-block tail-call? [ %jump f ] [ %call iterate-next ] if ; M: #label generate-node dup node-param dup generate-call >r swap node-child generate r> ; ! #if : end-false-branch ( label -- ) tail-call? [ %return drop ] [ %jump-label ] if ; : generate-if ( node label -- next )