mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
re-write map.v and update the compiler
This commit is contained in:
@ -13,6 +13,7 @@ const (
|
||||
struct Fn {
|
||||
// addr int
|
||||
mut:
|
||||
name string
|
||||
pkg string
|
||||
local_vars []Var
|
||||
var_idx int
|
||||
@ -22,7 +23,6 @@ mut:
|
||||
// idx int
|
||||
scope_level int
|
||||
typ string // return type
|
||||
name string
|
||||
is_c bool
|
||||
receiver_typ string
|
||||
is_public bool
|
||||
|
@ -356,8 +356,7 @@ string _STR_TMP(const char *fmt, ...) {
|
||||
// Generate `main` which calls every single test function
|
||||
else if v.pref.is_test {
|
||||
cgen.genln('int main() { init_consts();')
|
||||
for entry in v.table.fns.entries {
|
||||
f := v.table.fns[entry.key]
|
||||
for key, f in v.table.fns {
|
||||
if f.name.starts_with('test_') {
|
||||
cgen.genln('$f.name();')
|
||||
}
|
||||
@ -680,7 +679,7 @@ fn (v &V) v_files_from_dir(dir string) []string {
|
||||
if file.ends_with('_mac.v') && v.os != .mac {
|
||||
lin_file := file.replace('_mac.v', '_lin.v')
|
||||
// println('lin_file="$lin_file"')
|
||||
// If there are both _mav.v and _lin.v, don't use _mav.v
|
||||
// If there are both _mac.v and _lin.v, don't use _mav.v
|
||||
if os.file_exists('$dir/$lin_file') {
|
||||
continue
|
||||
}
|
||||
@ -1035,7 +1034,7 @@ fn run_repl() []string {
|
||||
mut temp_line := line
|
||||
mut temp_flag := false
|
||||
if !(line.contains(' ') || line.contains(':') || line.contains('=') || line.contains(',') ){
|
||||
temp_line = 'println('+line+')'
|
||||
temp_line = 'println($line)'
|
||||
temp_flag = true
|
||||
}
|
||||
temp_source_code := lines.join('\n') + '\n' + temp_line
|
||||
@ -1064,7 +1063,6 @@ fn run_repl() []string {
|
||||
return lines
|
||||
}
|
||||
|
||||
// This definitely needs to be better :)
|
||||
const (
|
||||
HelpText = '
|
||||
Usage: v [options] [file | directory]
|
||||
@ -1077,8 +1075,7 @@ Options:
|
||||
-prod Build an optimized executable.
|
||||
-o <file> Place output into <file>.
|
||||
-obf Obfuscate the resulting binary.
|
||||
run Build and execute a V program.
|
||||
You can add arguments after file name.
|
||||
run Build and execute a V program. You can add arguments after file name.
|
||||
|
||||
Files:
|
||||
<file>_test.v Test file.
|
||||
|
@ -1200,7 +1200,7 @@ fn (p mut Parser) var_decl() {
|
||||
fn (p mut Parser) bool_expression() string {
|
||||
tok := p.tok
|
||||
typ := p.bterm()
|
||||
for p.tok == .and || p.tok == .ortok {
|
||||
for p.tok == .and || p.tok == .logical_or {
|
||||
p.gen(' ${p.tok.str()} ')
|
||||
p.check_space(p.tok)
|
||||
p.check_types(p.bterm(), typ)
|
||||
@ -2916,10 +2916,21 @@ fn (p mut Parser) for_st() {
|
||||
is_mut: true
|
||||
}
|
||||
p.register_var(i_var)
|
||||
p.genln('array_string keys_$tmp = map_keys(& $tmp ); ')
|
||||
p.genln('for (int l = 0; l < keys_$tmp .len; l++) {')
|
||||
p.genln(' string $i = ((string*)keys_$tmp .data)[l];')
|
||||
//p.genln(' string $i = *(string*) ( array__get(keys_$tmp, l) );')
|
||||
def := type_default(var_typ)
|
||||
// TODO don't call map_get() for each key, fetch values while traversing
|
||||
// the tree (replace `map_keys()` above with `map_key_vals()`)
|
||||
p.genln('$var_typ $val = $def; map_get($tmp, $i, & $val);')
|
||||
|
||||
/*
|
||||
p.genln('for (int l = 0; l < $tmp . entries.len; l++) {')
|
||||
p.genln('Entry entry = *((Entry*) (array__get($tmp .entries, l)));')
|
||||
p.genln('string $i = entry.key;')
|
||||
p.genln('$var_typ $val; map_get($tmp, $i, & $val);')
|
||||
*/
|
||||
}
|
||||
}
|
||||
// `for val in vals`
|
||||
|
@ -344,7 +344,7 @@ fn (s mut Scanner) scan() ScanRes {
|
||||
case `|`:
|
||||
if nextc == `|` {
|
||||
s.pos++
|
||||
return scan_res(.ortok, '')
|
||||
return scan_res(.logical_or, '')
|
||||
}
|
||||
if nextc == `=` {
|
||||
s.pos++
|
||||
|
@ -565,8 +565,7 @@ fn (t &Table) is_interface(name string) bool {
|
||||
|
||||
// Do we have fn main()?
|
||||
fn (t &Table) main_exists() bool {
|
||||
for entry in t.fns.entries {
|
||||
f := t.fns[entry.key]
|
||||
for _, f in t.fns {
|
||||
if f.name == 'main' {
|
||||
return true
|
||||
}
|
||||
@ -696,11 +695,11 @@ fn (fit mut FileImportTable) register_import(mod string) {
|
||||
}
|
||||
|
||||
fn (fit mut FileImportTable) register_alias(alias string, mod string) {
|
||||
if !fit.imports.exists(alias) {
|
||||
fit.imports[alias] = mod
|
||||
} else {
|
||||
panic('Cannot import $mod as $alias: import name $alias already in use in "${fit.file_path}".')
|
||||
}
|
||||
if fit.imports.exists(alias) {
|
||||
panic('cannot import $mod as $alias: import name $alias already in use in "${fit.file_path}".')
|
||||
return
|
||||
}
|
||||
fit.imports[alias] = mod
|
||||
}
|
||||
|
||||
fn (fit &FileImportTable) known_alias(alias string) bool {
|
||||
@ -708,10 +707,10 @@ fn (fit &FileImportTable) known_alias(alias string) bool {
|
||||
}
|
||||
|
||||
fn (fit &FileImportTable) is_aliased(mod string) bool {
|
||||
for i in fit.imports.keys() {
|
||||
if fit.imports[i] == mod {
|
||||
return true
|
||||
}
|
||||
for _, val in fit.imports {
|
||||
if val == mod {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ enum Token {
|
||||
inc
|
||||
dec
|
||||
and
|
||||
ortok
|
||||
logical_or
|
||||
not
|
||||
bit_not
|
||||
question
|
||||
@ -67,51 +67,51 @@ enum Token {
|
||||
dotdot
|
||||
// keywords
|
||||
keyword_beg
|
||||
key_module
|
||||
key_struct
|
||||
key_if
|
||||
key_else
|
||||
key_return
|
||||
key_go
|
||||
key_const
|
||||
key_import_const
|
||||
key_mut
|
||||
typ
|
||||
key_enum
|
||||
key_for
|
||||
key_switch
|
||||
MATCH
|
||||
key_case
|
||||
func
|
||||
key_true
|
||||
key_false
|
||||
key_continue
|
||||
key_break
|
||||
key_embed
|
||||
key_import
|
||||
//typeof
|
||||
key_default
|
||||
key_as
|
||||
key_assert
|
||||
key_sizeof
|
||||
key_in
|
||||
key_atomic
|
||||
key_interface
|
||||
key_orelse
|
||||
key_break
|
||||
key_case
|
||||
key_const
|
||||
key_continue
|
||||
key_default
|
||||
key_else
|
||||
key_embed
|
||||
key_enum
|
||||
key_false
|
||||
key_for
|
||||
func
|
||||
key_global
|
||||
key_go
|
||||
key_goto
|
||||
key_if
|
||||
key_import
|
||||
key_import_const
|
||||
key_in
|
||||
key_interface
|
||||
MATCH
|
||||
key_module
|
||||
key_mut
|
||||
key_return
|
||||
key_sizeof
|
||||
key_struct
|
||||
key_switch
|
||||
key_true
|
||||
typ
|
||||
//typeof
|
||||
key_orelse
|
||||
key_union
|
||||
key_pub
|
||||
key_goto
|
||||
key_static
|
||||
key_as
|
||||
keyword_end
|
||||
}
|
||||
|
||||
// build_keys genereates a map with keywords' string values:
|
||||
// Keywords['return'] == .key_return
|
||||
fn build_keys() map_int {
|
||||
fn build_keys() map[string]int {
|
||||
mut res := map[string]int{}
|
||||
for t := int(Token.keyword_beg) + 1; t < int(Token.keyword_end); t++ {
|
||||
key := TOKENSTR[t]
|
||||
key := TokenStr[t]
|
||||
res[key] = int(t)
|
||||
}
|
||||
return res
|
||||
@ -140,7 +140,7 @@ fn build_token_str() []string {
|
||||
s[Token.inc] = '++'
|
||||
s[Token.dec] = '--'
|
||||
s[Token.and] = '&&'
|
||||
s[Token.ortok] = '||'
|
||||
s[Token.logical_or] = '||'
|
||||
s[Token.not] = '!'
|
||||
s[Token.dot] = '.'
|
||||
s[Token.dotdot] = '..'
|
||||
@ -218,7 +218,7 @@ fn build_token_str() []string {
|
||||
|
||||
const (
|
||||
NrTokens = 140
|
||||
TOKENSTR = build_token_str()
|
||||
TokenStr = build_token_str()
|
||||
KEYWORDS = build_keys()
|
||||
)
|
||||
|
||||
@ -232,11 +232,13 @@ fn is_key(key string) bool {
|
||||
}
|
||||
|
||||
fn (t Token) str() string {
|
||||
return TOKENSTR[int(t)]
|
||||
return TokenStr[int(t)]
|
||||
}
|
||||
|
||||
fn (t Token) is_decl() bool {
|
||||
// TODO return t in [.func ,.typ, .key_const, .key_import_.key_const ,AT ,.eof]
|
||||
// TODO i
|
||||
//return t in [.key_enum, .key_interface, .func, .typ, .key_const,
|
||||
//.key_import_const, .key_struct, .key_pub, .eof]
|
||||
return t == .key_enum || t == .key_interface || t == .func ||
|
||||
t == .key_struct || t == .typ ||
|
||||
t == .key_const || t == .key_import_const || t == .key_pub || t == .eof
|
||||
|
Reference in New Issue
Block a user