Better types #15

Merged
alex-eg merged 27 commits from better-types into main 2025-10-30 16:05:44 +01:00
Showing only changes of commit 4273d7bfd4 - Show all commits

View File

@@ -53,43 +53,29 @@
(string->symbol
pkulev commented 2025-10-28 17:50:25 +01:00 (Migrated from github.com)
Review

Looks like this code can be extracted into a function with a slight readability boost (if named properly).

Something like this:

(define (squeeze-typleton type-list)
  (if (and (list? (car type-list))
    ...
Looks like this code can be extracted into a function with a slight readability boost (if named properly). Something like this: ```scheme (define (squeeze-typleton type-list) (if (and (list? (car type-list)) ... ```
pkulev commented 2025-10-28 17:52:13 +01:00 (Migrated from github.com)
Review

And here we can reuse it

         `(%array ,(walk-type (squeeze-typleton array-type)))
And here we can reuse it ```suggestion `(%array ,(walk-type (squeeze-typleton array-type))) ```
pkulev commented 2025-10-28 17:59:15 +01:00 (Migrated from github.com)
Review

That function is a little complex, would be nice to have unit tests for it.

Also could fold-right be replaced with flatten?

  (if (atom? type) (atom-to-fmt-c type)
      (flatten
       (tree-map atom-to-fmt-c
                 (flatten
                             (list-join (reverse (list-split type '*))
                                        '(*)))))))

Gosh it's fucking torture to write and edit lisp snippets on github.

That function is a little complex, would be nice to have unit tests for it. Also could fold-right be replaced with flatten? ```suggestion (if (atom? type) (atom-to-fmt-c type) (flatten (tree-map atom-to-fmt-c (flatten (list-join (reverse (list-split type '*)) '(*))))))) ``` Gosh it's fucking torture to write and edit lisp snippets on github.
pkulev commented 2025-10-28 18:01:39 +01:00 (Migrated from github.com)
Review
;;; TODO: isn't there a better way?
```suggestion ;;; TODO: isn't there a better way? ```
pkulev commented 2025-10-29 14:53:09 +01:00 (Migrated from github.com)
Review

Oh! That's similar

          ((var . type) (append (list (walk-type (squeeze-typleton-or-maybe-better-name-huh type))...
Oh! That's similar ```suggestion ((var . type) (append (list (walk-type (squeeze-typleton-or-maybe-better-name-huh type))... ```
alex-eg commented 2025-10-30 00:08:18 +01:00 (Migrated from github.com)
Review

Yes. Qualifies as self-harm.

Yes. Qualifies as self-harm.
alex-eg commented 2025-10-30 00:08:30 +01:00 (Migrated from github.com)
Review

🤯

🤯
alex-eg commented 2025-10-30 00:08:47 +01:00 (Migrated from github.com)
Review

🤯

🤯
alex-eg commented 2025-10-30 09:52:56 +01:00 (Migrated from github.com)
Review

Also could fold-right be replaced with flatten?

In general, it could not:

(fold-right append (list) '(((1 2)) (3 4) (5 6)))
; ((1 2) 3 4 5 6)

However, here we can, I think. There shouldn't be any meaningful nesting in cv* type chains.

That function is a little complex, would be nice to have unit tests for it.

It's implicitly tested via all walk-type tests. However, I agree that it would be nice to have some test specifically for this function.

>Also could fold-right be replaced with flatten? In general, it could not: ``` (fold-right append (list) '(((1 2)) (3 4) (5 6))) ; ((1 2) 3 4 5 6) ``` However, here we can, I think. There shouldn't be any meaningful nesting in `cv*` type chains. > That function is a little complex, would be nice to have unit tests for it. It's implicitly tested via all `walk-type` tests. However, I agree that it would be nice to have some test specifically for this function.
(fmt #f (cadr form) (car form)))))
(define (walk-generic form acc)
(cond
((null? form) (cons '() acc))
(define (walk-generic-toplevel form)
(cond ((atom? form) (atom-to-fmt-c form))
((list? form) (map walk-generic-toplevel form))
(else (error "Malformed form " form))))
;; vector, e.g. {}-initializer
((vector? form)
(cons
(define (field-access-form? form)
(and (symbol? (car form))
(char=? #\. (string-ref (symbol->string (car form)) 0))))
(define (walk-expr form)
(match form
((? vector?)
(list->vector
(car (walk-generic (vector->list form) (list))))
acc))
;; atom (hopefully)
((not (list? form)) (cons (atom-to-fmt-c form) acc))
;; another special case - field access
((and (symbol? (car form))
(char=? #\. (string-ref (symbol->string (car form)) 0)))
(cons (make-field-access form) acc))
;; variable declaration inside function
((eq? (car form) 'var)
(cons (walk-var form) acc))
;; (cast expr type) -> (%cast type expr)
((eq? (car form) 'cast)
(cons (list '%cast
(walk-type (drop form 2))
(car (walk-generic (second form) (list))))
acc))
;; toplevel, or a start of a regular list form
(else
(cons (fold-right
walk-generic
(list)
form)
acc))))
(walk-expr (vector->list form))))
((? atom?)
(atom-to-fmt-c form))
((? field-access-form?)
(make-field-access form))
(('var . _) (walk-var form))
(('cast expr type) (list '%cast
(walk-type type)
(walk-expr expr)))
(else (map walk-expr form))))
(define (walk-var form)
;; (var a int) -> (%var int a)
@@ -97,14 +83,13 @@
;; (var b [const char 512]) -> (%var (%array (const char) 512) b)
;; note: [...] is actually (¤ ...) after reading
;; (var c (fn ((int) (float)) void)) -> (%var (%fun void ((int) (float))) c)
(append
(list '%var)
(list (walk-type (flatten (third form))))
(list (atom-to-fmt-c (second form)))
(if (null? (drop form 3))
`(%var
,(walk-type (flatten (third form)))
,(atom-to-fmt-c (second form))
.
,(if (null? (drop form 3))
(list)
(car (walk-generic (drop form 3) (list)))) ; optional init expression
(walk-expr (drop form 3))) ; optional init expression
))
(define (walk-type form)
@@ -131,15 +116,11 @@
;; Special case: nested structs/unions
(('struct ((field-names field-types) ...) . attrs)
(append `(struct ,(process-struct-fields field-names field-types))
(if (null? attrs)
(list)
(list (map atom-to-fmt-c attrs)))))
`(struct ,(process-struct-fields field-names field-types)
. ,(map atom-to-fmt-c attrs)))
(('union ((field-names field-types) ...) . attrs)
(append `(union ,(process-struct-fields field-names field-types))
(if (null? attrs)
(list)
(list (map atom-to-fmt-c attrs)))))
`(union ,(process-struct-fields field-names field-types)
. ,(map atom-to-fmt-c attrs)))
(else
(type-convert-to-c form))))
@@ -160,10 +141,10 @@
(('fn name args ret-type . maybe-body)
`(%fun
,(walk-type ret-type)
,(car (walk-generic name (list)))
,(atom-to-fmt-c name)
,(walk-arglist args)
.
,maybe-body))))
,(walk-expr maybe-body)))))
;;; Todo: isn't there a better way?
(define (is-probably-type form)
@@ -193,19 +174,12 @@
(list (walk-type var))))))
form))
(define (normalize-fn-form form)
(define (walk-function form)
;; (fn ret-type name arglist body) -> normal function
;; (fn ret-type name arglist) -> prototype
(if (>= (length form) 5)
(walk-fn-def form)
(cons 'prototype (cdr (walk-fn-def form)))))
(define (walk-function form static)
(if static
(walk-generic (list 'static (normalize-fn-form form))
(list))
(walk-generic (normalize-fn-form (cdr form))
(list))))
(cons '%prototype (cdr (walk-fn-def form)))))
(define (process-struct-fields names types)
(zip (map walk-type types) (map atom-to-fmt-c names)))
@@ -213,45 +187,52 @@
(define (walk-struct form)
(match form
((type name ((field-names field-types) ...) . attrs)
(list (append `(,type ,(atom-to-fmt-c name)
,(process-struct-fields field-names field-types))
(if (null? attrs)
(list)
(list (map atom-to-fmt-c attrs))))))
`(,type ,(atom-to-fmt-c name)
,(process-struct-fields field-names field-types)
. ,(map atom-to-fmt-c attrs)))
(else (error "Malformed aggregate definition " form))))
(define (walk-extern form)
(case (cadr form)
((fn)
(list (cons 'extern (walk-function form #f))))
((var)
(list (cons 'extern (walk-generic (cdr form) (list)))))
(match form
(('fn . _)
;; extern function?.. What
(list 'extern (walk-function form)))
(('var . _)
(list 'extern (walk-var form)))
(else (error "Extern what?"))))
(define (walk-public form)
(case (cadr form)
((fn)
(walk-function form #f))
((var)
(walk-generic (walk-var (cdr form)) (list)))
((define defmacro import include struct typedef union var)
(match form
(('fn . _)
(walk-function form))
(('var . _)
(walk-var form))
((or ('define . _)
('defmacro . _)
('import . _)
('include . _)
('struct . _)
('union . _)
('typedef . _))
;; ignore here, used in generating public interface
(process-toplevel-form (cdr form)))
(process-toplevel-form form))
(else
(error "Pub what?" (cadr form)))))
(define (process-toplevel-form form)
;; todo: rewrite to match
;; for some reason should return list in a list; TODO: rewrite
(case (car form)
((fn) (walk-function form #t))
((var) (walk-generic (list 'static (walk-var form)) (list)))
((extern) (walk-extern form))
((pub) (walk-public form))
((struct union) (walk-struct form))
(else (walk-generic form (list)))))
(match form
(('fn . _) (list 'static (walk-function form)))
(('var . _) (list 'static (walk-var form)))
(('extern . rest) (walk-extern rest))
(('pub . rest) (walk-public rest))
((or ('struct . _)
('union . _)) (walk-struct form))
(else (walk-expr form))))
(define (emit-c sex-forms)
(for-each (lambda (form)
(fmt #t (c-expr (car (process-toplevel-form form))) nl))
(fmt #t (c-expr (process-toplevel-form form)) nl))
sex-forms))