@@ -24,13 +24,19 @@ struct Token {
24
24
25
25
// 現在着目しているトークン
26
26
Token * token ;
27
+ char * user_input ;
27
28
28
29
// エラーを報告するための関数
29
30
// printfと同じ引数を取る
30
- void error ( char * fmt , ...) {
31
+ void error_at ( char * loc , char * fmt , ...) {
31
32
va_list ap ;
32
33
va_start (ap , fmt );
33
- vfprintf (stderr , fmt , ap );
34
+
35
+ int pos = loc - user_input ;
36
+ fprintf (stderr , "%s\n" , user_input );
37
+ fprintf (stderr , "%*s" , pos , " " );
38
+ fprintf (stderr , "^ " );
39
+ fprintf (stderr , fmt , ap );
34
40
fprintf (stderr , "\n" );
35
41
exit (1 );
36
42
}
@@ -48,15 +54,15 @@ bool consume(char op) {
48
54
// それ以外の場合にはエラーを報告する。
49
55
void expect (char op ) {
50
56
if (token -> kind != TK_RESERVED || token -> str [0 ] != op )
51
- error ( "'%c'ではありません" , op );
57
+ error_at ( token -> str , "'%c'ではありません" , op );
52
58
token = token -> next ;
53
59
}
54
60
55
61
// 次のトークンが数値の場合、トークンを1つ読み進めてその数値を返す。
56
62
// それ以外の場合にはエラーを報告する。
57
63
int expect_number () {
58
64
if (token -> kind != TK_NUM )
59
- error ( "数ではありません" );
65
+ error_at ( token -> str , "数ではありません" );
60
66
int val = token -> val ;
61
67
token = token -> next ;
62
68
return val ;
@@ -99,7 +105,7 @@ Token *tokenize(char *p) {
99
105
continue ;
100
106
}
101
107
102
- error ( "トークナイズできません" );
108
+ error_at ( token -> str , "トークナイズできません" );
103
109
}
104
110
105
111
new_token (TK_EOF , cur , p );
@@ -108,11 +114,12 @@ Token *tokenize(char *p) {
108
114
109
115
int main (int argc , char * * argv ) {
110
116
if (argc != 2 ) {
111
- error ( "引数の個数が正しくありません" );
117
+ error_at ( token -> str , "引数の個数が正しくありません" );
112
118
return 1 ;
113
119
}
114
120
115
121
// トークナイズする
122
+ user_input = argv [1 ];
116
123
token = tokenize (argv [1 ]);
117
124
118
125
// アセンブリの前半部分を出力
0 commit comments