2
2
import { Lexer , Token , TokenType } from "./lexer" ;
3
3
import * as AST from "./ast" ;
4
4
5
+
6
+ function parseNumber ( input : string ) {
7
+ return parseInt ( input )
8
+ }
9
+
5
10
export class Parser {
6
11
private lexer : Lexer ;
7
12
private currentToken : Token ;
@@ -11,12 +16,12 @@ export class Parser {
11
16
constructor ( lexer : Lexer ) {
12
17
this . lexer = lexer ;
13
18
this . currentToken = this . lexer . nextToken ( ) ;
14
- this . nextToken = this . lexer . nextToken ( ) ;
19
+ this . nextToken = this . lexer . nextToken ( ) ;
15
20
}
16
21
17
- public next ( ) {
18
- this . currentToken = this . nextToken ;
19
- this . nextToken = this . lexer . nextToken ( ) ;
22
+ public next ( ) {
23
+ this . currentToken = this . nextToken ;
24
+ this . nextToken = this . lexer . nextToken ( ) ;
20
25
return this . currentToken
21
26
}
22
27
@@ -54,6 +59,45 @@ export class Parser {
54
59
} ;
55
60
}
56
61
62
+ private parseDataDeclaration ( ) : AST . DataDeclaration {
63
+ const name = this . eat ( TokenType . IDENTIFIER ) . value ;
64
+ const dataType = this . eat ( this . currentToken . type ) . value ;
65
+ let value : AST . DataExpression [ ] = [ ]
66
+ while ( this . currentToken . type !== TokenType . NEWLINE ) {
67
+ if ( this . currentToken . type === TokenType . COMMA ) {
68
+ this . eat ( TokenType . COMMA )
69
+ continue
70
+ }
71
+ if ( this . currentToken . type === TokenType . STRING ) {
72
+ let a : AST . DataExpression = {
73
+ type : "DataExpression" ,
74
+ value : this . eat ( TokenType . STRING ) . value ,
75
+ location : this . currentToken . location
76
+ }
77
+ value . push ( a )
78
+ }
79
+ if ( this . currentToken . type === TokenType . NUMBER ) {
80
+ let a : AST . DataExpression = {
81
+ type : "DataExpression" ,
82
+ value : {
83
+ "type" : "NumericLiteralExpression" ,
84
+ value : parseNumber ( this . eat ( TokenType . NUMBER ) . value ) ,
85
+ location : this . currentToken . location
86
+ } ,
87
+ location : this . currentToken . location
88
+ }
89
+ value . push ( a )
90
+ }
91
+ }
92
+ return {
93
+ type : "DataDeclaration" ,
94
+ name,
95
+ dataType,
96
+ value,
97
+ location : this . currentToken . location ,
98
+ } ;
99
+ }
100
+
57
101
private parseSegmentEnd ( ) : AST . SegmentEnd {
58
102
const name = this . eat ( TokenType . IDENTIFIER ) . value ;
59
103
this . eat ( TokenType . ENDS ) ;
@@ -76,6 +120,22 @@ export class Parser {
76
120
return { type : "Instruction" , mnemonic, operands, location : this . currentToken . location } ;
77
121
}
78
122
123
+ private parseAssume ( ) : AST . AssumeDirective {
124
+ let out : AST . AssumeDirective = {
125
+ "type" : "AssumeDirective" ,
126
+ "pair" : [ ] ,
127
+ "location" : this . currentToken . location
128
+ } ;
129
+ this . eat ( this . currentToken . type )
130
+ while ( this . currentToken . type !== TokenType . NEWLINE ) {
131
+ const register = this . eat ( this . currentToken . type ) . value ;
132
+ this . eat ( TokenType . COLON )
133
+ const segment = this . eat ( this . currentToken . type ) . value
134
+ out . pair . push ( { register, segment} )
135
+ }
136
+ return out
137
+ }
138
+
79
139
private parseOperand ( ) : AST . Operand {
80
140
if ( this . currentToken . type === TokenType . IDENTIFIER ) {
81
141
if ( this . nextToken . value === ":" ) {
@@ -131,7 +191,7 @@ export class Parser {
131
191
const name = this . eat ( TokenType . DIRECTIVE ) . value ;
132
192
const args : AST . Expression [ ] = [ ] ;
133
193
if ( this . currentToken . type === TokenType . STRING ) {
134
- args . push ( { type : "StringLiteralExpression" , name :"debug!!!!" , value : this . eat ( TokenType . STRING ) . value , location : this . currentToken . location } ) ;
194
+ args . push ( { type : "StringLiteralExpression" , name : "debug!!!!" , value : this . eat ( TokenType . STRING ) . value , location : this . currentToken . location } ) ;
135
195
}
136
196
137
197
return { type : "Directive" , name, arguments : args , location : this . currentToken . location } ;
@@ -151,7 +211,12 @@ export class Parser {
151
211
if ( this . currentToken . type === TokenType . IDENTIFIER ) {
152
212
if ( this . nextToken . value === "SEGMENT" ) {
153
213
return this . parseSegmentDeclaration ( ) ;
154
- } else if ( this . nextToken . value === "ENDS" ) {
214
+ }
215
+ else if ( [ TokenType . DB , TokenType . DW , TokenType . DD ] . some ( a => a === this . nextToken . type ) ) {
216
+ return this . parseDataDeclaration ( ) ;
217
+ }
218
+
219
+ else if ( this . nextToken . value === "ENDS" ) {
155
220
return this . parseSegmentEnd ( ) ;
156
221
} else if ( this . nextToken . value === ":" ) {
157
222
return this . parseLabel ( ) ;
@@ -164,6 +229,8 @@ export class Parser {
164
229
} else {
165
230
return this . parseDirective ( ) ;
166
231
}
232
+ } else if ( this . currentToken . type === TokenType . ASSUME ) {
233
+ return this . parseAssume ( )
167
234
}
168
235
return null ;
169
236
}
0 commit comments