This repository has been archived on 2022-08-10. You can view files and clone it, but cannot push or open issues or pull requests.
chez-openbsd/s/base-lang.ss
2022-07-29 15:12:07 +02:00

261 lines
9.1 KiB
Scheme

;;; base-lang.ss
;;; Copyright 1984-2017 Cisco Systems, Inc.
;;;
;;; Licensed under the Apache License, Version 2.0 (the "License");
;;; you may not use this file except in compliance with the License.
;;; You may obtain a copy of the License at
;;;
;;; http://www.apache.org/licenses/LICENSE-2.0
;;;
;;; Unless required by applicable law or agreed to in writing, software
;;; distributed under the License is distributed on an "AS IS" BASIS,
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;;; See the License for the specific language governing permissions and
;;; limitations under the License.
(module (Lsrc Lsrc? Ltype Ltype? unparse-Ltype unparse-Lsrc count-Lsrc
lookup-primref primref? primref-name primref-level primref-flags primref-arity
sorry! make-preinfo preinfo? preinfo-lambda? preinfo-sexpr preinfo-sexpr-set! preinfo-src
make-preinfo-lambda preinfo-lambda-name preinfo-lambda-name-set! preinfo-lambda-flags preinfo-lambda-libspec
prelex? make-prelex prelex-name prelex-name-set! prelex-flags prelex-flags-set!
prelex-source prelex-operand prelex-operand-set! prelex-uname make-prelex*
target-fixnum? target-bignum?)
(module (lookup-primref primref? primref-name primref-flags primref-arity primref-level)
(include "primref.ss")
(define $lookup-primref
(lambda (level name)
(unless (symbol? name)
(sorry! 'lookup-primref "invalid primitive name ~s" name))
(or ($sgetprop name
(case level
[(2) '*prim2*]
[(3) '*prim3*]
[else ($oops 'lookup-primref "invalid level ~s" level)])
#f)
($oops 'lookup-primref "unrecognized prim ~s" name))))
(define-syntax lookup-primref
(lambda (x)
(define exact-integer?
(lambda (x)
(and (integer? x) (exact? x))))
(define constant-level&name
(lambda (level name)
(unless (and (exact-integer? level) (memv level '(2 3)))
(syntax-error x (format "invalid level ~s" level)))
(unless (symbol? name)
(syntax-error x (format "invalid name ~s" name)))
(let ([primref ($sgetprop name (if (eqv? level 2) '*prim2* '*prim3*) #f)])
(unless primref (syntax-error x (format "unknown primitive ~s" name)))
#`'#,primref)))
(define constant-name
(lambda (?level name)
(unless (symbol? name)
(syntax-error x (format "invalid name ~s" name)))
(let ([primref2 ($sgetprop name '*prim2* #f)]
[primref3 ($sgetprop name '*prim3* #f)])
(unless (and primref2 primref3)
(syntax-error x (format "unknown primitive ~s" name)))
#`(let ([level #,?level])
(case level
[(2) '#,primref2]
[(3) '#,primref3]
[else (sorry! 'lookup-primref "invalid level ~s" level)])))))
(syntax-case x (quote)
[(_ (quote level) (quote name))
(constant-level&name (datum level) (datum name))]
[(_ level (quote name))
(exact-integer? (datum level))
(constant-level&name (datum level) (datum name))]
[(_ ?level (quote name))
(constant-name #'?level (datum name))]
[(k ?level ?name) #'($lookup-primref ?level ?name)]))))
(module (prelex? make-prelex
prelex-name prelex-name-set!
prelex-flags prelex-flags-set!
prelex-source
prelex-operand prelex-operand-set!
prelex-uname)
(define-record-type prelex
(nongenerative #{prelex grpmhtzqa9bflxfggfu6pp-0})
(sealed #t)
(fields (mutable name) (mutable flags) source (mutable operand) (mutable $uname))
(protocol
(lambda (new)
(lambda (name flags source operand)
(new name flags source operand #f)))))
(define prelex-uname
(lambda (id)
(or (prelex-$uname id)
(let ([uname (gensym (symbol->string (prelex-name id)))])
(with-tc-mutex
(or (prelex-$uname id)
(begin (prelex-$uname-set! id uname) uname)))))))
(record-writer (record-type-descriptor prelex)
(lambda (x p wr)
(fprintf p "~s" (prelex-name x)))))
(define make-prelex*
(case-lambda
[() (make-prelex (gensym) 0 #f #f)]
[(name) (make-prelex name 0 #f #f)]))
; TODO: use sorry! where appropriate
(define sorry!
(lambda (who str . arg*)
($oops 'compiler-internal "~@[~a: ~]~?" who str arg*)))
(define maybe-source-object?
(lambda (x)
(or (eq? x #f) (source-object? x))))
(define rcd?
(lambda (x)
(or (record-constructor-descriptor? x) #t))) ; rcd should be restricted to rcd or ctrcd
(define exact-integer?
(lambda (x)
(and (integer? x) (exact? x))))
(meta-cond
[(= (constant fixnum-bits) (fixnum-width))
(define target-fixnum? fixnum?)
(define target-bignum? bignum?)]
[(< (constant fixnum-bits) (fixnum-width))
(define target-fixnum?
(lambda (x)
(and (fixnum? x)
(fx<= (constant most-negative-fixnum) x (constant most-positive-fixnum)))))
(define target-bignum?
(lambda (x)
(or (bignum? x)
(and (fixnum? x)
(not (fx<= (constant most-negative-fixnum) x (constant most-positive-fixnum)))))))]
[else
(define target-fixnum?
(lambda (x)
(or (fixnum? x)
(and (bignum? x)
(<= (constant most-negative-fixnum) x (constant most-positive-fixnum))))))
(define target-bignum?
(lambda (x)
(and (bignum? x)
(not (<= (constant most-negative-fixnum) x (constant most-positive-fixnum))))))])
(define $prelex?
(lambda (x)
(prelex? x)))
(define datum?
(lambda (x)
#t))
(define convention?
(lambda (x)
(symbol? x)))
(define-record-type preinfo
(nongenerative #{preinfo e23pkvo5btgapnzomqgegm-2})
(fields src (mutable sexpr))
(protocol
(lambda (new)
(case-lambda
[() (new #f #f)]
[(src) (new src #f)]
[(src sexpr) (new src sexpr)]))))
(define-record-type preinfo-lambda
(nongenerative #{preinfo-lambda e23pkvo5btgapnzomqgegm-4})
(parent preinfo)
(sealed #t)
(fields libspec (mutable name) flags)
(protocol
(lambda (pargs->new)
(case-lambda
[() ((pargs->new) #f #f 0)]
[(src) ((pargs->new src) #f #f 0)]
[(src sexpr) ((pargs->new src sexpr) #f #f 0)]
[(src sexpr libspec) ((pargs->new src sexpr) libspec #f 0)]
[(src sexpr libspec name) ((pargs->new src sexpr) libspec name 0)]
[(src sexpr libspec name flags) ((pargs->new src sexpr) libspec name flags)]))))
; language of foreign types
(define-language Ltype
(nongenerative-id #{Ltype czp82kxwe75y4e18-1})
(terminals
(exact-integer (bits))
($ftd (ftd)))
(Type (t)
(fp-integer bits)
(fp-unsigned bits)
(fp-void)
(fp-scheme-object)
(fp-u8*)
(fp-u16*)
(fp-u32*)
(fp-fixnum)
(fp-double-float)
(fp-single-float)
(fp-ftd ftd)
(fp-ftd& ftd)))
(define arity?
(lambda (x)
(or (eq? x #f)
(for-all fixnum? x))))
(define maybe-string? (lambda (x) (or (eq? x #f) (string? x))))
; source language used by the passes leading up to the compiler or interpreter
(define-language Lsrc
(nongenerative-id #{Lsrc czsa1fcfzdeh493n-3})
(terminals
(preinfo (preinfo))
($prelex (x))
(datum (d))
(record-type-descriptor (rtd))
(rcd (rcd))
(source-object (src))
(maybe-source-object (maybe-src))
(Ltype (arg-type result-type)) => unparse-Ltype
(fixnum (interface index flags level))
(arity (arity))
(box (box))
(convention (conv))
(maybe-string (name))
(symbol (sym type))
(primref (pr)))
(Expr (e body rtd-expr)
pr
(moi)
(ref maybe-src x) => x
(quote d)
(if e0 e1 e2)
(seq e0 e1)
(set! maybe-src x e) => (set! x e)
(pariah)
(case-lambda preinfo cl ...) => (case-lambda cl ...)
(letrec ([x* e*] ...) body)
(letrec* ([x* e*] ...) body)
(call preinfo e0 e1 ...) => (e0 e1 ...)
(record-type rtd e)
(record-cd rcd rtd-expr e)
(immutable-list (e* ...) e)
(record rtd rtd-expr e* ...)
(record-ref rtd type index e)
(record-set! rtd type index e1 e2)
(cte-optimization-loc box e)
(foreign (conv* ...) name e (arg-type* ...) result-type)
(fcallable (conv* ...) e (arg-type* ...) result-type)
(profile src) => (profile)
; used only in cpvalid
(cpvalid-defer e))
(CaseLambdaClause (cl)
(clause (x* ...) interface body) => [(x* ...) interface body]))
(define-language-node-counter count-Lsrc Lsrc)
)