This commit is contained in:
Sam Caldwell 2017-10-27 18:07:17 -04:00
parent aa5bcee3eb
commit 6f553c6130
2 changed files with 123 additions and 58 deletions

View File

@ -9,18 +9,4 @@
(on (asserted (list "hello"))
(printf "hello\n")))
(check-type 1 : Int)
(check-type (let-field x : Int 5 nil) : )
(check-type (let-field x : Int 5 nil) :2 )
(check-type (let-field x : Int 5 nil) :3 )
(check-type (tuple 1 2 3) : (Tuple Int Int Int))
(typecheck-fail (let-field x : Int 5
(let-field y : (Field Int) x nil))
#:with-msg "Keep your functions out of fields")
(check-type (tuple discard 1 (bind x Int)) : (Tuple Discard Int (Bind Int)))
(check-type (λ [(bind x Int) nil]) : (Case [ (Bind Int) (Facet )]))
(spawn (assert "hello"))

View File

@ -1,24 +1,28 @@
#lang turnstile
(provide #%module-begin
(provide (rename-out [syndicate:#%module-begin #%module-begin])
#%app
#%top-interaction
require
Int
let-field
;; Types
Int Tuple Bind Discard Case Facet Field
;; Statements
nil let-field let-function spawn dataspace facet set! begin stop
;; endpoints
assert on
;; expressions
tuple λ ref
;; values
#%datum
Field
nil
tuple Tuple
bind Bind
discard Discard
+ -
λ Case
Facet)
;; patterns
bind discard
;; primitives
+ - displayln
)
(require (rename-in racket/match [match-lambda match-lambda-]))
(require (prefix-in syndicate: syndicate/actor))
(require (prefix-in syndicate: (only-in syndicate/actor-lang #%module-begin)))
(module+ test
(require rackunit)
@ -52,7 +56,8 @@
(define-syntax-class prim-op
(pattern (~or (~literal +)
(~literal -))))
(~literal -)
(~literal displayln))))
(define-syntax-class stmt
#:datum-literals (:
@ -63,10 +68,11 @@
spawn
dataspace
stop
facet)
facet
nil)
(pattern (~or (begin seq:stmt ...)
(e1:exp e2:exp)
nil ;; TODO - remove, only for making some initial examples
;; nil ;; TODO - remove, only for making some initial examples
(let-field [x:id : τ:type e:exp] lf-body:stmt)
(let-function [f:id : τ:type e:exp] let-fun-body:stmt)
(set! x:id e:exp)
@ -109,22 +115,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Statements
#;(define-syntax-class stmt
#:datum-literals (spawn
dataspace
stop
facet)
(pattern (~or (begin seq:stmt ...)
(e1:exp e2:exp)
nil ;; TODO - remove, only for making some initial examples
(let-field [x:id : τ:type e:exp] lf-body:stmt)
(let-function [f:id : τ:type e:exp] let-fun-body:stmt)
(set! x:id e:exp)
(spawn τ:type s:stmt)
(dataspace τ:type nested:stmt ...)
(stop x:id s:stmt)
(facet x:id ep:endpoint ...))))
(define-typed-syntax (set! x:id e:exp)
[ e e- τ]
[ x x- (Field τ-x)]
@ -132,6 +122,41 @@
-------------------------
[ (x- e-) ( : ) ( :2 ) ( :3 )])
(define-typed-syntax (stop facet-name:id cont:stmt)
[ facet-name facet-name- Facet]
[ cont cont- ( : τ-i) ( :2 τ-o) ( :3 τ-a)]
--------------------------------------------------
[ (syndicate:stop facet-name- cont-) ( : τ-i) ( :2 τ-o) ( :3 τ-a)])
(define-typed-syntax (facet name:id ep:endpoint ...)
[[name name- : Facet] ep ep- ( : τ-i) ( :2 τ-o) ( :3 τ-a)] ...
--------------------------------------------------------------
;; name NOT name- here because I get an error that way.
;; Since name is just an identifier I think it's OK?
[ (syndicate:react (let- ([name (syndicate:current-facet-id)]) ep- ...))
( : (U τ-i ...)) ( :2 (U τ-o ...)) ( :3 (U τ-a ...))])
(define-typed-syntax (dataspace τ-c:type s:stmt ...)
#:fail-unless (flat-type? #'τ-c.norm) "Communication type must be first-order"
[ (spawn s) (_ s-) _] ...
#:with τ-i (strip-inbound #'τ-c.norm)
#:with τ-o (strip-outbound #'τ-c.norm)
#:with τ-relay (relay-interests #'τ-c.norm)
----------------------------------------------
[ (syndicate:dataspace s- ...) ( : τ-i) ( :2 (U τ-o τ-relay)) ( :3 )])
(define-for-syntax (strip-inbound t)
(syntax-parse t
[_ #']))
(define-for-syntax (strip-outbound t)
(syntax-parse t
[_ #']))
(define-for-syntax (relay-interests t)
(syntax-parse t
[_ #']))
(define-typed-syntax (spawn τ-c:type s:stmt)
#:fail-unless (flat-type? #'τ-c.norm) "Communication type must be first-order"
[ s s- ( : τ-i) ( :2 τ-o) ( :3 τ-a)]
@ -140,14 +165,14 @@
;; TODO: (Actor τ-a) <: (Actor τ-c)
;; TODO: project-safe(strip-?(τ-o) ∩ τ-c, τ-i)
----------------------------------------------
[ (syndicate:spawn s-) ( : ) ( :2 ) ( τ-c)])
[ (syndicate:spawn s-) ( : ) ( :2 ) ( :3 τ-c)])
(define-typed-syntax (let-field x:id (~datum :) τ:type e:expr body:expr)
[ e e- ( : τ.norm)]
[[x x- : (Field τ)] body body- ( : τ-body) ( :2 τ-body2) ( :3 τ-body3)]
#:fail-unless (flat-type? #'τ.norm) "Keep your functions out of fields"
------------------------------------------------------------------------
[ (begin- (syndicate:field [x- e-]) body-) ( : τ-body) ( :2 τ-body2) ( :3 τ-body3)])
[ (let () (syndicate:field [x- e-]) body-) ( : τ-body) ( :2 τ-body2) ( :3 τ-body3)])
(define-typed-syntax (let-function f:id (~datum :) τ:type e:expr body:expr)
[ e e- ( : τ.norm)]
@ -177,6 +202,22 @@
[(~Field _) #f]
[_ #t]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Endpoints
#;(define-syntax-class endpoint
#:datum-literals (on start stop)
(pattern (~or (on ed:event-desc s:stmt)
(assert e:exp))))
(define-typed-syntax (on ed:event-desc s:stmt)
-------------------
[ (void-) ( : ) ( :2 ) ( :3 )])
(define-typed-syntax (assert e:exp)
-------------------
[ (void-) ( : ) ( :2 ) ( :3 )])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Expressions
@ -233,6 +274,12 @@
(define-primop + ( Int Int Int))
(define-primop - ( Int Int Int))
(define-typed-syntax (displayln e:exp)
[ e e- τ]
---------------
[ (displayln- e-) ])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Basic Values
@ -251,20 +298,52 @@
;; Tests
(module+ test
(check-true (void? ((λ [(bind x Int) nil]) 1))))
(check-type 1 : Int)
(check-type (let-field x : Int 5 nil) : )
(check-type (let-field x : Int 5 nil) :2 )
(check-type (let-field x : Int 5 nil) :3 )
(check-type (tuple 1 2 3) : (Tuple Int Int Int))
(typecheck-fail (let-field x : Int 5
(let-field y : (Field Int) x nil))
#:with-msg "Keep your functions out of fields")
(check-type (tuple discard 1 (bind x Int)) : (Tuple Discard Int (Bind Int)))
(check-type (λ [(bind x Int) (begin)]) : (Case [ (Bind Int) (Facet )]))
(check-true (void? ((λ [(bind x Int) (begin)]) 1))))
(define bank-account
#'(facet account
(let-field [balance : Int 0]
(begin (assert (list "balance" (ref balance)))
(on (asserted (list "deposit" (bind amount Int)))
;; this bit isn't valid because `assert` is not a statement
(begin (assert (tuple "balance" (ref balance)))
(on (asserted (tuple "deposit" (bind amount Int)))
(set! balance (+ (ref balance) amount)))))))
(define client
#'(facet client
(let-field [deposits : Int 3]
(on (asserted (list "balance" (bind amount Int)))
(assert (list "deposit" 100))
(set! deposits (- (ref deposits) 1))
(if (= (ref deposits) 0)
(stop client (begin)))))))
#'(spawn
(let-field [deposits : Int 3]
(facet client
(on (asserted (tuple "balance" (bind amount Int)))
;; this bit isn't valid because `assert` is not a statement
(begin (assert (tuple "deposit" 100))
(set! deposits (- (ref deposits) 1))
;; also `if` isn't in the grammar
(if (= (ref deposits) 0)
(stop client (begin))
(begin))))))))
(require rackunit)
(define-syntax (test-syntax-class stx)
(syntax-parse stx
[(_ e class:id)
#`(let ()
(define-syntax (test-result stx)
(syntax-parse e
[(~var _ class) #'#t]
[_ #'#f]))
(test-result))]))