- (when (not (eqv? 'stack (ast-type (cadr e))))
- (error #f "expected stack value"))
- (let* ([stack-expr (cadr e)]
- [stack-body (caddr stack-expr)]
- [stack-type (cadr stack-expr)])
-
- (codegen-expr stack-body si env)
- (let ([index (cadr tor)]
- [products 2]
- [to-traverse (list-head products index)]
- [offset (fold-left
- (lambda (acc t) (+ acc (type-size t)))
- wordsize ; skip tag in first word
- to-traverse)])
- 3
- )))
+ (let* ([res (codegen-expr (cadr e) si env)]
+ [info (cadr tor)]
+ [index (caddr info)]
+ [type (car info)]
+ [sum (cadr info)])
+ (when (not (stack-expr? res))
+ (error #f "codegened something that wasn't a stack expression"))
+ ;TODO handle stack types
+ (emit "movq ~a(%rbp), %rax"
+ (- si (data-product-offset (env-data-layouts env) type sum index)))))
+
+ (define (codegen-constructor tor)
+ (let* ([info (cadr tor)]
+ [type (car info)]
+ [sum (cadr info)]
+ [constructor (car e)]
+
+ [args (cdr e)]
+
+ [tag (data-sum-tag (env-data-layouts env)
+ type
+ sum)]
+
+ [insert-product
+ (lambda (expr i)
+ (let ([res (codegen-expr expr si env)]
+ [stack-offset (- si (data-product-offset (env-data-layouts env)
+ type sum
+ i))])
+ (if (stack-expr? res)
+ (error #f "todo: handle stack-exprs in stack exprs")
+ (emit "movq %rax, ~a(%rbp)" stack-offset))))])
+
+ ; emit the tag
+ (emit "movq $~a, ~a(%rbp)" tag si)
+
+ (for-each insert-product args (range 0 (length args)))
+ (type-size (env-data-layouts env) type)))