HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
0211
K-s#define でラベルを展開したときの挙動5解決


K-s

リンク

2017/2/11(Sat) 21:27:30|NO.78236

ctype指定の有無やスペースで展開がうまくいかないようです。
テスト環境はHSP 3.5beta4です。

↓これはOK。
#define ctype ROUTINE(%1) *rt%1
ROUTINE(aa)

↓*rt aaと間にスペースが入ってエラーになります。
#define ROUTINE(%1) *rt%1
ROUTINE aa

↓ctypeありでもaaの前にスペースを入れると↑同様エラーになります。
#define ctype ROUTINE(%1) *rt%1
ROUTINE( aa)



この記事に返信する


掘木

リンク

2017/2/22(Wed) 20:23:03|NO.78300

hspcmpの現状の仕様です、そして、そうなる原因についても把握はしていますが…

それは言語上認められる記法なのですかね?
私個人としてはトークン結合を行う事のできる現状の動作が異端で、
空白文字の有無に関わらずにコンパイル不可で有るべきと思いますけどどうなのでしょう。

今の仕様は統一感がないのは事実ですね。



K-s

リンク

2017/2/25(Sat) 11:07:11|NO.78312

テスト前は#defineはコンパイル前のコードの置換というイメージだったので
こういった書き方も大丈夫だろうと思っていました…

自分的にはありかと思うんですが統一していないと混乱の元になりそうですね。

事の発端はラベルの代入・参照の際、同じ文字列をなるべく何度も打たなくてもいい方法はないかと
↓のような書き方を考えていたことです。
#define ctype setRoutine(%1,%2) rt_init(%1)=*init%2: rt_update(%1)=*update%2: rt_draw(%1)=*draw%2
#define ctype rtInit(%1) %troutine %s1 *init%p #define rtUpdate %troutine return : *update%p #define rtDraw %troutine return : *draw%p #define rtEnd %troutine return : %o0 setRoutine(0,Enemy00) ;本当は setRoutine 0, Enemy00 という風に命令形で書きたかった setRoutine(1,Enemy01) setRoutine(2,Enemy02) ;... num = length(rt_init) repeat num : gosub rt_init(cnt) : loop *mainLoop repeat num : gosub rt_update(cnt) : loop redraw 0 repeat num : gosub rt_draw(cnt) : loop redraw 1 await 15 goto *mainLoop rtInit(Enemy00) ; 初期処理 rtUpdate ; 更新処理 rtDraw ; 描画処理 rtEnd rtInit(Enemy01) ; rtUpdate ; rtDraw ; rtEnd rtInit(Enemy02) ; rtUpdate ; rtDraw ; rtEnd ;...
switchだとcaseが増えると比較処理もそれなりに無視できなくなりそうなので
ラベルで直接ジャンプするようにしているのですが、
素直に switch,case で書いた方が良い気もしています…



掘木

リンク

2017/2/26(Sun) 22:22:51|NO.78322

大本の質問とは別のところに飛んでいきますが、
初期化と動作と描画がひとまとまりっぽいので、それを配列番号に割り当てて、
匿名ラベルっぽいもののリストを作ってごまかしてみるとか?

if (0) : *sub_null : return #define templabel *@f:if(0):*@ #enum EnemyRoutine_null = 0 #enum EnemyRoutine_00 #enum EnemyRoutine_01 dim enemys #define registerEnemy(%1,%2) enemyroutine(%1) = %2 gosub *RegisterRoutine registerEnemy 0,EnemyRoutine_00 registerEnemy 1,EnemyRoutine_00 registerEnemy 2,EnemyRoutine_01 registerEnemy 3,EnemyRoutine_01 registerEnemy 4,EnemyRoutine_01 foreach enemyroutine gosub init(enemyroutine(cnt)) loop *main foreach enemyroutine gosub sync(enemyroutine(cnt)) loop foreach enemyroutine gosub draw(enemyroutine(cnt)) loop await 1000 goto *main *RegisterRoutine ldim init,8 ldim sync,8 ldim draw,8 ldim term,8 init(EnemyRoutine_00) = templabel{ mes "Init@0" return } sync(EnemyRoutine_00) = *sub_null draw(EnemyRoutine_00) = tempLabel{ mes "Draw@0" return } term(EnemyRoutine_00) = tempLabel{ mes "Term@0" return } init(EnemyRoutine_01) = *sub_null sync(EnemyRoutine_01) = tempLabel{ mes "Sync@1" } draw(EnemyRoutine_01) = tempLabel{ mes "Draw@1" return } term(EnemyRoutine_01) = *sub_null return
ま、いいコードとは言えない気がしますね。
条件次第ではモジュール型に任せるとかその辺の話になりそうでもあるです。



GENKI

リンク

2017/2/27(Mon) 00:30:53|NO.78323

> 素直に switch,case で書いた方が良い気もしています…

on命令とかどうですか。



K-s

リンク

2017/3/6(Mon) 04:55:38|NO.78375

>>掘木さん
匿名ラベルを変数に入れる発想はありませんでした。
こんな使い方もできるんですね…

>>GENKIさん
速度的にはonが有利ですがやはり大量にラベルを書かないといけないので。
面倒がらず書けばいい話なんですが…



ONION software Copyright 1997-2021(c) All rights reserved.