Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#if exists LABEL が後方定義のラベルを認識しない #202

Open
SuperTurboZ opened this issue Apr 21, 2023 · 7 comments
Open

#if exists LABEL が後方定義のラベルを認識しない #202

SuperTurboZ opened this issue Apr 21, 2023 · 7 comments

Comments

@SuperTurboZ
Copy link

#if exists で参照するラベルが後方で定義されていると、#false判定になるようです。

                                ;draw bytes
0002FC F5FC 1EFF             7      LD   E,$FF
                                 #if exists  HOGE
                                ; #if exists  hfill_bc_e_a
                                    inc bc
                                    call    hfill_bc_e_a    ;BC=GA,E=FILL,A=BYTES
                                 #else
0002FE F5FE 3C               4      inc a
0002FF F5FF CB3F             8      srl a
000301 F601 3003            12      jr  nc,hline_odd
       F603                     hline_even:
000303 F603 03               6      INC  BC
000304 F604 ED59            12      OUT  (C),E
       F606                     hline_odd:
000306 F606 03               6      INC  BC
000307 F607 ED59            12      OUT  (C),E
000309 F609 3D               4      DEC  A
00030A F60A C203F6          10      JP   NZ,hline_even
                                 #endif
       F60D                     HOGE    equ $
                                 
       F60D                     hline_byte0:
@AILight
Copy link
Owner

AILight commented Apr 24, 2023

ご評価有難うございます。確認をさせて頂きます。

@AILight
Copy link
Owner

AILight commented Oct 30, 2023

(別の処理を開発していて思い出したのですが・・・)
#IFの展開はアセンブル処理の前に行う必要があります。この前処理ではソースコード全体を走査していないので、後方で定義されるラベルを参照することができず、エラーが生じます。この仕様で問題がある場合、実装の見直しを検討します。ご意見をお聞かせいただければ幸いです。

@SuperTurboZ
Copy link
Author

SuperTurboZ commented Oct 30, 2023

#IFは前処理なのでラベルが参照できないのは仕様になるのですね。
気が付きませんでした。

前処理ではマクロ内で引数から動的に処理する事ができないので、欲を言うとアセンブル時の IF も前処理とは別に欲しいです。REPT 1 or 0で代用はできることは分かりましたがELSEが使えないので可読性が下がります。

それとPASS2(最終パス)だけでエラー判定を行いたいケースがあります。
AASMではパス数がグローバルなシステム変数として定義されていて、$ や$$を参照できるようにIFから参照できるようになっています。

@SuperTurboZ
Copy link
Author

もし if else endif が実装されるなら、変数や文字列変換や文字列結合なども出来るとうれしいです。
これはもはやZ80コード生成ではないですが、こういったこともしたいです。

;	定義ポイントにはテーブルのindex値を埋め込んで実体はテーブルに一括出力する
;
;必要とする機能
;
; 1. アセンブル時に評価される if else endif
; 2. 現在のパス数の参照
; 3. 1パス内で再定義が可能な変数
; 4.数値の書式付き文字列置換と文字列の結合

;--------------------------------------
;アイテムの実態をテーブルに列挙する
item_header:
  if pass >= 2		;配列はpass1では未定義なのでpass2以降で行う
item_max	equ	item_index	;前回のパスから配列の数を取得
;このマクロから
  var repeat_index = 0	;何度も変更できるワーク変数が使いたい
 rept item_max			;配列の数だけ出力する
	dw	item%%repeat_index.@03d%%	;repeat_indexを10進数3桁文字列にして結合
    repeat_index = repeat_index+1
  endm
;こんな感じに展開されてほしい
	dw	item000		;1234
	dw	item001		;2345
	dw	item002		;3456
 endif

;--------------------------------------
;アイテムを配列に登録する
	ITEM_REGIST	macro item_value
	db	0x80+item_index	;格納する配列のindexを出力する
item%%item_index.@03d%%	equ	item_value	;実態は配列に格納
item_index = item_index+1	;配列の数を一つ増やす
	endm
	
;--------------------------------------
;配列をリセット
;macroで何度も更新されるので、定数ではなく変数である必要がある
	var	item_index = 0

;--------------------------------------
;データ定義
;
data_list:
	db	100			;他のデータ

	ITEM_REGIST	1234	;item000 に 1234を登録する
;こんな感じに展開したい
	db	0x80+0
item000	equ	1234
item_index = 1

	db	200			;他のデータ

	ITEM_REGIST	2345
;こんな感じに展開したい
	db	0x80+1
item001	equ	2345
item_index = 2

	db	300			;他のデータ

	ITEM_REGIST	3456
;こんな感じに展開したい
	db	0x80+2
item002	equ	3456
item_index = 3

@AILight
Copy link
Owner

AILight commented Nov 16, 2023

返信が遅くなってすみませんでした。
興味深いご提案ありがとうございます。実はうちのアセンブラのマクロは単なる文字列としての展開ではなく、スコープを内でのコードを展開するものとして実装してしまいました。そのためにデータの定義ができない問題を抱えているような気がしています(確認はしていないのですが、そういう実装だったと思います)
今回のような機能を実装するときにはその辺の問題が解消できると思いますので、なんとか実装できないか探ってみたいと思います。

後方定義のラベルにつきましては、スーパーアセンブルモードを使えばいけるのでは?とアイデアが出てきましたのでそちらも時間が取れたら実験をして実装できるか確認をしてみたいと思います。

手が遅くて改修が遅くなっており申し訳ございません。諦めは悪い方ですのでコツコツと頑張りたいと思います。

@SuperTurboZ
Copy link
Author

よく理解できてないですが、マクロ展開の構造的に難しそうということなのですね。
マクロは何が静的に展開されて何が動的に展開されるのかアセンブラによって異なるので使う側も把握が難しいです。

もしマクロ内でIF ENDIFを動的に処理できるなら、データ配列の定義と生成については

;データ登録とインデックスの発行
ITEM_REGIST	macro item_value
 if DATA0.@E==#FALSE
DATA0	equ	item_value
  db 0x80+0
 elif DATA1.@E==#FALSE
DATA1	equ	item_value
  db 0x80+1
 elif DATA2.@E==#FALSE
DATA2	equ	item_value
  db 0x80+2
 endif
endm

;データテーブル生成
 if DATA0.@E
	dw	DATA0
 endif
 if DATA1.@E
	dw	DATA1
 endif
 if DATA2.@E
	dw	DATA2
 endif

とベタ書きすることで変数と変数値の文字列結合は使わなくても出来そうな気はします。
無いと困る基本機能ではないので、簡単に実装できそうなアイデアが思いついたらでよいと思います。気長に待っています。

@AILight
Copy link
Owner

AILight commented Mar 20, 2024

ご要望を頂いているのに、開発が遅く申し訳ございません。
2週間近く仕様および実装について悩みました(汗)

existsを実装した時の使い方の想定として、ラベルが定義済みの時に再度同一のラベルを定義しないために設計したものでした。後方ラベルの参照については、頑張れば実装できそうではあったのですが当初の仕様から考えると直感的ではないので実装は見送りたいと考えております。が、追加で頂いた要望については、引き続き検討したいと思います。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants