implement basic implicit expression generation
This commit is contained in:
parent
983872d898
commit
e6a3af8232
|
@ -93,8 +93,10 @@
|
||||||
[(string) $1]
|
[(string) $1]
|
||||||
[(boolean) $1]
|
[(boolean) $1]
|
||||||
[(identifier) $1]
|
[(identifier) $1]
|
||||||
|
[(lbracket rbracket) '(array)]
|
||||||
[(lbracket apply-args rbracket) (cons 'array $2)]
|
[(lbracket apply-args rbracket) (cons 'array $2)]
|
||||||
[(exp dot identifier) (list 'get $1 $3)]
|
[(exp dot identifier) (list 'get $1 $3)]
|
||||||
|
[(exp lparen rparen) `(apply ,$1)]
|
||||||
[(exp lparen apply-args rparen) `(apply ,$1 ,@$3)]
|
[(exp lparen apply-args rparen) `(apply ,$1 ,@$3)]
|
||||||
[(exp * exp) (list '* $1 $3)]
|
[(exp * exp) (list '* $1 $3)]
|
||||||
[(exp / exp) (list '/ $1 $3)]
|
[(exp / exp) (list '/ $1 $3)]
|
||||||
|
@ -142,12 +144,20 @@
|
||||||
;; - (apply func args ...): applies a function
|
;; - (apply func args ...): applies a function
|
||||||
;; - (array args ...): constructs array
|
;; - (array args ...): constructs array
|
||||||
;; - (get obj attr): references an attribute on an object
|
;; - (get obj attr): references an attribute on an object
|
||||||
|
;;
|
||||||
|
;; stuff that cannot be constructed in user code
|
||||||
|
;; - (get-builtin obj attr): get a built-in attribute (magic stuff that's hidden from the user)
|
||||||
|
;;
|
||||||
;; primitive types: boolean, number, string, symbol (identifier)
|
;; primitive types: boolean, number, string, symbol (identifier)
|
||||||
|
;;
|
||||||
|
;; known issues: you can't do eg 5.to_s it has to be (5).to_s
|
||||||
|
;; i don't believe this breaks spec but idk
|
||||||
|
;; also i have no idea how to fix it
|
||||||
|
|
||||||
; (define test2 "true and 'a' != 'b' ? -1 + ~bits : ('hello' + 'world').substring(2, 3)")
|
; (define test2 "true and 'a' != 'b' ? -1 + ~bits : ('hello' + 'world').substring(2, 3)")
|
||||||
;; => '(if (and #t (!= "a" "b"))
|
;; => '(if (and #t (!= "a" "b"))
|
||||||
;; (+ -1 (~ bits))
|
;; (+ -1 (~ bits))
|
||||||
;; (apply (get (+ "hello" "world") substring) 2 3))
|
;; (apply (get (+ "hello" "world") substring) 2 3))
|
||||||
|
|
||||||
; (let ([input (open-input-string test2)])
|
; (let ([input (open-input-string "awoo . to_s([1, 2,3])")])
|
||||||
; (kaitai-parser (lambda () (kaitai-lexer input))))
|
; (kaitai-parser (lambda () (kaitai-lexer input))))
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
|
|
||||||
(require (for-syntax racket/base racket/list racket/match racket/pretty
|
(require (for-syntax racket/base racket/list racket/match racket/pretty racket/set
|
||||||
"expr.rkt"))
|
"expr.rkt"))
|
||||||
(provide (rename-out [kaitai:module-begin #%module-begin])
|
(provide (rename-out [kaitai:module-begin #%module-begin])
|
||||||
(except-out (all-from-out racket/base) #%module-begin))
|
(except-out (all-from-out racket/base) #%module-begin))
|
||||||
|
|
||||||
;; builtin types
|
(define-for-syntax kaitai:reserved (set '_io '_parent '_root))
|
||||||
|
|
||||||
;; utility to concat symbol stuff
|
;; utility to concat symbol stuff
|
||||||
(define-for-syntax (sym+ . args)
|
(define-for-syntax (sym+ . args)
|
||||||
|
@ -25,9 +25,32 @@
|
||||||
;; helper for types meta lookup
|
;; helper for types meta lookup
|
||||||
(define-for-syntax (get-id-seq top given-id)
|
(define-for-syntax (get-id-seq top given-id)
|
||||||
(define id-sym (get-id top given-id))
|
(define id-sym (get-id top given-id))
|
||||||
|
(when (set-member? kaitai:reserved (string->symbol id-sym))
|
||||||
|
(raise-syntax-error #f "reserved id" id-sym))
|
||||||
(define seq (hash-ref top "seq" (make-rse "form must have a seq element")))
|
(define seq (hash-ref top "seq" (make-rse "form must have a seq element")))
|
||||||
(values id-sym seq))
|
(values id-sym seq))
|
||||||
|
|
||||||
|
;; everything is an object (uwu)
|
||||||
|
;; besides kaitai-expr-lang accessible things each object also has a magic secret node with its
|
||||||
|
;; implicit properties
|
||||||
|
;; magic properties:
|
||||||
|
;; - start: Nat
|
||||||
|
;; - length: Nat
|
||||||
|
;;
|
||||||
|
;; let the base type be KaitaiType. everything is KaitaiType and all KaitaiTypes have the above
|
||||||
|
;; magic properties
|
||||||
|
;; user-defined types extend KaitaiType
|
||||||
|
;; primitive types also extend KaitaiType, besides having the kaitai-builtin functions available
|
||||||
|
;; but evaluating a primitive object directly results in the value of the object
|
||||||
|
;; eg: if example is bound to the integer 5
|
||||||
|
;; - '(get example to_s): "5"
|
||||||
|
;; - 'example: 5
|
||||||
|
;; - '(get-builtin example start): some integer
|
||||||
|
;; some magic functions will evaluate the function applied to its object whether you actually apply
|
||||||
|
;; or not (eg to_s) because kaitai is really wacky about this and doesn't require parens if it takes
|
||||||
|
;; no arguments (even though it does, there's an implicit object argument)
|
||||||
|
;; so '(get example to_s) is equivalent to '(apply (get example to_s))
|
||||||
|
|
||||||
;; idk yet
|
;; idk yet
|
||||||
(define-for-syntax (kaitai:process-ty defn [given-id #f])
|
(define-for-syntax (kaitai:process-ty defn [given-id #f])
|
||||||
(define (primitive-size prim-ty)
|
(define (primitive-size prim-ty)
|
||||||
|
@ -42,9 +65,10 @@
|
||||||
(for ([(name subty) (in-hash (hash-ref defn "types" (hash)))])
|
(for ([(name subty) (in-hash (hash-ref defn "types" (hash)))])
|
||||||
(kaitai:process-ty subty name))
|
(kaitai:process-ty subty name))
|
||||||
|
|
||||||
(struct context [io-pos] #:transparent)
|
(struct context [code io-pos] #:transparent)
|
||||||
|
|
||||||
(for/fold ([ctx (context 0)]) ([seq (in-list seqs)])
|
(define ctx
|
||||||
|
(for/fold ([ctx (context (hash) 0)]) ([seq (in-list seqs)])
|
||||||
; (printf "seq: ~a\n" seq)
|
; (printf "seq: ~a\n" seq)
|
||||||
|
|
||||||
(define seq-id (hash-ref seq "id" (make-rse "seq item has no id")))
|
(define seq-id (hash-ref seq "id" (make-rse "seq item has no id")))
|
||||||
|
@ -58,18 +82,22 @@
|
||||||
[(hash-has-key? seq "type") (primitive-size (hash-ref seq "type"))]
|
[(hash-has-key? seq "type") (primitive-size (hash-ref seq "type"))]
|
||||||
[else (raise-syntax-error #f "seq has unsolvable size" seq)]))
|
[else (raise-syntax-error #f "seq has unsolvable size" seq)]))
|
||||||
|
|
||||||
(define next-pos `(+ ,(context-io-pos ctx) ,size-expr))
|
(define pos (context-io-pos ctx))
|
||||||
|
(define next-pos `(+ ,pos ,size-expr))
|
||||||
|
(printf "~a: ~a to ~a\n" seq-id pos next-pos)
|
||||||
|
(define next-code
|
||||||
|
(hash-set (context-code ctx) seq-id
|
||||||
|
#`(read-io #,pos #,next-pos)))
|
||||||
|
|
||||||
(printf "~a: ~a to ~a\n" seq-id (context-io-pos ctx) next-pos)
|
(context next-code next-pos)))
|
||||||
|
|
||||||
(context next-pos))
|
#`(define #,(string->symbol id)
|
||||||
|
#,(for/hash ([(id code) (context-code ctx)])
|
||||||
(void))
|
(values (string->symbol id) #`(lambda () #,code)))))
|
||||||
|
|
||||||
;; top level process
|
;; top level process
|
||||||
(define-for-syntax (kaitai:process defn)
|
(define-for-syntax (kaitai:process defn)
|
||||||
(kaitai:process-ty defn)
|
(kaitai:process-ty defn))
|
||||||
(void))
|
|
||||||
|
|
||||||
;; runtime lib
|
;; runtime lib
|
||||||
|
|
||||||
|
@ -88,7 +116,8 @@
|
||||||
|
|
||||||
(define-syntax (kaitai:module-begin stx)
|
(define-syntax (kaitai:module-begin stx)
|
||||||
(define body (second (syntax-e stx)))
|
(define body (second (syntax-e stx)))
|
||||||
(kaitai:process (syntax->datum body))
|
(define top-level (kaitai:process (syntax->datum body)))
|
||||||
|
(pretty-write (syntax->datum top-level))
|
||||||
#`(#%module-begin
|
#`(#%module-begin
|
||||||
(module+ main
|
(module+ main
|
||||||
(kaitai:uwu))))
|
(kaitai:uwu))))
|
||||||
|
|
Loading…
Reference in New Issue