Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

453 linhas
10KB

  1. ; interfaces.s - interface slot order and class conformance (E03-S06).
  2. ;
  3. ; Runs once after pass 1, when every interface, class, member, parameter, and
  4. ; implements row is recorded:
  5. ; assign_slots numbers each interface method in declaration order and
  6. ; stores it in C_MEM_SLOT, so later method tables and the MAP
  7. ; writer can use a stable slot without re-reading the source;
  8. ; check_interfaces
  9. ; verifies each class against every interface it implements.
  10. ; A satisfying method is public and has the same parameter
  11. ; count, parameter types, and return type. One method may
  12. ; satisfy identical requirements from several interfaces.
  13. ;
  14. ; Diagnostics are reported at the class declaration line, column 1:
  15. ; E130 no public method with a required name (missing, field, or private)
  16. ; E131 a public method with that name differs in its signature
  17. ; E132 the differing method matches the same-named requirement of another
  18. ; implemented interface, so the interfaces conflict
  19. ; E133 an implements entry names a class or program, not an interface
  20. ; An implements entry that names no declared type is left to pass 2, which
  21. ; already reports the unknown name at the source position.
  22. ;
  23. ; Everything is read through tb_get/tb_set, so this module runs in the normal
  24. ; bank-0 compiler state.
  25. .setcpu "6502"
  26. .include "../common/errors.inc"
  27. .include "../common/parser.inc"
  28. .import tb_get, tb_set, names_count
  29. .import diag_report, diag_line, diag_col, diag_arg1, diag_arg1_len
  30. .import name_get, name_out, name_out_len
  31. .export assign_slots, check_interfaces, find_method
  32. .segment "CODE"
  33. ; ------------------------------------------------------------- slot order
  34. ; Every interface method gets its declaration index: 0, 1, ... in source
  35. ; order. Interfaces cannot declare fields, so member rows are signatures.
  36. assign_slots:
  37. lda #$01
  38. sta as_id
  39. @next: lda as_id
  40. cmp names_count
  41. bcc :+
  42. rts
  43. : ldy as_id
  44. lda #C_TYPE_KIND
  45. jsr tb_get
  46. cmp #TYPE_INTERFACE
  47. beq :+
  48. jmp @skip
  49. : ldy as_id
  50. lda #C_TYPE_MFIRST
  51. jsr tb_get
  52. sta as_row
  53. ldy as_id
  54. lda #C_TYPE_MCOUNT
  55. jsr tb_get
  56. sta as_n
  57. lda #$00
  58. sta as_slot
  59. @slot: lda as_n
  60. beq @skip
  61. ldy as_row
  62. ldx as_slot
  63. lda #C_MEM_SLOT
  64. jsr tb_set
  65. inc as_row
  66. inc as_slot
  67. dec as_n
  68. bne @slot
  69. @skip: inc as_id
  70. bne @next
  71. rts
  72. ; ----------------------------------------------------------- conformance
  73. ; For each class in declaration order, walk its implements list in source
  74. ; order and each interface's signatures in slot order.
  75. check_interfaces:
  76. lda #$01
  77. sta cf_class
  78. @class: lda cf_class
  79. cmp names_count
  80. bcc :+
  81. jmp @done
  82. : ldy cf_class
  83. lda #C_TYPE_KIND
  84. jsr tb_get
  85. cmp #TYPE_CLASS
  86. beq :+
  87. jmp @cnext
  88. : ldy cf_class
  89. lda #C_TYPE_ICOUNT
  90. jsr tb_get
  91. bne :+
  92. jmp @cnext ; no implements list
  93. : sta cf_count
  94. ldy cf_class
  95. lda #C_TYPE_IFIRST
  96. jsr tb_get
  97. sta cf_row
  98. lda #$00
  99. sta cf_i
  100. @impl: lda cf_i
  101. cmp cf_count
  102. bcc :+
  103. jmp @cnext
  104. : ldy cf_row
  105. lda #C_IMPL_IFACE
  106. jsr tb_get
  107. sta cf_iface
  108. ldy cf_iface
  109. lda #C_TYPE_KIND
  110. jsr tb_get
  111. cmp #TYPE_INTERFACE
  112. beq @conform
  113. cmp #$00
  114. bne :+ ; unknown: pass 2 reports it
  115. jmp @inext
  116. :
  117. ldx cf_iface
  118. lda #E_IFC_NOT_INTERFACE
  119. jsr iface_err
  120. bcc :+
  121. jmp @stop
  122. :
  123. jmp @inext
  124. @conform:
  125. ldy cf_iface
  126. lda #C_TYPE_MFIRST
  127. jsr tb_get
  128. sta cf_req
  129. ldy cf_iface
  130. lda #C_TYPE_MCOUNT
  131. jsr tb_get
  132. sta cf_n
  133. @req: lda cf_n
  134. bne :+
  135. jmp @inext
  136. : ldy cf_req
  137. lda #C_MEM_NAME
  138. jsr tb_get
  139. sta cf_name
  140. lda cf_class
  141. ldx cf_name
  142. jsr find_method
  143. bcc @missing
  144. sty cf_method
  145. lda #C_MEM_FLAGS
  146. jsr tb_get
  147. and #MF_PRIVATE
  148. beq @sig
  149. jmp @missing ; private methods do not implement
  150. @sig: lda cf_req
  151. ldx cf_method
  152. jsr same_sig
  153. bcs @satisfied
  154. lda cf_method
  155. ldx cf_name
  156. jsr conflicting
  157. bcs @conflict
  158. ldx cf_name
  159. lda #E_IFC_SIGNATURE_MISMATCH
  160. jsr iface_err
  161. bcc :+
  162. jmp @stop
  163. :
  164. jmp @satisfied
  165. @conflict:
  166. ldx cf_name
  167. lda #E_IFC_SIGNATURE_CONFLICT
  168. jsr iface_err
  169. bcc :+
  170. jmp @stop
  171. :
  172. jmp @satisfied
  173. @missing:
  174. ldx cf_name
  175. lda #E_IFC_METHOD_MISSING
  176. jsr iface_err
  177. bcc :+
  178. jmp @stop
  179. :
  180. @satisfied:
  181. inc cf_req
  182. dec cf_n
  183. jmp @req
  184. @inext: inc cf_row
  185. inc cf_i
  186. jmp @impl
  187. @cnext: inc cf_class
  188. beq @done
  189. jmp @class
  190. @stop: sec
  191. rts
  192. @done: clc
  193. rts
  194. ; A = class ID, X = method name ID. C=1 and Y=row when the class declares a
  195. ; method with that name; C=0 otherwise. A field with the name does not count.
  196. find_method:
  197. sta fmc_class
  198. stx fmc_name
  199. ldy fmc_class
  200. lda #C_TYPE_MFIRST
  201. jsr tb_get
  202. sta fmc_row
  203. ldy fmc_class
  204. lda #C_TYPE_MCOUNT
  205. jsr tb_get
  206. sta fmc_n
  207. @row: lda fmc_n
  208. beq @no
  209. ldy fmc_row
  210. lda #C_MEM_FLAGS
  211. jsr tb_get
  212. and #MF_METHOD
  213. beq @next
  214. ldy fmc_row
  215. lda #C_MEM_NAME
  216. jsr tb_get
  217. cmp fmc_name
  218. beq @yes
  219. @next: inc fmc_row
  220. dec fmc_n
  221. bne @row
  222. @no: clc
  223. rts
  224. @yes: ldy fmc_row
  225. sec
  226. rts
  227. ; C=1 when the class method A matches a same-named requirement (X) of an
  228. ; implemented interface other than the one being checked. That means the
  229. ; interfaces themselves disagree, not that the class method is wrong.
  230. conflicting:
  231. sta cn_method
  232. stx cn_name
  233. ldy cf_class
  234. lda #C_TYPE_IFIRST
  235. jsr tb_get
  236. sta cn_row
  237. ldy cf_class
  238. lda #C_TYPE_ICOUNT
  239. jsr tb_get
  240. sta cn_n
  241. @iface: lda cn_n
  242. beq @no
  243. ldy cn_row
  244. lda #C_IMPL_IFACE
  245. jsr tb_get
  246. sta cn_iface
  247. cmp cf_iface
  248. beq @next_iface
  249. ldy cn_iface
  250. lda #C_TYPE_KIND
  251. jsr tb_get
  252. cmp #TYPE_INTERFACE
  253. bne @next_iface
  254. ldy cn_iface
  255. lda #C_TYPE_MFIRST
  256. jsr tb_get
  257. sta cn_req
  258. ldy cn_iface
  259. lda #C_TYPE_MCOUNT
  260. jsr tb_get
  261. sta cn_req_n
  262. @req: lda cn_req_n
  263. beq @next_iface
  264. ldy cn_req
  265. lda #C_MEM_NAME
  266. jsr tb_get
  267. cmp cn_name
  268. bne @next_req
  269. lda cn_method
  270. ldx cn_req
  271. jsr same_sig
  272. bcs @yes
  273. @next_req:
  274. inc cn_req
  275. dec cn_req_n
  276. bne @req
  277. @next_iface:
  278. inc cn_row
  279. dec cn_n
  280. bne @iface
  281. @no: clc
  282. rts
  283. @yes: sec
  284. rts
  285. ; C=1 when member rows A and X have equal signatures: result type, parameter
  286. ; count, and each parameter type.
  287. same_sig:
  288. sta sg_a
  289. stx sg_b
  290. ldy sg_a
  291. lda #C_MEM_PCOUNT
  292. jsr tb_get
  293. sta sg_n
  294. ldy sg_b
  295. lda #C_MEM_PCOUNT
  296. jsr tb_get
  297. cmp sg_n
  298. bne @no
  299. lda sg_a
  300. ldx sg_b
  301. jsr same_result
  302. bcc @no
  303. ldy sg_a
  304. lda #C_MEM_PFIRST
  305. jsr tb_get
  306. sta sg_pa
  307. ldy sg_b
  308. lda #C_MEM_PFIRST
  309. jsr tb_get
  310. sta sg_pb
  311. lda #$00
  312. sta sg_i
  313. @param: lda sg_i
  314. cmp sg_n
  315. beq @yes
  316. lda sg_pa
  317. clc
  318. adc sg_i
  319. sta sg_ra
  320. lda sg_pb
  321. clc
  322. adc sg_i
  323. sta sg_rb
  324. lda sg_ra
  325. ldx sg_rb
  326. jsr same_param
  327. bcc @no
  328. inc sg_i
  329. bne @param
  330. @yes: sec
  331. rts
  332. @no: clc
  333. rts
  334. same_result:
  335. ldy #C_MEM_TBASE
  336. jmp same_cells
  337. same_param:
  338. ldy #C_PAR_TBASE
  339. jmp same_cells
  340. ; C=1 when four consecutive type columns starting at Y are equal for rows A
  341. ; and X (base, name, length lo, length hi).
  342. same_cells:
  343. sta sg_a
  344. stx sg_b
  345. sty sg_col
  346. lda #$00
  347. sta sg_ci
  348. @col: ldy sg_a
  349. lda sg_col
  350. clc
  351. adc sg_ci
  352. jsr tb_get
  353. sta sg_v
  354. ldy sg_b
  355. lda sg_col
  356. clc
  357. adc sg_ci
  358. jsr tb_get
  359. cmp sg_v
  360. bne @no
  361. inc sg_ci
  362. lda sg_ci
  363. cmp #$04
  364. bne @col
  365. sec
  366. rts
  367. @no: clc
  368. rts
  369. ; Report A at class cf_class's declaration line, column 1, with name X as
  370. ; argument 1. C=1 when the diagnostic limit stopped compilation.
  371. iface_err:
  372. sta ie_code
  373. stx ie_name
  374. ldy cf_class
  375. lda #C_TYPE_LINE_LO
  376. jsr tb_get
  377. sta diag_line
  378. ldy cf_class
  379. lda #C_TYPE_LINE_HI
  380. jsr tb_get
  381. sta diag_line+1
  382. lda #$01
  383. sta diag_col
  384. lda ie_name
  385. jsr name_get
  386. lda #<name_out
  387. sta diag_arg1
  388. lda #>name_out
  389. sta diag_arg1+1
  390. lda name_out_len
  391. sta diag_arg1_len
  392. lda ie_code
  393. jsr diag_report
  394. bcc @ok
  395. sec
  396. rts
  397. @ok: clc
  398. rts
  399. .segment "BSS"
  400. ; slot assignment
  401. as_id: .res 1
  402. as_row: .res 1
  403. as_n: .res 1
  404. as_slot: .res 1
  405. ; conformance
  406. cf_class: .res 1
  407. cf_iface: .res 1
  408. cf_count: .res 1
  409. cf_row: .res 1
  410. cf_i: .res 1
  411. cf_req: .res 1
  412. cf_n: .res 1
  413. cf_name: .res 1
  414. cf_method: .res 1
  415. fmc_class: .res 1
  416. fmc_name: .res 1
  417. fmc_row: .res 1
  418. fmc_n: .res 1
  419. cn_method: .res 1
  420. cn_name: .res 1
  421. cn_row: .res 1
  422. cn_n: .res 1
  423. cn_iface: .res 1
  424. cn_req: .res 1
  425. cn_req_n: .res 1
  426. sg_a: .res 1
  427. sg_b: .res 1
  428. sg_n: .res 1
  429. sg_i: .res 1
  430. sg_pa: .res 1
  431. sg_pb: .res 1
  432. sg_col: .res 1
  433. sg_ci: .res 1
  434. sg_v: .res 1
  435. sg_ra: .res 1
  436. sg_rb: .res 1
  437. ie_code: .res 1
  438. ie_name: .res 1

Powered by TurnKey Linux.