Kestrel-3

Check-in [f23325b630]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Support .asciz and fix unit test breakage in scanner
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:f23325b630014e86991313393783d6f49ef2b3e25ed83d2c64e42779f008550a
User & Date: kc5tja 2019-09-05 03:10:06
Context
2019-09-05
03:41
.skip and .zero support check-in: 447c21378e user: kc5tja tags: trunk
03:10
Support .asciz and fix unit test breakage in scanner check-in: f23325b630 user: kc5tja tags: trunk
02:51
.ascii support check-in: 29d317a6a2 user: kc5tja tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to dev/src/bcpl/assemrv/parser.b.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
..
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63

64
65
66

67
68





69
70
71
72
73
74
75
LET parse(s, d, errp) BE {
	LET sym = scanner_sym(s)

	// Don't even try unless a chain of errors can be constructed.
	UNLESS errp DO RETURN

	IF sym = scs_dword DO scanner_next(s) <> const(s, d, errp, IR_DWORD) <> RETURN
	IF sym = scs_word DO scanner_next(s) <> const(s, d, errp, IR_WORD) <> RETURN
	IF sym = scs_half DO scanner_next(s) <> const(s, d, errp, IR_HALF) <> RETURN
	IF sym = scs_byte DO scanner_next(s) <> const(s, d, errp, IR_BYTE) <> RETURN
	IF sym = scs_8byte DO scanner_next(s) <> const(s, d, errp, IR_8BYTE) <> RETURN
	IF sym = scs_4byte DO scanner_next(s) <> const(s, d, errp, IR_4BYTE) <> RETURN
	IF sym = scs_2byte DO scanner_next(s) <> const(s, d, errp, IR_2BYTE) <> RETURN


	error(errp, s, err_syntax_error)
}

AND error(errp, scanner, errcode) BE {
	LET errdesc = getvec(ed_sizeof)
	IF errdesc DO {
................................................................................
		errdesc!ed_code := errcode

		errdesc!ed_next := !errp
		!errp := errdesc
	}
}

AND const(s, d, errp, order) BE {
	LET expr = VEC expr_sizeof

	zerovec(expr, expr_sizeof)

	const_part(s, d, errp, expr, order)
	IF !errp DO RETURN
	WHILE scanner_sym(s) = ',' DO {
		scanner_next(s)
		const_part(s, d, errp, expr, order)
		IF !errp DO RETURN
	}
}

AND const_part(s, d, errp, expr, order) BE {
	expression(s, d, errp, expr)
	IF !errp DO RETURN

	IF expr!expr_type = et_integer DO {
		dynvec_put_at(d, IR_LIT, d!dv_length)
		dynvec_put_at(d, expr!expr_value, d!dv_length)
		dynvec_put_at(d, order, d!dv_length)
		RETURN
	}

	IF expr!expr_type = et_string DO {

		LET s = @expr!expr_string

		FOR i = 1 TO s%0 DO {
			dynvec_put_at(d, IR_LIT, d!dv_length)
			dynvec_put_at(d, s%i, d!dv_length)
			dynvec_put_at(d, order, d!dv_length)

		}
		RETURN
	}


	error(errp, s, err_int_str_expr_expected) <> RETURN





}

AND expression(s, d, errp, expr) BE {
	LET sym = scanner_sym(s)

	IF sym = scs_integer DO {
		expr!expr_type := et_integer






|
|
|
|
|
|
|
>







 







|




|



|




|



|
|
<
<
<
|
<
|
>


|
<
<
<
>
|
<
|
>
|
<
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52



53

54
55
56
57
58



59
60

61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
LET parse(s, d, errp) BE {
	LET sym = scanner_sym(s)

	// Don't even try unless a chain of errors can be constructed.
	UNLESS errp DO RETURN

	IF sym = scs_dword DO scanner_next(s) <> const(s, d, errp, IR_DWORD, FALSE) <> RETURN
	IF sym = scs_word DO scanner_next(s) <> const(s, d, errp, IR_WORD, FALSE) <> RETURN
	IF sym = scs_half DO scanner_next(s) <> const(s, d, errp, IR_HALF, FALSE) <> RETURN
	IF sym = scs_byte DO scanner_next(s) <> const(s, d, errp, IR_BYTE, FALSE) <> RETURN
	IF sym = scs_8byte DO scanner_next(s) <> const(s, d, errp, IR_8BYTE, FALSE) <> RETURN
	IF sym = scs_4byte DO scanner_next(s) <> const(s, d, errp, IR_4BYTE, FALSE) <> RETURN
	IF sym = scs_2byte DO scanner_next(s) <> const(s, d, errp, IR_2BYTE, FALSE) <> RETURN
	IF sym = scs_asciz DO scanner_next(s) <> const(s, d, errp, IR_BYTE, TRUE) <> RETURN

	error(errp, s, err_syntax_error)
}

AND error(errp, scanner, errcode) BE {
	LET errdesc = getvec(ed_sizeof)
	IF errdesc DO {
................................................................................
		errdesc!ed_code := errcode

		errdesc!ed_next := !errp
		!errp := errdesc
	}
}

AND const(s, d, errp, order, null_after_strings) BE {
	LET expr = VEC expr_sizeof

	zerovec(expr, expr_sizeof)

	const_part(s, d, errp, expr, order, null_after_strings)
	IF !errp DO RETURN
	WHILE scanner_sym(s) = ',' DO {
		scanner_next(s)
		const_part(s, d, errp, expr, order, null_after_strings)
		IF !errp DO RETURN
	}
}

AND const_part(s, d, errp, expr, order, null_after_strings) BE {
	expression(s, d, errp, expr)
	IF !errp DO RETURN

	TEST expr!expr_type = et_integer
	THEN append_order(d, order, expr!expr_value)





	ELSE TEST expr!expr_type = et_string
	THEN {
		LET s = @expr!expr_string

		FOR i = 1 TO s%0 DO append_order(d, order, s%i)



		IF null_after_strings DO append_order(d, order, 0)
	}


	ELSE error(errp, s, err_int_str_expr_expected)
}


AND append_order(d, order, v) BE {
	dynvec_put_at(d, IR_LIT, d!dv_length)
	dynvec_put_at(d, v, d!dv_length)
	dynvec_put_at(d, order, d!dv_length)
}

AND expression(s, d, errp, expr) BE {
	LET sym = scanner_sym(s)

	IF sym = scs_integer DO {
		expr!expr_type := et_integer

Changes to dev/src/bcpl/assemrv/test_parser.b.

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
..
85
86
87
88
89
90
91

92
93
94
95
96
97
98
....
1147
1148
1149
1150
1151
1152
1153




























































1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
GET "globals_dynvec"
GET "globals_scanner"
GET "globals_utils"
GET "globals_parser"


LET testlist() = VALOF {
	MANIFEST { ntests = 22 }
	LET tl = getvec(ntests)
	tl!0 := ntests
	tl!1 := test_dword
	tl!2 := test_dword_chain
	tl!3 := test_dword_string
	tl!4 := test_word
	tl!5 := test_word_chain
................................................................................
	tl!16 := test_4byte
	tl!17 := test_4byte_chain
	tl!18 := test_4byte_string
	tl!19 := test_2byte
	tl!20 := test_2byte_chain
	tl!21 := test_2byte_string
	tl!22 := test_ascii_string

	RESULTIS tl
}


// Parser Tests: Utilities

AND free_errors(p) BE {
................................................................................

	parse(s, d, @errlist)
	UNLESS EQ(errlist, 0, 5) DO GOTO unwind

	UNLESS EQ(d!dv_length, 21, 100) DO GOTO unwind
	FOR i = 0 TO 20 DO UNLESS EQ(dynvec_at(d, i), expected!i, 200+i) DO GOTO unwind





























































	err := 0

unwind:
	IF errlist DO free_errors(errlist)
	IF d DO dynvec_free(d)
	IF s DO scanner_free(s)
	IF scb DO endstream(scb)
	RESULTIS err
}








|







 







>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
..
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
....
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
GET "globals_dynvec"
GET "globals_scanner"
GET "globals_utils"
GET "globals_parser"


LET testlist() = VALOF {
	MANIFEST { ntests = 23 }
	LET tl = getvec(ntests)
	tl!0 := ntests
	tl!1 := test_dword
	tl!2 := test_dword_chain
	tl!3 := test_dword_string
	tl!4 := test_word
	tl!5 := test_word_chain
................................................................................
	tl!16 := test_4byte
	tl!17 := test_4byte_chain
	tl!18 := test_4byte_string
	tl!19 := test_2byte
	tl!20 := test_2byte_chain
	tl!21 := test_2byte_string
	tl!22 := test_ascii_string
	tl!23 := test_asciz_string
	RESULTIS tl
}


// Parser Tests: Utilities

AND free_errors(p) BE {
................................................................................

	parse(s, d, @errlist)
	UNLESS EQ(errlist, 0, 5) DO GOTO unwind

	UNLESS EQ(d!dv_length, 21, 100) DO GOTO unwind
	FOR i = 0 TO 20 DO UNLESS EQ(dynvec_at(d, i), expected!i, 200+i) DO GOTO unwind

	err := 0

unwind:
	IF errlist DO free_errors(errlist)
	IF d DO dynvec_free(d)
	IF s DO scanner_free(s)
	IF scb DO endstream(scb)
	RESULTIS err
}

AND test_asciz_string(r) = VALOF {
	LET err = failat
	LET scb, s, d = 0, 0, 0
	LET expected = TABLE IR_LIT, 6, IR_BYTE,
	                     IR_LIT, 'A', IR_BYTE,
	                     IR_LIT, 'b', IR_BYTE,
	                     IR_LIT, 'a', IR_BYTE,
	                     IR_LIT, 'c', IR_BYTE,
	                     IR_LIT, 'a', IR_BYTE,
	                     IR_LIT, 'b', IR_BYTE,
	                     IR_LIT, 0, IR_BYTE,
	                     IR_LIT, 'N', IR_BYTE,
	                     IR_LIT, 'a', IR_BYTE,
	                     IR_LIT, 'm', IR_BYTE,
	                     IR_LIT, 'i', IR_BYTE,
	                     IR_LIT, 'n', IR_BYTE,
	                     IR_LIT, 'a', IR_BYTE,
	                     IR_LIT, 'n', IR_BYTE,
	                     IR_LIT, 'u', IR_BYTE,
	                     IR_LIT, 0, IR_BYTE
	LET errlist = 0

	IF r DO RESULTIS r
	testid := "test_ascii_string"

	scb := findinoutput("RAM:")
	UNLESS NEQ(scb, 0, 0) DO GOTO unwind
	{
		LET outs = output()
		selectoutput(scb)
		writef(".asciz 6, *"Abacab*", *"Naminanu*"*n")
		selectoutput(outs)
		rewindstream(scb)
	}

	s := make_scanner()
	UNLESS NEQ(s, 0, 1) DO GOTO unwind
	UNLESS EQ(scanner_get_stream(s, scb, "RAM:"), TRUE, 3) DO GOTO unwind
	scanner_nextchar(s)
	scanner_next(s)

	d := make_dynvec()
	UNLESS NEQ(d, 0, 4) DO GOTO unwind

	parse(s, d, @errlist)
	UNLESS EQ(errlist, 0, 5) DO GOTO unwind

	UNLESS EQ(d!dv_length, 51, 100) DO GOTO unwind
	FOR i = 0 TO 50 DO UNLESS EQ(dynvec_at(d, i), expected!i, 200+i) DO GOTO unwind

	err := 0

unwind:
	IF errlist DO free_errors(errlist)
	IF d DO dynvec_free(d)
	IF s DO scanner_free(s)
	IF scb DO endstream(scb)
	RESULTIS err
}

Changes to dev/src/bcpl/assemrv/test_scanner.b.

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_byte,    100) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_2byte,   101) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_4byte,   102) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_8byte,   103) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_half,    104) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_word,    105) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_dword,   106) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_ascii,   107) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_asciz,   108) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_asciz,   109) DO GOTO unwind	// .string synonym to .asciz
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_zero,    110) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_p2align, 111) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_balign,  112) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_equ,     113) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_equ,     114) DO GOTO unwind	// .set synonym to .equ







|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_byte,    100) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_2byte,   101) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_4byte,   102) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_8byte,   103) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_half,    104) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_word,    105) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_dword,   106) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_byte,    107) DO GOTO unwind	// .ascii synonym to .byte
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_asciz,   108) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_asciz,   109) DO GOTO unwind	// .string synonym to .asciz
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_zero,    110) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_p2align, 111) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_balign,  112) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_equ,     113) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_equ,     114) DO GOTO unwind	// .set synonym to .equ