compiler.scm
来自「Scheme跨平台编译器」· SCM 代码 · 共 1,734 行 · 第 1/5 页
SCM
1,734 行
;;;; compiler.scm - The CHICKEN Scheme compiler;;;; "This is insane. What we clearly want to do is not exactly clear, and is rooted in NCOMPLR.";;;-----------------------------------------------------------------------------------------------------------; Copyright (c) 2000-2007, Felix L. Winkelmann; Copyright (c) 2008, The Chicken Team; All rights reserved.;; Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following; conditions are met:;; Redistributions of source code must retain the above copyright notice, this list of conditions and the following; disclaimer. ; Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following; disclaimer in the documentation and/or other materials provided with the distribution. ; Neither the name of the author nor the names of its contributors may be used to endorse or promote; products derived from this software without specific prior written permission. ;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY; AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE; POSSIBILITY OF SUCH DAMAGE.;;; Supported syntax:;; - Declaration specifiers:;; (unit <unitname>); (uses {<unitname>}); ([not] standard-bindings {<name>}); ([not] usual-integrations {<name>}); ([not] extended-bindings (<name>}); ([number-type] <type>); (fixnum-arithmetic); (unsafe); ([not] safe); ([not] interrupts-enabled); (no-bound-checks); (no-argc-checks); (no-procedure-checks); (no-procedure-checks-for-usual-bindings); (block-global {<name>}); (lambda-lift); (hide {<name>}); (disable-interrupts); (disable-warning <class> ...); (always-bound {<name>}); (foreign-declare {<string>}); (block); (separate); (run-time-macros); (export {<name>}); (safe-globals); (custom-declare (<tag> <name> <filename> <arg> ...) <string> ...); (data <tag1> <exp1> ...); (post-process <string> ...); (emit-exports <string>); (keep-shadowed-macros); (import <symbol-or-string> ...); (unused <symbol> ...); (profile <symbol> ...);; <type> = fixnum | generic;; - Source language:;; <variable>; <constant>; (##core#declare {(quote <spec>)}); (##core#immutable <exp>); (##core#global-ref <variable>); (quote <exp>); (if <exp> <exp> [<exp>]); (let ({(<variable> <exp>)}) <body>); (##core#let-location (quote <symbol>) (quote <type>) [<init>] <exp>); (lambda <variable> <body>); (lambda ({<variable>}+ [. <variable>]) <body>); (set! <variable> <exp>); (##core#set! <variable> <exp>); (##core#named-lambda <name> <llist> <body>); (##core#loop-lambda <llist> <body>); (##core#undefined); (##core#primitive <name>); (##core#inline <op> {<exp>}); (##core#inline_allocate (<op> <words>) {<exp>}); (##core#inline_ref (<name> <type>)); (##core#inline_update (<name> <type>) <exp>); (##core#inline_loc_ref (<type>) <exp>); (##core#inline_loc_update (<type>) <exp> <exp>); (##core#compiletimetoo <exp>); (##core#compiletimeonly <exp>); (##core#elaborationtimetoo <exp>); (##core#elaborationtimeonly <exp>); (##core#define-foreign-variable (quote <symbol>) (quote <type>) [(quote <string>)]); (##core#define-foreign-type (quote <symbol>) (quote <type>) [<proc1> [<proc2>]]); (##core#foreign-lambda (quote <type>) (quote <string>) {(quote <type>)}); (##core#foreign-lambda* (quote <type>) (quote ({(<type> <var>)})) {(quote <string>)}); (##core#foreign-callback-lambda (quote <type>) (quote <string>) {(quote <type>)}); (##core#foreign-callback-lambda* (quote <type>) (quote ({(<type> <var>)})) {(quote <string>)}); (##core#foreign-primitive (quote <type>) (quote ({(<type> <var>)})) {(quote <string>)}); (##core#define-inline (quote <name>) <exp>); (##core#define-constant (quote <name>) <exp>); (##core#foreign-callback-wrapper (quote <name>) (quote <qualifiers>) (quote <type>) (quote {<type>}) <exp>); (##core#define-external-variable (quote <name>) (quote <type>) (quote <bool>)); (##core#check <exp>); (##core#require-for-syntax <exp> ...); (##core#require-extension '<id> ...); (##core#app <exp> {<exp>}); (<exp> {<exp>});; - Core language:;; [##core#variable {<variable>}]; [if {} <exp> <exp> <exp>)]; [quote {<exp>}]; [let {<variable>} <exp-v> <exp>]; [##core#lambda {<id> <mode> (<variable>... [. <variable>]) <size>} <exp>]; [set! {<variable>} <exp>]; [##core#undefined {}]; [##core#global-ref {<variable>}]; [##core#primitive {<name>}]; [##core#inline {<op>} <exp>...]; [##core#inline_allocate {<op> <words>} <exp>...]; [##core#inline_ref {<name> <type>}]; [##core#inline_update {<name> <type>} <exp>]; [##core#inline_loc_ref {<type>} <exp>]; [##core#inline_loc_update {<type>} <exp> <exp>]; [##core#call {<safe-flag> [<debug-info>]} <exp-f> <exp>...]; [##core#callunit {<unitname>} <exp>...]; [##core#switch {<count>} <exp> <const1> <body1> ... <defaultbody>]; [##core#cond <exp> <exp> <exp>]; [##core#recurse {<tail-flag>} <exp1> ...]; [##core#return <exp>]; [##core#direct_call {<safe-flag> <debug-info> <call-id> <words>} <exp-f> <exp>...]; [##core#direct_lambda {<id> <mode> (<variable>... [. <variable>]) <size>} <exp>];; - Closure converted/prepared language:;; [if {} <exp> <exp> <exp>]; [quote {<exp>}]; [##core#bind {<count>} <exp-v>... <exp>]; [##core#undefined {}]; [##core#inline {<op>} <exp>...]; [##core#inline_allocate {<op <words>} <exp>...]; [##core#inline_ref {<name> <type>}]; [##core#inline_update {<name> <type>} <exp>]; [##core#inline_loc_ref {<type>} <exp>]; [##core#inline_loc_update {<type>} <exp> <exp>]; [##core#closure {<count>} <exp>...]; [##core#box {} <exp>]; [##core#unbox {} <exp>]; [##core#ref {<index>} <exp>]; [##core#update {<index>} <exp> <exp>]; [##core#updatebox {} <exp> <exp>]; [##core#update_i {<index>} <exp> <exp>]; [##core#updatebox_i {} <exp> <exp>]; [##core#call {<safe-flag> [<debug-info> [<call-id> <customizable-flag>]]} <exp-f> <exp>...]; [##core#callunit {<unitname>} <exp>...]; [##core#local {<index>}]; [##core#setlocal {<index>} <exp>]; [##core#global {<literal> <safe-flag> <block-mode> [<name>]}]; [##core#setglobal {<literal> <block-mode>} <exp>]; [##core#setglobal_i {<literal> <block-mode>} <exp>]; [##core#literal {<literal>}]; [##core#immediate {<type> [<immediate>]}] - type: bool/fix/nil/char; [##core#proc {<name> [<non-internal>]}]; [##core#recurse {<tail-flag> <call-id>} <exp1> ...]; [##core#return <exp>]; [##core#direct_call {<safe-flag> <debug-info> <call-id> <words>} <exp-f> <exp>...];;; Analysis database entries:;; <variable>:;; captured -> <boolean> If true: variable is used outside it's home-scope; global -> <boolean> If true: variable does not occur in any lambda-list; call-sites -> ((<lambda-id> <node>) ...) Known call-nodes of a named procedure; home -> <lambda-id> Procedure which introduces this variable; unknown -> <boolean> If true: variable can not have a known value; assigned -> <boolean> If true: variable is assigned somewhere; assigned-locally -> <boolean> If true: variable has been assigned inside user lambda; undefined -> <boolean> If true: variable is unknown yet but can be known later; value -> <node> Variable has a known value; potential-value -> <node> Global variable was assigned this value; references -> (<node> ...) Nodes that are accesses of this variable (##core#variable nodes); side-effecting -> <boolean> If true: variable names side-effecting standard-binding; foldable -> <boolean> If true: variable names foldable standard-binding; boxed -> <boolean> If true: variable has to be boxed after closure-conversion; contractable -> <boolean> If true: variable names contractable procedure; inlinable -> <boolean> If true: variable names potentially inlinable procedure; collapsable -> <boolean> If true: variable refers to collapsable constant; removable -> <boolean> If true: variable is not used; replacable -> <variable> Variable can be replaced by another variable; replacing -> <boolean> If true: variable can replace another variable (don't remove); standard-binding -> <boolean> If true: variable names a standard binding; extended-binding -> <boolean> If true: variable names an extended binding; unused -> <boolean> If true: variable is a formal parameter that is never used; rest-parameter -> #f | 'vector | 'list If true: variable holds rest-argument list mode; o-r/access-count -> <n> Contains number of references as arguments of optimizable rest operators; constant -> <boolean> If true: variable has fixed value; ; <lambda-id>:;; contains -> (<lambda-id> ...) Procedures contained in this lambda; contained-in -> <lambda-id> Procedure containing this lambda; has-unused-parameters -> <boolean> If true: procedure has unused formal parameters; use-expr -> (<lambda-id> ...) Marks non-direct use-sites of common subexpression; closure-size -> <integer> Number of free variables stored in a closure; customizable -> <boolean> If true: all call sites are known, procedure does not escape; simple -> <boolean> If true: procedure only calls its continuation; explicit-rest -> <boolean> If true: procedure is called with consed rest list; captured-variables -> (<var> ...) List of closed over variables(declare (unit compiler) (disable-warning var) )#>#ifndef C_INSTALL_SHARE_HOME# define C_INSTALL_SHARE_HOME NULL#endif#ifndef C_DEFAULT_TARGET_STACK_SIZE# define C_DEFAULT_TARGET_STACK_SIZE 0#endif#ifndef C_DEFAULT_TARGET_HEAP_SIZE# define C_DEFAULT_TARGET_HEAP_SIZE 0#endif<#(private compiler compiler-arguments process-command-line explicit-use-flag inline-list not-inline-list default-standard-bindings default-extended-bindings side-effecting-standard-bindings non-foldable-standard-bindings foldable-standard-bindings non-foldable-extended-bindings foldable-extended-bindings standard-bindings-that-never-return-false side-effect-free-standard-bindings-that-never-return-false installation-home decompose-lambda-list external-to-pointer defconstant-bindings constant-declarations copy-node! error-is-extended-binding toplevel-scope toplevel-lambda-id unit-name insert-timer-checks used-units external-variables require-imports-flag custom-declare-alist profile-info-vector-name finish-foreign-result pending-canonicalizations foreign-declarations emit-trace-info block-compilation line-number-database-size always-bound-to-procedure block-globals make-block-variable-literal block-variable-literal? block-variable-literal-name target-heap-size target-stack-size valid-c-identifier? profiled-procedures target-initial-heap-size internal-bindings source-filename dump-nodes source-info->string default-default-target-heap-size default-default-target-stack-size verbose-mode original-program-size current-program-size line-number-database-2 foreign-lambda-stubs immutable-constants foreign-variables rest-parameters-promoted-to-vector inline-table inline-table-used constant-table constants-used mutable-constants broken-constant-nodes inline-substitutions-enabled loop-lambda-names expand-profile-lambda profile-lambda-list profile-lambda-index emit-profile expand-profile-lambda direct-call-ids foreign-type-table first-analysis callback-names disabled-warnings initialize-compiler canonicalize-expression expand-foreign-lambda update-line-number-database! scan-toplevel-assignments compiler-warning import-table use-import-table compiler-macro-table compiler-macros-enabled perform-cps-conversion analyze-expression simplifications perform-high-level-optimizations perform-pre-optimization! reorganize-recursive-bindings substitution-table simplify-named-call inline-max-size perform-closure-conversion prepare-for-code-generation compiler-source-file create-foreign-stub expand-foreign-lambda* data-declarations emit-control-file-item expand-foreign-primitive process-declaration external-protos-first basic-literal? transform-direct-lambdas! expand-foreign-callback-lambda* debugging emit-unsafe-marker debugging-chicken bomb check-signature posq stringify symbolify build-lambda-list string->c-identifier c-ify-string words check-and-open-input-file close-checked-input-file fold-inner constant? collapsable-literal? immediate? canonicalize-begin-body extract-mutable-constants string->expr get get-all put! collect! count! get-line get-line-2 find-lambda-container display-analysis-database varnode qnode build-node-graph build-expression-tree fold-boolean inline-lambda-bindings match-node expression-has-side-effects? simple-lambda-node? compute-database-statistics print-program-statistics output gen gen-list pprint-expressions-to-file foreign-type-check estimate-foreign-result-size scan-used-variables scan-free-variables topological-sort print-version print-usage initialize-analysis-database export-list csc-control-file estimate-foreign-result-location-size unused-variables expand-foreign-callback-lambda default-optimization-passes default-optimization-passes-when-trying-harder units-used-by-default words-per-flonum disable-stack-overflow-checking parameter-limit eq-inline-operator optimizable-rest-argument-operators postponed-initforms membership-test-operators membership-unfold-limit valid-compiler-options valid-compiler-options-with-argument make-random-name final-foreign-type real-name-table real-name set-real-name! safe-globals-flag location-pointer-map literal-rewrite-hook lookup-exports-file undefine-shadowed-macros process-lambda-documentation emit-syntax-trace-info generate-code make-variable-list make-argument-list generate-foreign-stubs foreign-type-declaration process-custom-declaration do-lambda-lifting file-requirements emit-closure-info export-file-name foreign-argument-conversion foreign-result-conversion foreign-type-convert-argument foreign-type-convert-result big-fixnum?)(eval-when (compile eval) (match-error-control #:fail) )(include "tweaks")(define-inline (gensym-f-id) (gensym 'f_))(eval-when (eval) (define installation-home #f) (define default-target-heap-size #f) (define default-target-stack-size #f) )(eval-when (load) (define-foreign-variable installation-home c-string "C_INSTALL_SHARE_HOME") (define-foreign-variable default-target-heap-size int "C_DEFAULT_TARGET_HEAP_SIZE") (define-foreign-variable default-target-stack-size int "C_DEFAULT_TARGET_STACK_SIZE") )(define user-options-pass (make-parameter #f))(define user-read-pass (make-parameter #f))(define user-preprocessor-pass (make-parameter #f))(define user-pass (make-parameter #f))(define user-pass-2 (make-parameter #f))(define user-post-analysis-pass (make-parameter #f))(define-constant foreign-type-table-size 301)(define-constant analysis-database-size 3001)(define-constant default-line-number-database-size 997)(define-constant inline-table-size 301)(define-constant constant-table-size 301)(define-constant file-requirements-size 301)(define-constant real-name-table-size 997)(define-constant import-table-size 997)(define-constant default-inline-max-size 10);;; Global variables containing compilation parameters:(define unit-name #f)(define number-type 'generic)(define standard-bindings '())(define extended-bindings '())(define insert-timer-checks #t)(define used-units '())(define unsafe #f)(define always-bound '())(define always-bound-to-procedure '())(define foreign-declarations '())(define emit-trace-info #f)(define block-compilation #f)(define line-number-database-size default-line-number-database-size)(define target-heap-size #f)(define target-initial-heap-size #f)(define target-stack-size #f)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?