vbscript: Added simple call test.
[wine] / dlls / vbscript / lex.c
1 /*
2  * Copyright 2011 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <assert.h>
20
21 #include "vbscript.h"
22 #include "parse.h"
23 #include "parser.tab.h"
24
25 #include "wine/debug.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
28
29 static inline BOOL is_identifier_char(WCHAR c)
30 {
31     return isalnumW(c) || c == '_';
32 }
33
34 static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret)
35 {
36     const WCHAR *ptr = ctx->ptr++;
37     WCHAR *str;
38     int len;
39
40     while(ctx->ptr < ctx->end && is_identifier_char(*ctx->ptr))
41         ctx->ptr++;
42     len = ctx->ptr-ptr;
43
44     str = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
45     if(!str)
46         return 0;
47
48     memcpy(str, ptr, (len+1)*sizeof(WCHAR));
49     str[len] = 0;
50     *ret = str;
51     return tIdentifier;
52 }
53
54 static int parse_next_token(void *lval, parser_ctx_t *ctx)
55 {
56     WCHAR c;
57
58     while(*ctx->ptr == ' ' || *ctx->ptr == '\t' || *ctx->ptr == '\r')
59         ctx->ptr++;
60     if(ctx->ptr == ctx->end)
61         return ctx->last_token == tNL ? tEOF : tNL;
62
63     c = *ctx->ptr;
64
65     if(isalphaW(c))
66         return parse_identifier(ctx, lval);
67
68     switch(c) {
69     case '\n':
70         ctx->ptr++;
71         return tNL;
72     case '\'':
73         ctx->ptr = strchrW(ctx->ptr, '\n');
74         if(ctx->ptr)
75             ctx->ptr++;
76         else
77             ctx->ptr = ctx->end;
78         return tNL;
79     default:
80         FIXME("Unhandled char %c in %s\n", *ctx->ptr, debugstr_w(ctx->ptr));
81     }
82
83     return 0;
84 }
85
86 int parser_lex(void *lval, parser_ctx_t *ctx)
87 {
88     int ret;
89
90     while(1) {
91         ret = parse_next_token(lval, ctx);
92         if(ret != tNL || ctx->last_token != tNL)
93             break;
94
95         ctx->last_nl = ctx->ptr-ctx->code;
96     }
97
98     return (ctx->last_token = ret);
99 }