jar-assem.scm 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. ; -*- Mode: Scheme; Syntax: Scheme; Package: Scheme; -*-
  2. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  3. ; This is file assem.scm.
  4. ;;;; Assembler
  5. ; Courtesy John Ramsdell.
  6. ; LAP syntax is much like that of the output of the disassembler except
  7. ; that global and set-global! take a symbol as an argument,
  8. ; statements may be labeled, and jump, jump-if-false, and make-cont
  9. ; may make a forward reference to a label to give an offset.
  10. ;
  11. ; Example: a translation of (define (dog) (if x 0 1)).
  12. ; (define dog
  13. ; (lap dog
  14. ; (check-nargs= 0)
  15. ; (global x)
  16. ; (jump-if-false 8)
  17. ; (literal '0)
  18. ; 8 (jump out)
  19. ; (literal '1)
  20. ; out (return)))
  21. (define-compilator '(lap syntax)
  22. (let ((op/closure (enum op closure)))
  23. (lambda (node cenv depth cont)
  24. (let ((exp (node-form node)))
  25. (deliver-value
  26. (instruction-with-template op/closure
  27. (compile-lap (cddr exp) cenv)
  28. (cadr exp))
  29. cont)))))
  30. ; Assembler label environments are simply a-lists.
  31. (define assembler-empty-env '())
  32. (define (assembler-extend sym val env) (cons (cons sym val) env))
  33. (define (assembler-lookup sym env)
  34. (let ((val (assv sym env)))
  35. (if (pair? val) (cdr val) #f)))
  36. (define (compile-lap instruction-list cenv)
  37. (assemble instruction-list
  38. assembler-empty-env
  39. cenv))
  40. ; ASSEMBLE returns a segment.
  41. (define (assemble instruction-list lenv cenv)
  42. (if (null? instruction-list)
  43. (sequentially)
  44. (let ((instr (car instruction-list))
  45. (instruction-list (cdr instruction-list)))
  46. (cond ((pair? instr) ; Instruction
  47. (sequentially
  48. (assemble-instruction instr lenv cenv)
  49. (assemble instruction-list
  50. lenv
  51. cenv)))
  52. ((or (symbol? instr) ; Label
  53. (number? instr))
  54. (let ((label (make-label)))
  55. (attach-label
  56. label
  57. (assemble instruction-list
  58. (assembler-extend instr label lenv)
  59. cenv))))
  60. (else (error "invalid instruction" instr))))))
  61. ; ASSEMBLE-INSTRUCTION returns a segment.
  62. (define (assemble-instruction instr lenv cenv)
  63. (let* ((opcode (name->enumerand (car instr) op))
  64. (arg-specs (vector-ref opcode-arg-specs opcode)))
  65. (cond ((or (not (pair? arg-specs))
  66. (not (pair? (cdr instr))))
  67. (instruction opcode))
  68. ((eq? (car arg-specs) 'index)
  69. (assemble-instruction-with-index opcode arg-specs (cdr instr) cenv))
  70. ((eq? (car arg-specs) 'offset)
  71. (let ((operand (cadr instr)))
  72. (apply instruction-using-label
  73. opcode
  74. (let ((probe (assembler-lookup operand lenv)))
  75. (if probe
  76. probe
  77. (begin
  78. (syntax-error "can't find forward label reference"
  79. operand)
  80. empty-segment)))
  81. (assemble-operands (cddr instr) arg-specs))))
  82. (else
  83. (apply instruction
  84. opcode
  85. (assemble-operands (cdr instr) arg-specs))))))
  86. ; <index> ::= (quote <datum>) | (lap <name> <instr>) | <name>
  87. (define (assemble-instruction-with-index opcode arg-specs operands cenv)
  88. (let ((operand (car operands)))
  89. (if (pair? operand)
  90. (case (car operand)
  91. ((quote)
  92. (instruction-with-literal opcode
  93. (cadr operand)))
  94. ((lap)
  95. (instruction-with-template opcode
  96. (compile-lap (cddr operand))
  97. (cadr operand)))
  98. (else
  99. (syntax-error "invalid index operand" operand)
  100. empty-segment))
  101. ;; Top-level variable reference
  102. (instruction-with-location
  103. opcode
  104. (get-location (lookup cenv operand)
  105. cenv
  106. operand
  107. value-type)))))
  108. (define (assemble-operands operands arg-specs)
  109. (map (lambda (operand arg-spec)
  110. (case arg-spec
  111. ((stob) (or (name->enumerand operand stob)
  112. (error "unknown stored object type" operand)))
  113. ((byte nargs) operand)
  114. (else (error "unknown operand type" operand arg-spec))))
  115. operands
  116. arg-specs))