#lang plai-typed

(require "python-core-syntax.rkt"
         "python-objects.rkt"
         "python-desugar.rkt")

#|

Here is a suggestion for how to implement shared runtime functionality -
write it as core expression forms and use python-lib to wrap your
desugared expressions in an environment that will contain useful
bindings.  For example, this sample library binds `print` to a function
that calls the primitive `print`.

|#

(define-type-alias Lib (CExp -> CExp))


(define print-lambda
  (CFunc (list 'to-print)
         (CPrim1 'print (call-method (CId 'to-print) (str->cval "%str") empty))))

(define assert-true-lambda
  (CFunc (list 'check-true)
         (CIf (CId 'check-true) (%to-object (VTrue)) (CError (%to-object (VStr "Assert failed"))))))

(define true-val
  (%to-object (VTrue)))

(define false-val
  (%to-object (VFalse)))

(define len-lambda
  (CFunc (list 'long-thing)
         (CGetField (CId 'long-thing)
                    (%to-object (VStr "%len")))))

(define-type LibBinding
  [bind (left : symbol) (right : CExp)])

(define lib-functions
  (list (bind 'print print-lambda)
        (bind 'True true-val)
        (bind '___assertTrue assert-true-lambda)
        (bind 'False false-val)
        (bind 'len len-lambda)

))

(define (python-lib expr)
  (local [(define (python-lib/recur libs)
            (cond [(empty? libs) expr]
                  [(cons? libs)
                   (type-case LibBinding (first libs)
                     (bind (name value)
                           (CLet name value
                                 (python-lib/recur (rest libs)))))]))]
    (python-lib/recur lib-functions)))




Here is a suggestion for how to implement shared runtime functionality -
write it as core expression forms and use python-lib to wrap your
desugared expressions in an environment that will contain useful
bindings.  For example, this sample library binds `print` to a function
that calls the primitive `print`.


#lang plai-typed

(require "python-core-syntax.rkt"
         "python-objects.rkt"
         "python-desugar.rkt")


(define-type-alias Lib (CExp -> CExp))


(define print-lambda
  (CFunc (list 'to-print)
         (CPrim1 'print (call-method (CId 'to-print) (str->cval "%str") empty))))

(define assert-true-lambda
  (CFunc (list 'check-true)
         (CIf (CId 'check-true) (%to-object (VTrue)) (CError (%to-object (VStr "Assert failed"))))))

(define true-val
  (%to-object (VTrue)))

(define false-val
  (%to-object (VFalse)))

(define len-lambda
  (CFunc (list 'long-thing)
         (CGetField (CId 'long-thing)
                    (%to-object (VStr "%len")))))

(define-type LibBinding
  [bind (left : symbol) (right : CExp)])

(define lib-functions
  (list (bind 'print print-lambda)
        (bind 'True true-val)
        (bind '___assertTrue assert-true-lambda)
        (bind 'False false-val)
        (bind 'len len-lambda)

))

(define (python-lib expr)
  (local [(define (python-lib/recur libs)
            (cond [(empty? libs) expr]
                  [(cons? libs)
                   (type-case LibBinding (first libs)
                     (bind (name value)
                           (CLet name value
                                 (python-lib/recur (rest libs)))))]))]
    (python-lib/recur lib-functions)))

