fvm-as.scm 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. (import srfi-69)
  2. (define (make-opcode-table)
  3. (define opcodes
  4. '(sp ssp bp sbp pc rv srv
  5. imm
  6. ld8 ld16 ld32 ld
  7. st8 st16 st32 st
  8. dup pop swap over rot
  9. add sub div mul mod
  10. shr shl sar
  11. and or not
  12. bitand bitor xor invert
  13. gt lt ge le eq neq
  14. jmp jz jnz
  15. ret call syscall
  16. fadd fsub fmul fdiv
  17. fge fgt fle flt feq fneq
  18. fti itf
  19. exit))
  20. (define (assign-index opcodes idx ret)
  21. (if (null? opcodes)
  22. (reverse ret)
  23. (assign-index (cdr opcodes)
  24. (+ 1 idx)
  25. (cons (cons (car opcodes) idx) ret))))
  26. (alist->hash-table (assign-index opcodes 0 '())))
  27. (define opcode-table (make-opcode-table))
  28. (define pseudo-op-table
  29. (alist->hash-table
  30. '((rel . (pc add))
  31. (bpick . ((imm 8) mul bp add ld))
  32. (spick . ((imm 8) mul sp add ld))
  33. (bput . ((imm 8) mul bp add st))
  34. (sput . ((imm 8) mul bp add st)))))
  35. (define (is-pseudo-op? sym)
  36. (hash-table-ref/default pseudo-op-table sym #f))
  37. (define (is-op? sym)
  38. (hash-table-ref/default opcode-table sym #f))
  39. (define (is-tag? sym tag-table)
  40. (not (or (is-op? sym)
  41. (is-pseudo-op? sym)
  42. (not (hash-table-ref/default tag-table sym #f)))))
  43. (define (pseudo-op-pass prog)
  44. (define (add-to-prog oplist ret)
  45. (if (null? oplist)
  46. ret
  47. (add-to-prog (cdr oplist) (cons (car oplist) ret))))
  48. (define (impl prog ret)
  49. (if (null? prog)
  50. ret
  51. (let ((next-op (car prog)))
  52. (if (is-pseudo-op? next-op)
  53. (impl (cdr prog) (add-to-prog
  54. (hash-table-ref pseudo-op-table next-op)
  55. ret))
  56. (impl (cdr prog) (cons (car prog) ret))))))
  57. (reverse (impl prog '())))
  58. (define (is-tag-op? op)
  59. (and (list? op) (eq? 'tag (car op))))
  60. (define (is-imm-op? op)
  61. (and (list? op) (eq? 'imm (car op))))
  62. (define (tag-preprocess-pass prog)
  63. (define (is-local-tag? sym)
  64. (eq? #\. (string-ref (symbol->string sym) 0)))
  65. (define (compose-tag seg sym)
  66. (if (null? seg)
  67. sym
  68. (if (is-local-tag? sym)
  69. (string->symbol (string-append (symbol->string seg) (symbol->string sym)))
  70. sym)))
  71. (define (not-op? sym) (not (or (is-op? sym) (is-pseudo-op? sym))))
  72. (define (impl prog ret curseg)
  73. (if (null? prog)
  74. (reverse ret)
  75. (let ((cur (car prog)))
  76. (cond ((symbol? cur) (if (not-op? cur)
  77. (impl (cdr prog)
  78. (cons (compose-tag curseg cur) ret)
  79. curseg)
  80. (impl (cdr prog) (cons cur ret) curseg)))
  81. ((tag-op? cur) (if (local-tag? (cadr cur))
  82. (impl (cdr prog)
  83. (cons (list 'tag (compose-tag curseg (cadr cur))) ret)
  84. curseg)
  85. (impl (cdr prog) (cons cur ret) (cadr cur))))
  86. (else (impl (cdr prog) (cons cur ret) curseg))))))
  87. (impl prog '() '()))
  88. (define (calculate-tag-pos prog)
  89. (define (impl prog cur-pos tag-table)
  90. ;; TODO
  91. '())
  92. (define tag-table (make-hash-table))
  93. (impl prog 0 tag-table)
  94. tag-table)
  95. (define (tag-pass prog)
  96. ;; TODO
  97. '())
  98. (define (output-prog prog port)
  99. ;;
  100. '())
  101. (define (main input-file output-file)
  102. (define prog '())
  103. ;; read s-exp from file
  104. (with-input-from-file input-file
  105. (lambda (port) (set! prog (read port))))
  106. (set! prog (pseudo-op-pass prog))
  107. (set! prog (tag-preprocess-pass prog))
  108. (set! prog (tag-pass prog))
  109. (with-output-to-file output-file
  110. (lambda (port) (output-prog prog port))))