Kestrel-3

Check-in [447c21378e]
Login

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

Overview
Comment:.skip and .zero support
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:447c21378e72bf57f3563ee1e030edf90d8a181409f3b61e91e3d13bce0280a8
User & Date: kc5tja 2019-09-05 03:41:14
Context
2019-09-08
23:48
Bring in the project report org-mode document. Tracks stepwise refinement of system firmware, hardware design choices, etc. check-in: e485309137 user: kc5tja tags: trunk
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
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to dev/src/bcpl/assemrv/manifest.h.

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    scs_2byte;
    scs_4byte;
    scs_8byte;
    scs_half;
    scs_word;
    scs_dword;
    scs_asciz;
    scs_zero;
    scs_p2align;
    scs_balign;
    scs_equ;
    scs_include;
    scs_file;
    scs_line;
    scs_gv;







|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    scs_2byte;
    scs_4byte;
    scs_8byte;
    scs_half;
    scs_word;
    scs_dword;
    scs_asciz;
    scs_skip;
    scs_p2align;
    scs_balign;
    scs_equ;
    scs_include;
    scs_file;
    scs_line;
    scs_gv;

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
21
..
63
64
65
66
67
68
69




















70
71
72
73
74
75
76
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 {
................................................................................
}

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
		expr!expr_value := scanner_value(s)

<
<


>
>
>
>
>
>









>







 







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







1


2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
LET parse(s, d, errp) BE {


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

	WHILE (scanner_sym(s) ~= endstreamch) & (!errp = 0) DO parse_part(s, d, errp)
}

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

	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
	IF sym = scs_skip DO scanner_next(s) <> skip(s, d, errp) <> RETURN

	error(errp, s, err_syntax_error)
}

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

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 skip(s, d, errp) BE {
	LET ecount = VEC expr_sizeof
	LET efill = VEC expr_sizeof	// optional; defaults to 0

	efill!expr_type, efill!expr_value := et_integer, 0

	expression(s, d, errp, ecount)
	IF !errp DO RETURN
	IF ecount!expr_type ~= et_integer DO error(errp, s, err_int_str_expr_expected) <> RETURN

	IF scanner_sym(s) = ',' DO {
		scanner_next(s)
		expression(s, d, errp, efill)
		IF !errp DO RETURN
		IF efill!expr_type ~= et_integer DO error(errp, s, err_int_expr_expected) <> RETURN
	}

	FOR i = 0 TO ecount!expr_value - 1 DO append_order(d, IR_BYTE, efill!expr_value)
}

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

	IF sym = scs_integer DO {
		expr!expr_type := et_integer
		expr!expr_value := scanner_value(s)

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

22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
	addKW(s, ".8byte",	scs_8byte)
	addKW(s, ".half",	scs_half)
	addKW(s, ".word",	scs_word)
	addKW(s, ".dword",	scs_dword)
	addKW(s, ".ascii",	scs_byte)
	addKW(s, ".asciz",	scs_asciz)
	addKW(s, ".string",	scs_asciz)

	addKW(s, ".zero",	scs_zero)
	addKW(s, ".p2align",	scs_p2align)
	addKW(s, ".balign",	scs_balign)
	addKW(s, ".equ",	scs_equ)
	addKW(s, ".set",	scs_equ)
	addKW(s, ".include",	scs_include)
	addKW(s, ".file",	scs_file)
	addKW(s, ".line",	scs_line)







>
|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
	addKW(s, ".8byte",	scs_8byte)
	addKW(s, ".half",	scs_half)
	addKW(s, ".word",	scs_word)
	addKW(s, ".dword",	scs_dword)
	addKW(s, ".ascii",	scs_byte)
	addKW(s, ".asciz",	scs_asciz)
	addKW(s, ".string",	scs_asciz)
	addKW(s, ".skip",       scs_skip)
	addKW(s, ".zero",	scs_skip)
	addKW(s, ".p2align",	scs_p2align)
	addKW(s, ".balign",	scs_balign)
	addKW(s, ".equ",	scs_equ)
	addKW(s, ".set",	scs_equ)
	addKW(s, ".include",	scs_include)
	addKW(s, ".file",	scs_file)
	addKW(s, ".line",	scs_line)

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

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

93
94
95
96
97
98
99
....
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
....
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!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 {
................................................................................
	                     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")
................................................................................

	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
}








|







 







>







 







|







 







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










60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
..
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
....
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
....
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
GET "globals_dynvec"
GET "globals_scanner"
GET "globals_utils"
GET "globals_parser"


LET testlist() = VALOF {
	MANIFEST { ntests = 24 }
	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!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
	tl!24 := test_skip
	RESULTIS tl
}


// Parser Tests: Utilities

AND free_errors(p) BE {
................................................................................
	                     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_asciz_string"

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

	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
}

AND test_skip(r) = VALOF {
	LET err = failat
	LET scb, s, d = 0, 0, 0
	LET expected = TABLE IR_LIT, #xAA, IR_BYTE,
	                     IR_LIT, #xAA, IR_BYTE,
	                     IR_LIT, #xAA, IR_BYTE,
	                     IR_LIT, #xAA, IR_BYTE,
	                     IR_LIT, #x55, IR_BYTE,
	                     IR_LIT, #x55, IR_BYTE,
	                     IR_LIT, #x55, IR_BYTE,
	                     IR_LIT, #x55, IR_BYTE,
	                     IR_LIT, #x00, IR_BYTE,
	                     IR_LIT, #x00, IR_BYTE,
	                     IR_LIT, #x00, IR_BYTE,
	                     IR_LIT, #x00, IR_BYTE,
	                     IR_LIT, #x00, IR_BYTE,
	                     IR_LIT, #x00, IR_BYTE,
	                     IR_LIT, #x00, IR_BYTE,
	                     IR_LIT, #x00, IR_BYTE
	LET errlist = 0

	IF r DO RESULTIS r
	testid := "test_skip"

	scb := findinoutput("RAM:")
	UNLESS NEQ(scb, 0, 0) DO GOTO unwind
	{
		LET outs = output()
		selectoutput(scb)
		writef(".skip 4, 0xAA*n.skip 4, 0x55*n.zero 4*n.zero 4, 0*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, 48, 100) DO GOTO unwind
	FOR i = 0 TO 47 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.

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
...
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
	UNLESS NEQ(s, 0) DO GOTO unwind
	scb := findinoutput("RAM:")
	{
		LET outs = output()
		selectoutput(scb)
		writef(".byte .2byte .4byte .8byte .half .word .dword ")
		writef(".ascii .asciz .string ")
		writef(".zero .p2align .balign ")
		writef(".equ .set .include .file .line ")
		writef(".gv .gref")
		selectoutput(outs)
		rewindstream(scb)
	}
	UNLESS EQ(scanner_get_stream(s, scb, "RAM:"), TRUE, 1) DO GOTO unwind
	scanner_nextchar(s)
................................................................................
	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
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_include, 115) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_file,    116) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_line,    117) DO GOTO unwind







|







 







|
>







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
...
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
	UNLESS NEQ(s, 0) DO GOTO unwind
	scb := findinoutput("RAM:")
	{
		LET outs = output()
		selectoutput(scb)
		writef(".byte .2byte .4byte .8byte .half .word .dword ")
		writef(".ascii .asciz .string ")
		writef(".zero .skip .p2align .balign ")
		writef(".equ .set .include .file .line ")
		writef(".gv .gref")
		selectoutput(outs)
		rewindstream(scb)
	}
	UNLESS EQ(scanner_get_stream(s, scb, "RAM:"), TRUE, 1) DO GOTO unwind
	scanner_nextchar(s)
................................................................................
	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_skip,    110) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_skip,    110) DO GOTO unwind	// .zero synonym to .skip
	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
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_include, 115) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_file,    116) DO GOTO unwind
	scanner_next(s); UNLESS EQ(scanner_sym(s), scs_line,    117) DO GOTO unwind