2019-06-23 05:21:30 +03:00
|
|
|
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
|
|
|
// Use of this source code is governed by an MIT license
|
|
|
|
// that can be found in the LICENSE file.
|
|
|
|
|
2019-06-22 21:20:28 +03:00
|
|
|
module main
|
|
|
|
|
|
|
|
enum Token {
|
2019-07-07 23:30:15 +03:00
|
|
|
eof
|
2019-08-17 22:19:37 +03:00
|
|
|
name // user
|
|
|
|
number // 123
|
|
|
|
str // 'foo'
|
|
|
|
str_inter // 'name=$user.name'
|
|
|
|
chartoken // `A`
|
2019-07-07 23:30:15 +03:00
|
|
|
plus
|
|
|
|
minus
|
|
|
|
mul
|
|
|
|
div
|
|
|
|
mod
|
2019-08-17 22:19:37 +03:00
|
|
|
xor // ^
|
|
|
|
pipe // |
|
|
|
|
inc // ++
|
|
|
|
dec // --
|
|
|
|
and // &&
|
|
|
|
logical_or
|
|
|
|
not
|
2019-07-07 23:30:15 +03:00
|
|
|
bit_not
|
|
|
|
question
|
|
|
|
comma
|
|
|
|
semicolon
|
|
|
|
colon
|
2019-08-17 22:19:37 +03:00
|
|
|
arrow // =>
|
2019-07-07 23:30:15 +03:00
|
|
|
amp
|
|
|
|
hash
|
|
|
|
dollar
|
|
|
|
left_shift
|
|
|
|
righ_shift
|
2019-08-17 22:19:37 +03:00
|
|
|
//at // @
|
2019-06-22 21:20:28 +03:00
|
|
|
// = := += -=
|
2019-07-07 23:30:15 +03:00
|
|
|
assign
|
|
|
|
decl_assign
|
|
|
|
plus_assign
|
|
|
|
minus_assign
|
|
|
|
div_assign
|
|
|
|
mult_assign
|
|
|
|
xor_assign
|
|
|
|
mod_assign
|
|
|
|
or_assign
|
|
|
|
and_assign
|
|
|
|
righ_shift_assign
|
|
|
|
left_shift_assign
|
2019-06-22 21:20:28 +03:00
|
|
|
// {} () []
|
2019-07-07 23:30:15 +03:00
|
|
|
lcbr
|
|
|
|
rcbr
|
|
|
|
lpar
|
|
|
|
rpar
|
|
|
|
lsbr
|
|
|
|
rsbr
|
2019-06-22 21:20:28 +03:00
|
|
|
// == != <= < >= >
|
2019-07-07 23:30:15 +03:00
|
|
|
eq
|
|
|
|
ne
|
|
|
|
gt
|
|
|
|
lt
|
|
|
|
ge
|
|
|
|
le
|
2019-06-22 21:20:28 +03:00
|
|
|
// comments
|
2019-08-17 22:19:37 +03:00
|
|
|
//line_com
|
|
|
|
//mline_com
|
|
|
|
nl
|
|
|
|
dot
|
2019-07-07 23:30:15 +03:00
|
|
|
dotdot
|
2019-06-22 21:20:28 +03:00
|
|
|
// keywords
|
|
|
|
keyword_beg
|
2019-07-14 12:01:32 +03:00
|
|
|
key_as
|
|
|
|
key_assert
|
|
|
|
key_atomic
|
|
|
|
key_break
|
|
|
|
key_case
|
2019-07-07 23:30:15 +03:00
|
|
|
key_const
|
2019-07-14 12:01:32 +03:00
|
|
|
key_continue
|
2019-08-17 22:19:37 +03:00
|
|
|
key_default
|
|
|
|
key_defer
|
2019-07-14 12:01:32 +03:00
|
|
|
key_else
|
|
|
|
key_embed
|
2019-07-07 23:30:15 +03:00
|
|
|
key_enum
|
2019-07-14 12:01:32 +03:00
|
|
|
key_false
|
2019-07-07 23:30:15 +03:00
|
|
|
key_for
|
|
|
|
func
|
2019-07-14 12:01:32 +03:00
|
|
|
key_global
|
|
|
|
key_go
|
2019-08-17 22:19:37 +03:00
|
|
|
key_goto
|
|
|
|
key_if
|
2019-07-07 23:30:15 +03:00
|
|
|
key_import
|
2019-08-17 22:19:37 +03:00
|
|
|
key_import_const
|
|
|
|
key_in
|
|
|
|
key_interface
|
|
|
|
key_match
|
2019-07-14 12:01:32 +03:00
|
|
|
key_module
|
|
|
|
key_mut
|
2019-09-17 22:41:58 +03:00
|
|
|
key_none
|
2019-07-14 12:01:32 +03:00
|
|
|
key_return
|
2019-08-17 22:19:37 +03:00
|
|
|
key_select
|
2019-07-14 12:01:32 +03:00
|
|
|
key_sizeof
|
|
|
|
key_struct
|
2019-08-17 22:19:37 +03:00
|
|
|
key_switch
|
2019-07-14 12:01:32 +03:00
|
|
|
key_true
|
2019-08-17 22:19:37 +03:00
|
|
|
key_type
|
|
|
|
//typeof
|
2019-07-07 23:30:15 +03:00
|
|
|
key_orelse
|
|
|
|
key_union
|
2019-08-17 22:19:37 +03:00
|
|
|
key_pub
|
2019-07-07 23:30:15 +03:00
|
|
|
key_static
|
2019-06-22 21:20:28 +03:00
|
|
|
keyword_end
|
|
|
|
}
|
|
|
|
|
|
|
|
// build_keys genereates a map with keywords' string values:
|
2019-07-07 23:30:15 +03:00
|
|
|
// Keywords['return'] == .key_return
|
2019-07-14 12:01:32 +03:00
|
|
|
fn build_keys() map[string]int {
|
2019-08-17 22:19:37 +03:00
|
|
|
mut res := map[string]int
|
2019-07-07 23:30:15 +03:00
|
|
|
for t := int(Token.keyword_beg) + 1; t < int(Token.keyword_end); t++ {
|
2019-07-14 12:01:32 +03:00
|
|
|
key := TokenStr[t]
|
2019-06-22 21:20:28 +03:00
|
|
|
res[key] = int(t)
|
|
|
|
}
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
2019-08-17 22:19:37 +03:00
|
|
|
// TODO remove once we have `enum Token { name('name') if('if') ... }`
|
2019-06-22 21:20:28 +03:00
|
|
|
fn build_token_str() []string {
|
2019-09-14 23:48:30 +03:00
|
|
|
mut s := [''].repeat2(NrTokens)
|
2019-07-07 23:30:15 +03:00
|
|
|
s[Token.keyword_beg] = ''
|
|
|
|
s[Token.keyword_end] = ''
|
2019-08-16 18:44:35 +03:00
|
|
|
s[Token.eof] = 'eof'
|
|
|
|
s[Token.name] = 'name'
|
|
|
|
s[Token.number] = 'number'
|
2019-07-16 18:59:07 +03:00
|
|
|
s[Token.str] = 'STR'
|
2019-08-16 18:44:35 +03:00
|
|
|
s[Token.chartoken] = 'char'
|
2019-07-07 23:30:15 +03:00
|
|
|
s[Token.plus] = '+'
|
|
|
|
s[Token.minus] = '-'
|
|
|
|
s[Token.mul] = '*'
|
|
|
|
s[Token.div] = '/'
|
|
|
|
s[Token.mod] = '%'
|
|
|
|
s[Token.xor] = '^'
|
|
|
|
s[Token.bit_not] = '~'
|
|
|
|
s[Token.pipe] = '|'
|
|
|
|
s[Token.hash] = '#'
|
|
|
|
s[Token.amp] = '&'
|
|
|
|
s[Token.inc] = '++'
|
|
|
|
s[Token.dec] = '--'
|
|
|
|
s[Token.and] = '&&'
|
2019-07-14 12:01:32 +03:00
|
|
|
s[Token.logical_or] = '||'
|
2019-07-07 23:30:15 +03:00
|
|
|
s[Token.not] = '!'
|
|
|
|
s[Token.dot] = '.'
|
|
|
|
s[Token.dotdot] = '..'
|
|
|
|
s[Token.comma] = ','
|
2019-07-24 03:22:34 +03:00
|
|
|
//s[Token.at] = '@'
|
2019-07-07 23:30:15 +03:00
|
|
|
s[Token.semicolon] = ';'
|
|
|
|
s[Token.colon] = ':'
|
2019-07-17 02:43:59 +03:00
|
|
|
s[Token.arrow] = '=>'
|
2019-07-07 23:30:15 +03:00
|
|
|
s[Token.assign] = '='
|
|
|
|
s[Token.decl_assign] = ':='
|
|
|
|
s[Token.plus_assign] = '+='
|
|
|
|
s[Token.minus_assign] = '-='
|
|
|
|
s[Token.mult_assign] = '*='
|
|
|
|
s[Token.div_assign] = '/='
|
|
|
|
s[Token.xor_assign] = '^='
|
|
|
|
s[Token.mod_assign] = '%='
|
|
|
|
s[Token.or_assign] = '|='
|
|
|
|
s[Token.and_assign] = '&='
|
|
|
|
s[Token.righ_shift_assign] = '>>='
|
|
|
|
s[Token.left_shift_assign] = '<<='
|
|
|
|
s[Token.lcbr] = '{'
|
|
|
|
s[Token.rcbr] = '}'
|
|
|
|
s[Token.lpar] = '('
|
|
|
|
s[Token.rpar] = ')'
|
|
|
|
s[Token.lsbr] = '['
|
|
|
|
s[Token.rsbr] = ']'
|
|
|
|
s[Token.eq] = '=='
|
|
|
|
s[Token.ne] = '!='
|
|
|
|
s[Token.gt] = '>'
|
|
|
|
s[Token.lt] = '<'
|
|
|
|
s[Token.ge] = '>='
|
|
|
|
s[Token.le] = '<='
|
|
|
|
s[Token.question] = '?'
|
|
|
|
s[Token.left_shift] = '<<'
|
|
|
|
s[Token.righ_shift] = '>>'
|
2019-07-16 18:59:07 +03:00
|
|
|
//s[Token.line_com] = '//'
|
2019-07-07 23:30:15 +03:00
|
|
|
s[Token.nl] = 'NLL'
|
|
|
|
s[Token.dollar] = '$'
|
|
|
|
s[Token.key_assert] = 'assert'
|
|
|
|
s[Token.key_struct] = 'struct'
|
|
|
|
s[Token.key_if] = 'if'
|
|
|
|
s[Token.key_else] = 'else'
|
|
|
|
s[Token.key_return] = 'return'
|
|
|
|
s[Token.key_module] = 'module'
|
|
|
|
s[Token.key_sizeof] = 'sizeof'
|
|
|
|
s[Token.key_go] = 'go'
|
|
|
|
s[Token.key_goto] = 'goto'
|
|
|
|
s[Token.key_const] = 'const'
|
|
|
|
s[Token.key_mut] = 'mut'
|
2019-07-16 13:17:17 +03:00
|
|
|
s[Token.key_type] = 'type'
|
2019-07-07 23:30:15 +03:00
|
|
|
s[Token.key_for] = 'for'
|
|
|
|
s[Token.key_switch] = 'switch'
|
|
|
|
s[Token.key_case] = 'case'
|
|
|
|
s[Token.func] = 'fn'
|
|
|
|
s[Token.key_true] = 'true'
|
|
|
|
s[Token.key_false] = 'false'
|
|
|
|
s[Token.key_continue] = 'continue'
|
|
|
|
s[Token.key_break] = 'break'
|
|
|
|
s[Token.key_import] = 'import'
|
|
|
|
s[Token.key_embed] = 'embed'
|
2019-08-16 18:44:35 +03:00
|
|
|
//Tokens[key_typeof] = 'typeof'
|
2019-07-07 23:30:15 +03:00
|
|
|
s[Token.key_default] = 'default'
|
|
|
|
s[Token.key_enum] = 'enum'
|
|
|
|
s[Token.key_interface] = 'interface'
|
|
|
|
s[Token.key_pub] = 'pub'
|
|
|
|
s[Token.key_import_const] = 'import_const'
|
|
|
|
s[Token.key_in] = 'in'
|
|
|
|
s[Token.key_atomic] = 'atomic'
|
|
|
|
s[Token.key_orelse] = 'or'
|
|
|
|
s[Token.key_global] = '__global'
|
|
|
|
s[Token.key_union] = 'union'
|
|
|
|
s[Token.key_static] = 'static'
|
2019-07-13 13:15:16 +03:00
|
|
|
s[Token.key_as] = 'as'
|
2019-07-15 23:09:34 +03:00
|
|
|
s[Token.key_defer] = 'defer'
|
2019-07-17 02:43:59 +03:00
|
|
|
s[Token.key_match] = 'match'
|
2019-08-09 19:10:59 +03:00
|
|
|
s[Token.key_select] = 'select'
|
2019-09-17 22:41:58 +03:00
|
|
|
s[Token.key_none] = 'none'
|
2019-06-22 21:20:28 +03:00
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
2019-07-03 10:14:10 +03:00
|
|
|
NrTokens = 140
|
2019-07-14 12:01:32 +03:00
|
|
|
TokenStr = build_token_str()
|
2019-06-22 21:20:28 +03:00
|
|
|
KEYWORDS = build_keys()
|
|
|
|
)
|
|
|
|
|
|
|
|
fn key_to_token(key string) Token {
|
|
|
|
a := Token(KEYWORDS[key])
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_key(key string) bool {
|
|
|
|
return int(key_to_token(key)) > 0
|
|
|
|
}
|
|
|
|
|
|
|
|
fn (t Token) str() string {
|
2019-07-14 12:01:32 +03:00
|
|
|
return TokenStr[int(t)]
|
2019-06-22 21:20:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn (t Token) is_decl() bool {
|
2019-07-14 12:01:32 +03:00
|
|
|
// TODO i
|
2019-08-17 22:19:37 +03:00
|
|
|
//return t in [.key_enum, .key_interface, .func, .typ, .key_const,
|
2019-07-14 12:01:32 +03:00
|
|
|
//.key_import_const, .key_struct, .key_pub, .eof]
|
2019-08-17 22:19:37 +03:00
|
|
|
return t == .key_enum || t == .key_interface || t == .func ||
|
2019-07-16 13:17:17 +03:00
|
|
|
t == .key_struct || t == .key_type ||
|
2019-07-07 23:30:15 +03:00
|
|
|
t == .key_const || t == .key_import_const || t == .key_pub || t == .eof
|
2019-06-22 21:20:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
|
|
|
AssignTokens = [
|
2019-07-07 23:30:15 +03:00
|
|
|
Token.assign, Token.plus_assign, Token.minus_assign,
|
2019-08-17 22:19:37 +03:00
|
|
|
Token.mult_assign, Token.div_assign, Token.xor_assign,
|
2019-07-07 23:30:15 +03:00
|
|
|
Token.mod_assign,
|
|
|
|
Token.or_assign, Token.and_assign, Token.righ_shift_assign,
|
|
|
|
Token.left_shift_assign
|
2019-06-22 21:20:28 +03:00
|
|
|
]
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
fn (t Token) is_assign() bool {
|
|
|
|
return t in AssignTokens
|
|
|
|
}
|
|
|
|
|
2019-06-30 14:06:46 +03:00
|
|
|
fn (t []Token) contains(val Token) bool {
|
2019-06-22 21:20:28 +03:00
|
|
|
for tt in t {
|
|
|
|
if tt == val {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|