ときどきの雑記帖 RE* (新南口)
真と偽と・補
GW-BASIC
前回は
GW-BASIC/MATH1.ASM at master ・ microsoft/GW-BASIC
ICOMP: ;COMPARE (DX) AND (BX)
;(AL)=1 IF (DX) .LT. (BX)
;(AL)=0 IF (DX) = (BX)
;(AL)=-1 IF (DX) .GT. (BX)
MOV AX,BX ;SO WE CAN HAVE SEPARATE ENTRY FOR AX
ICMPA: SUB AX,DX ;COMPARISONS
JZ IC40 ;ALL OK , JUST EXIT
JO IC20 ;IF SF=1 ADDITIONALLY THEN AX LARGER
JS IC30 ;DX DEFINITELY LARGER
IC10: XOR AL,AL ;(AX) LARGER
INRART: INC AL ;(AL)=1
IC15: RET
IC20: JS IC10
IC30: STC
SBB AL,AL ;(AL)=377
IC40: RET
ここだけ出したけど、追記したようにここだけでは説明不足。ここでは コメントにもある通り -1, 0, 1 の三種類が結果として(ALレジスタ-経由で)返されているのだけど、 これを元の比較演算子との組み合わせで求める値に変換しているところがある。
GW-BASIC/GWEVAL.ASM at master ・ microsoft/GW-BASIC
SUBTTL MORE FORMULA EVALUATION - LOGICAL, RELATIONAL OPS
DOCMP: INC AL ;SETUP BITS
ADC AL,AL ;4=LESS 2=EQUAL 1=GREATER
POP CX ;WHAT DID HE WANT?
AND AL,CH ;ANY BITS MATCH?
ADD AL,LOW 255 ;MAP 0 TO 0
SBB AL,AL ;AND ALL OTHERS TO 377
CALL CONIA ;CONVERT [A] TO AN INTEGER SIGNED
JMP SHORT RETAPG ;RETURN FROM OPERATOR APPLICATION
NOTER: MOV DH,LOW 90 ;"NOT" HAS PRECEDENCE 90, SO
CALL LPOPER ;FORMULA EVALUATION IS ENTERED WITH A DUMMY
;ENTRY OF 90 ON THE STACK
CALL FRCINT ;COERCE THE ARGUMENT TO INTEGER
INS86 367,323 ;NOT [H,L]
MOV FACLO,BX ;UPDATE THE FAC
POP CX ;FRMEVL, AFTER SEEING THE PRECEDENCE
;OF 90 THINKS IT IS APPLYING AN OPERATOR
;SO IT HAS THE TEXT POINTER IN TEMP2 SO
RETAPG: JMP RETAOP ;RETURN TO REFETCH IT
それがここ。引き算による結果と呼び出したときの比較演算子の組み合わせで0 か -1 に変換している。 コメントもしっかりついてるし、ここを読んでいる人ならロジックの説明はしないでも大丈夫だよね?(笑) 途中呼び出している CONIA というサブルーチンは AL レジスターの値を AX レジスターに 符号付きで拡幅するもの。
Regexp::Assemble
Regexp::AssembleのGo実装 rassemble-go を作りました - プログラムモグモグ
go はよくわからんのでソースコードは(まだ)読んでないんだけど、元記事の使用例
xs, err = rassemble.Join([]string{
"北海道", "青森県", "岩手県", "宮城県", "秋田県", "山形県", "福島県", "茨城県",
"栃木県", "群馬県", "埼玉県", "千葉県", "東京都", "神奈川県", "新潟県", "富山県",
"石川県", "福井県", "山梨県", "長野県", "岐阜県", "静岡県", "愛知県", "三重県",
"滋賀県", "京都府", "大阪府", "兵庫県", "奈良県", "和歌山県", "鳥取県", "島根県",
"岡山県", "広島県", "山口県", "徳島県", "香川県", "愛媛県", "高知県", "福岡県",
"佐賀県", "長崎県", "熊本県", "大分県", "宮崎県", "鹿児島県", "沖縄県",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(xs) // 北海道|(?:青森|岩手|宮[城崎]|秋田|山[口形梨]|福[井岡島]|茨城|栃木|
// 群馬|埼玉|千葉|(?:神奈|石|香)川|新潟|(?:富|和歌|岡)山|長[崎野]|岐阜|
// 静岡|愛[媛知]|三重|[佐滋]賀|兵庫|奈良|鳥取|島根|(?:[広徳]|鹿児)島|
// 高知|熊本|沖縄)県|東京都|京都府|大(?:阪府|分県)
のコメントにある部分が変換結果だと思うのだけど、 (?:[広徳]|鹿児)島 ができてるのだから (?:神奈|石|香)川 や (?:富|和歌|岡)山 も (?:神奈|[石香])川 と (?:和歌|[富岡])山 にならんもんだろうか?
後者は並び替えしないといけないから面倒が多いかもだけど。