all: mutability check (part 1); enable mutable sumtype args
parent
1ee0939f69
commit
624f22e27e
|
@ -145,7 +145,7 @@ pub fn (a array) repeat(count int) array {
|
|||
|
||||
// array.sort sorts array in-place using given `compare` function as comparator
|
||||
pub fn (mut a array) sort_with_compare(compare voidptr) {
|
||||
C.qsort(a.data, a.len, a.element_size, compare)
|
||||
C.qsort(mut a.data, a.len, a.element_size, compare)
|
||||
}
|
||||
|
||||
// array.insert
|
||||
|
|
|
@ -274,7 +274,7 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 {
|
|||
e10 = int(q) + e2
|
||||
i := -e2 - int(q)
|
||||
k := pow5_bits(i) - pow5_num_bits_64
|
||||
mut j := int(q) - k
|
||||
j := int(q) - k
|
||||
mul := pow5_split_64[i]
|
||||
vr = mul_shift_64(u64(4) * m2 , mul, j)
|
||||
vp = mul_shift_64(u64(4) * m2 + u64(2) , mul, j)
|
||||
|
|
|
@ -777,7 +777,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
if ch in [`f`, `F`] {
|
||||
v_sprintf_panic(p_index, pt.len)
|
||||
x := unsafe {*(&f64(pt[p_index]))}
|
||||
mut positive := x >= f64(0.0)
|
||||
positive := x >= f64(0.0)
|
||||
len1 = if len1 >= 0 { len1 } else { def_len1 }
|
||||
s := format_fl(f64(x), {pad_ch: pad_ch, len0: len0, len1: len1, positive: positive, sign_flag: sign, allign: allign})
|
||||
res.write(if ch == `F` {s.to_upper()} else {s})
|
||||
|
@ -789,7 +789,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
else if ch in [`e`, `E`] {
|
||||
v_sprintf_panic(p_index, pt.len)
|
||||
x := unsafe {*(&f64(pt[p_index]))}
|
||||
mut positive := x >= f64(0.0)
|
||||
positive := x >= f64(0.0)
|
||||
len1 = if len1 >= 0 { len1 } else { def_len1 }
|
||||
s := format_es(f64(x), {pad_ch: pad_ch, len0: len0, len1: len1, positive: positive, sign_flag: sign, allign: allign})
|
||||
res.write(if ch == `E` {s.to_upper()} else {s})
|
||||
|
@ -801,7 +801,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||
else if ch in [`g`, `G`] {
|
||||
v_sprintf_panic(p_index, pt.len)
|
||||
x := unsafe {*(&f64(pt[p_index]))}
|
||||
mut positive := x >= f64(0.0)
|
||||
positive := x >= f64(0.0)
|
||||
mut s := ""
|
||||
tx := fabs(x)
|
||||
if tx < 999_999.0 && tx >= 0.00001 {
|
||||
|
|
|
@ -55,17 +55,17 @@ pub fn parse_rfc2822(s string) ?Time {
|
|||
// also checks and support for leapseconds should be added in future PR
|
||||
pub fn parse_iso8601(s string) ?Time {
|
||||
|
||||
mut year := 0
|
||||
mut month := 0
|
||||
mut day := 0
|
||||
mut hour := 0
|
||||
mut minute := 0
|
||||
mut second := 0
|
||||
mut mic_second := 0
|
||||
mut time_char := `a`
|
||||
mut plus_min := `a`
|
||||
mut offset_hour := 0
|
||||
mut offset_min := 0
|
||||
year := 0
|
||||
month := 0
|
||||
day := 0
|
||||
hour := 0
|
||||
minute := 0
|
||||
second := 0
|
||||
mic_second := 0
|
||||
time_char := `a`
|
||||
plus_min := `a`
|
||||
offset_hour := 0
|
||||
offset_min := 0
|
||||
|
||||
count := unsafe {C.sscanf(charptr(s.str), "%4d-%2d-%2d%c%2d:%2d:%2d.%6d%c%2d:%2d", &year, &month, &day,
|
||||
&time_char, &hour, &minute,
|
||||
|
|
|
@ -12,9 +12,9 @@ pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl
|
|||
pub type Expr = AnonFn | ArrayInit | AsCast | Assoc | BoolLiteral | CallExpr | CastExpr |
|
||||
ChanInit | CharLiteral | Comment | ComptimeCall | ConcatExpr | EnumVal | FloatLiteral |
|
||||
Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr |
|
||||
MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr | SelectExpr |
|
||||
SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | StringLiteral | StructInit | Type |
|
||||
TypeOf | UnsafeExpr
|
||||
MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr |
|
||||
SelectExpr | SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | StringLiteral | StructInit |
|
||||
Type | TypeOf | UnsafeExpr
|
||||
|
||||
pub type Stmt = AssertStmt | AssignStmt | Block | BranchStmt | CompFor | ConstDecl | DeferStmt |
|
||||
EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt |
|
||||
|
@ -966,7 +966,8 @@ pub fn (expr Expr) is_blank_ident() bool {
|
|||
|
||||
pub fn (expr Expr) position() token.Position {
|
||||
// all uncommented have to be implemented
|
||||
match mut expr {
|
||||
match expr {
|
||||
// KEKW2
|
||||
AnonFn {
|
||||
return expr.decl.pos
|
||||
}
|
||||
|
@ -1151,16 +1152,12 @@ pub fn (stmt Stmt) position() token.Position {
|
|||
// field table.Field.default_expr, which should be ast.Expr
|
||||
pub fn fe2ex(x table.FExpr) Expr {
|
||||
res := Expr{}
|
||||
unsafe {
|
||||
C.memcpy(&res, &x, sizeof(Expr))
|
||||
}
|
||||
unsafe {C.memcpy(&res, &x, sizeof(Expr))}
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn ex2fe(x Expr) table.FExpr {
|
||||
res := table.FExpr{}
|
||||
unsafe {
|
||||
C.memcpy(&res, &x, sizeof(table.FExpr))
|
||||
}
|
||||
unsafe {C.memcpy(&res, &x, sizeof(table.FExpr))}
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -37,8 +37,7 @@ pub fn (s &Scope) find_with_scope(name string) ?(ScopeObject, &Scope) {
|
|||
}
|
||||
|
||||
pub fn (s &Scope) find(name string) ?ScopeObject {
|
||||
for sc := s; true; sc = sc.parent
|
||||
{
|
||||
for sc := s; true; sc = sc.parent {
|
||||
if name in sc.objects {
|
||||
return sc.objects[name]
|
||||
}
|
||||
|
@ -85,6 +84,7 @@ pub fn (s &Scope) known_var(name string) bool {
|
|||
}
|
||||
|
||||
pub fn (mut s Scope) update_var_type(name string, typ table.Type) {
|
||||
s.end_pos = s.end_pos // TODO mut bug
|
||||
match mut s.objects[name] {
|
||||
Var {
|
||||
if it.typ == typ {
|
||||
|
|
100
vlib/v/ast/str.v
100
vlib/v/ast/str.v
|
@ -13,17 +13,12 @@ pub fn (node &FnDecl) modname() string {
|
|||
}
|
||||
mut pamod := node.name.all_before_last('.')
|
||||
if pamod == node.name.after('.') {
|
||||
pamod = if node.is_builtin {
|
||||
'builtin'
|
||||
} else {
|
||||
'main'
|
||||
}
|
||||
pamod = if node.is_builtin { 'builtin' } else { 'main' }
|
||||
}
|
||||
return pamod
|
||||
}
|
||||
|
||||
// These methods are used only by vfmt, vdoc, and for debugging.
|
||||
|
||||
pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string {
|
||||
mut f := strings.new_builder(30)
|
||||
if node.is_pub {
|
||||
|
@ -32,7 +27,7 @@ pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string {
|
|||
mut receiver := ''
|
||||
if node.is_method {
|
||||
mut styp := util.no_cur_mod(t.type_to_str(node.receiver.typ), cur_mod)
|
||||
mut m := if node.rec_mut { node.receiver.typ.share().str() + ' ' } else { '' }
|
||||
m := if node.rec_mut { node.receiver.typ.share().str() + ' ' } else { '' }
|
||||
if node.rec_mut {
|
||||
styp = styp[1..] // remove &
|
||||
}
|
||||
|
@ -51,11 +46,10 @@ pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string {
|
|||
mut name := if node.is_anon { '' } else { node.name.after('.') }
|
||||
if node.language == .c {
|
||||
name = 'C.$name'
|
||||
}
|
||||
else if node.language == .js {
|
||||
} else if node.language == .js {
|
||||
name = 'JS.$name'
|
||||
}
|
||||
f.write('fn ${receiver}${name}')
|
||||
f.write('fn $receiver$name')
|
||||
if node.is_generic {
|
||||
f.write('<T>')
|
||||
}
|
||||
|
@ -70,8 +64,8 @@ pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string {
|
|||
continue
|
||||
}
|
||||
is_last_arg := i == node.args.len - 1
|
||||
should_add_type := is_last_arg || node.args[i + 1].typ != arg.typ || (node.is_variadic &&
|
||||
i == node.args.len - 2)
|
||||
should_add_type := is_last_arg || node.args[i + 1].typ != arg.typ ||
|
||||
(node.is_variadic && i == node.args.len - 2)
|
||||
if arg.is_mut {
|
||||
f.write(arg.typ.share().str() + ' ')
|
||||
}
|
||||
|
@ -105,7 +99,7 @@ pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string {
|
|||
}
|
||||
|
||||
pub fn (x &InfixExpr) str() string {
|
||||
return '${x.left.str()} $x.op.str() ${x.right.str()}'
|
||||
return '$x.left.str() $x.op.str() $x.right.str()'
|
||||
}
|
||||
|
||||
// Expressions in string interpolations may have to be put in braces if they
|
||||
|
@ -116,10 +110,10 @@ pub fn (x &InfixExpr) str() string {
|
|||
// This method creates the format specifier (including the colon) or an empty
|
||||
// string if none is needed and also returns (as bool) if the expression
|
||||
// must be enclosed in braces.
|
||||
|
||||
pub fn (lit &StringInterLiteral) get_fspec_braces(i int) (string, bool) {
|
||||
mut res := []string{}
|
||||
needs_fspec := lit.need_fmts[i] || lit.pluss[i] || (lit.fills[i] && lit.fwidths[i] >= 0) || lit.fwidths[i] != 0 || lit.precisions[i] != 0
|
||||
needs_fspec := lit.need_fmts[i] || lit.pluss[i] ||
|
||||
(lit.fills[i] && lit.fwidths[i] >= 0) || lit.fwidths[i] != 0 || lit.precisions[i] != 0
|
||||
mut needs_braces := needs_fspec
|
||||
if !needs_braces {
|
||||
if i + 1 < lit.vals.len && lit.vals[i + 1].len > 0 {
|
||||
|
@ -181,90 +175,94 @@ pub fn (lit &StringInterLiteral) get_fspec_braces(i int) (string, bool) {
|
|||
pub fn (x Expr) str() string {
|
||||
match x {
|
||||
BoolLiteral {
|
||||
return it.val.str()
|
||||
return x.val.str()
|
||||
}
|
||||
CastExpr {
|
||||
return '${it.typname}(${it.expr.str()})'
|
||||
return '${x.typname}($x.expr.str())'
|
||||
}
|
||||
CallExpr {
|
||||
sargs := args2str(it.args)
|
||||
if it.is_method {
|
||||
return '${it.left.str()}.${it.name}($sargs)'
|
||||
sargs := args2str(x.args)
|
||||
if x.is_method {
|
||||
return '${x.left.str()}.${x.name}($sargs)'
|
||||
}
|
||||
return '${it.mod}.${it.name}($sargs)'
|
||||
return '${x.mod}.${x.name}($sargs)'
|
||||
}
|
||||
CharLiteral {
|
||||
return '`$it.val`'
|
||||
return '`$x.val`'
|
||||
}
|
||||
EnumVal {
|
||||
return '.${it.val}'
|
||||
return '.$x.val'
|
||||
}
|
||||
FloatLiteral {
|
||||
return it.val
|
||||
return x.val
|
||||
}
|
||||
Ident {
|
||||
return it.name
|
||||
return x.name
|
||||
}
|
||||
IndexExpr {
|
||||
return '${it.left.str()}[${it.index.str()}]'
|
||||
return '$x.left.str()[$x.index.str()]'
|
||||
}
|
||||
IntegerLiteral {
|
||||
return it.val
|
||||
return x.val
|
||||
}
|
||||
InfixExpr {
|
||||
return '${it.left.str()} $it.op.str() ${it.right.str()}'
|
||||
return '$x.left.str() $x.op.str() $x.right.str()'
|
||||
}
|
||||
ParExpr {
|
||||
return '($it.expr)'
|
||||
return '($x.expr)'
|
||||
}
|
||||
PrefixExpr {
|
||||
return it.op.str() + it.right.str()
|
||||
return x.op.str() + x.right.str()
|
||||
}
|
||||
RangeExpr {
|
||||
mut s := '..'
|
||||
if it.has_low {s = '$it.low ' + s}
|
||||
if it.has_high {s = s + ' $it.high'}
|
||||
if x.has_low {
|
||||
s = '$x.low ' + s
|
||||
}
|
||||
if x.has_high {
|
||||
s = s + ' $x.high'
|
||||
}
|
||||
return s
|
||||
}
|
||||
SelectorExpr {
|
||||
return '${it.expr.str()}.${it.field_name}'
|
||||
return '${x.expr.str()}.$x.field_name'
|
||||
}
|
||||
SizeOf {
|
||||
return 'sizeof($it.expr)'
|
||||
return 'sizeof($x.expr)'
|
||||
}
|
||||
StringInterLiteral {
|
||||
mut res := []string{}
|
||||
res << "'"
|
||||
for i, val in it.vals {
|
||||
for i, val in x.vals {
|
||||
res << val
|
||||
if i >= it.exprs.len {
|
||||
if i >= x.exprs.len {
|
||||
break
|
||||
}
|
||||
res << '$'
|
||||
fspec_str, needs_braces := it.get_fspec_braces(i)
|
||||
fspec_str, needs_braces := x.get_fspec_braces(i)
|
||||
if needs_braces {
|
||||
res << '{'
|
||||
res << it.exprs[i].str()
|
||||
res << x.exprs[i].str()
|
||||
res << fspec_str
|
||||
res << '}'
|
||||
} else {
|
||||
res << it.exprs[i].str()
|
||||
res << x.exprs[i].str()
|
||||
}
|
||||
}
|
||||
res << "'"
|
||||
return res.join('')
|
||||
}
|
||||
StringLiteral {
|
||||
return '"$it.val"'
|
||||
return '"$x.val"'
|
||||
}
|
||||
TypeOf {
|
||||
return 'typeof(${it.expr.str()})'
|
||||
return 'typeof($x.expr.str())'
|
||||
}
|
||||
Likely {
|
||||
return '_likely_(${it.expr.str()})'
|
||||
return '_likely_($x.expr.str())'
|
||||
}
|
||||
UnsafeExpr {
|
||||
return 'unsafe { $it.expr }'
|
||||
return 'unsafe { $x.expr }'
|
||||
}
|
||||
else {}
|
||||
}
|
||||
|
@ -273,9 +271,9 @@ pub fn (x Expr) str() string {
|
|||
|
||||
pub fn (a CallArg) str() string {
|
||||
if a.is_mut {
|
||||
return 'mut ${a.expr.str()}'
|
||||
return 'mut $a.expr.str()'
|
||||
}
|
||||
return '${a.expr.str()}'
|
||||
return '$a.expr.str()'
|
||||
}
|
||||
|
||||
pub fn args2str(args []CallArg) string {
|
||||
|
@ -290,7 +288,7 @@ pub fn (node Stmt) str() string {
|
|||
match node {
|
||||
AssignStmt {
|
||||
mut out := ''
|
||||
for i, left in it.left {
|
||||
for i, left in node.left {
|
||||
if left is Ident {
|
||||
var_info := left.var_info()
|
||||
if var_info.is_mut {
|
||||
|
@ -302,20 +300,20 @@ pub fn (node Stmt) str() string {
|
|||
out += ','
|
||||
}
|
||||
}
|
||||
out += ' $it.op.str() '
|
||||
for i, val in it.right {
|
||||
out += ' $node.op.str() '
|
||||
for i, val in node.right {
|
||||
out += val.str()
|
||||
if i < it.right.len - 1 {
|
||||
if i < node.right.len - 1 {
|
||||
out += ','
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
ExprStmt {
|
||||
return it.expr.str()
|
||||
return node.expr.str()
|
||||
}
|
||||
FnDecl {
|
||||
return 'fn ${it.name}() { $it.stmts.len stmts }'
|
||||
return 'fn ${node.name}() { $node.stmts.len stmts }'
|
||||
}
|
||||
else {
|
||||
return '[unhandled stmt str type: ${typeof(node)} ]'
|
||||
|
|
|
@ -96,10 +96,11 @@ pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// TODO: fix all of these warnings
|
||||
// if obj.is_mut && !obj.is_changed {
|
||||
// c.warn('`$obj.name` is declared as mutable, but it was never changed', obj.pos)
|
||||
// }
|
||||
if obj.is_mut && !obj.is_changed && !c.is_builtin_mod && obj.name != 'it' {
|
||||
// if obj.is_mut && !obj.is_changed && !c.is_builtin { //TODO C error bad field not checked
|
||||
// c.warn('`$obj.name` is declared as mutable, but it was never changed',
|
||||
// obj.pos)
|
||||
}
|
||||
}
|
||||
else {}
|
||||
}
|
||||
|
@ -555,7 +556,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
|
|||
c.expected_type = former_expected_type
|
||||
}
|
||||
c.expected_type = table.void_type
|
||||
mut left_type := c.expr(infix_expr.left)
|
||||
left_type := c.expr(infix_expr.left)
|
||||
// left_type = c.unwrap_genric(c.expr(infix_expr.left))
|
||||
infix_expr.left_type = left_type
|
||||
c.expected_type = left_type
|
||||
|
@ -816,6 +817,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
|
|||
}
|
||||
|
||||
// returns name and position of variable that needs write lock
|
||||
// also sets `is_changed` to true (TODO update the name to reflect this?)
|
||||
fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) {
|
||||
mut to_lock := '' // name of variable that needs lock
|
||||
mut pos := token.Position{} // and its position
|
||||
|
@ -1518,7 +1520,7 @@ pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type table.Type) t
|
|||
return ret_type
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) check_or_expr(mut or_expr ast.OrExpr, ret_type table.Type) {
|
||||
pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type) {
|
||||
if or_expr.kind == .propagate {
|
||||
if !c.cur_fn.return_type.has_flag(.optional) && c.cur_fn.name != 'main.main' {
|
||||
c.error('to propagate the optional call, `$c.cur_fn.name` must itself return an optional',
|
||||
|
@ -1536,7 +1538,7 @@ pub fn (mut c Checker) check_or_expr(mut or_expr ast.OrExpr, ret_type table.Type
|
|||
// allow `f() or {}`
|
||||
return
|
||||
}
|
||||
mut last_stmt := or_expr.stmts[stmts_len - 1]
|
||||
last_stmt := or_expr.stmts[stmts_len - 1]
|
||||
if ret_type != table.void_type {
|
||||
match mut last_stmt {
|
||||
ast.ExprStmt {
|
||||
|
@ -2932,7 +2934,7 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type {
|
|||
// since it is used in c.match_exprs() it saves checking twice
|
||||
node.cond_type = cond_type
|
||||
if cond_type == 0 {
|
||||
c.error('match 0 cond type', node.pos)
|
||||
c.error('compiler bug: match 0 cond type', node.pos)
|
||||
}
|
||||
cond_type_sym := c.table.get_type_symbol(cond_type)
|
||||
if cond_type_sym.kind !in [.sum_type, .interface_] {
|
||||
|
@ -2981,7 +2983,11 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type {
|
|||
// node.expected_type = c.expected_type
|
||||
// }
|
||||
node.return_type = ret_type
|
||||
// println('!m $expr_type')
|
||||
if node.is_mut {
|
||||
// Mark `x` in `match mut x {` as changed, and ensure it's mutable
|
||||
// TODO2 enable when code is fixed
|
||||
// c.fail_if_immutable(node.cond)
|
||||
}
|
||||
return ret_type
|
||||
}
|
||||
|
||||
|
|
|
@ -568,7 +568,7 @@ fn (p &Parser) fileis(s string) bool {
|
|||
|
||||
fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position) {
|
||||
sym := p.table.get_type_symbol(typ)
|
||||
if sym.kind !in [.array, .struct_, .map, .placeholder] && !typ.is_ptr() {
|
||||
if sym.kind !in [.array, .struct_, .map, .placeholder, .sum_type] && !typ.is_ptr() {
|
||||
p.error_with_pos('mutable arguments are only allowed for arrays, maps, and structs\n' +
|
||||
'return values instead: `fn foo(mut n $sym.name) {` => `fn foo(n $sym.name) $sym.name {`',
|
||||
pos)
|
||||
|
|
|
@ -229,6 +229,7 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
|
|||
typ: typ.to_ptr()
|
||||
pos: cond_pos
|
||||
is_used: true
|
||||
is_changed: true // TODO mut unchanged warning hack, remove
|
||||
is_mut: is_mut
|
||||
})
|
||||
}
|
||||
|
|
|
@ -178,8 +178,8 @@ fn (mut s Scanner) ident_name() string {
|
|||
return name
|
||||
}
|
||||
|
||||
// ident_fn_name look ahead and return name of function if possible, otherwise empty string
|
||||
fn (mut s Scanner) ident_fn_name() string {
|
||||
// ident_fn_name looks ahead and returns name of the function if possible, otherwise an empty string
|
||||
fn (s &Scanner) ident_fn_name() string {
|
||||
start := s.pos
|
||||
mut pos := s.pos
|
||||
pos++
|
||||
|
@ -221,9 +221,8 @@ fn (mut s Scanner) ident_fn_name() string {
|
|||
if pos <= start || pos >= s.text.len {
|
||||
return ''
|
||||
}
|
||||
if s.text[start_pos].is_digit() || end_pos > s.text.len ||
|
||||
end_pos <= start_pos || end_pos <= start ||
|
||||
start_pos < start {
|
||||
if s.text[start_pos].is_digit() || end_pos > s.text.len || end_pos <= start_pos ||
|
||||
end_pos <= start || start_pos < start {
|
||||
return ''
|
||||
}
|
||||
fn_name := s.text[start_pos..end_pos]
|
||||
|
@ -231,7 +230,7 @@ fn (mut s Scanner) ident_fn_name() string {
|
|||
}
|
||||
|
||||
// ident_mod_name look ahead and return name of module this file belongs to if possible, otherwise empty string
|
||||
fn (mut s Scanner) ident_mod_name() string {
|
||||
fn (s &Scanner) ident_mod_name() string {
|
||||
start := s.pos
|
||||
mut pos := s.pos
|
||||
pos++
|
||||
|
@ -259,7 +258,7 @@ fn (mut s Scanner) ident_mod_name() string {
|
|||
}
|
||||
|
||||
// ident_struct_name look ahead and return name of last encountered struct if possible, otherwise empty string
|
||||
fn (mut s Scanner) ident_struct_name() string {
|
||||
fn (s &Scanner) ident_struct_name() string {
|
||||
start := s.pos
|
||||
mut pos := s.pos
|
||||
// Return last known stuct_name encountered to avoid using high order/anonymous function definitions
|
||||
|
@ -303,9 +302,8 @@ fn (mut s Scanner) ident_struct_name() string {
|
|||
return ''
|
||||
}
|
||||
start_pos := pos + 1
|
||||
if s.text[start_pos].is_digit() || end_pos > s.text.len ||
|
||||
end_pos <= start_pos || end_pos <= start ||
|
||||
start_pos <= start {
|
||||
if s.text[start_pos].is_digit() || end_pos > s.text.len || end_pos <= start_pos ||
|
||||
end_pos <= start || start_pos <= start {
|
||||
return ''
|
||||
}
|
||||
struct_name := s.text[start_pos..end_pos]
|
||||
|
@ -354,8 +352,7 @@ fn (mut s Scanner) ident_bin_number() string {
|
|||
}
|
||||
if s.text[s.pos - 1] == num_sep {
|
||||
s.error('cannot use `_` at the end of a numeric literal')
|
||||
}
|
||||
else if start_pos + 2 == s.pos {
|
||||
} else if start_pos + 2 == s.pos {
|
||||
s.pos-- // adjust error position
|
||||
s.error('number part of this binary is not provided')
|
||||
} else if has_wrong_digit {
|
||||
|
@ -394,8 +391,7 @@ fn (mut s Scanner) ident_hex_number() string {
|
|||
}
|
||||
if s.text[s.pos - 1] == num_sep {
|
||||
s.error('cannot use `_` at the end of a numeric literal')
|
||||
}
|
||||
else if start_pos + 2 == s.pos {
|
||||
} else if start_pos + 2 == s.pos {
|
||||
s.pos-- // adjust error position
|
||||
s.error('number part of this hexadecimal is not provided')
|
||||
} else if has_wrong_digit {
|
||||
|
@ -434,8 +430,7 @@ fn (mut s Scanner) ident_oct_number() string {
|
|||
}
|
||||
if s.text[s.pos - 1] == num_sep {
|
||||
s.error('cannot use `_` at the end of a numeric literal')
|
||||
}
|
||||
else if start_pos + 2 == s.pos {
|
||||
} else if start_pos + 2 == s.pos {
|
||||
s.pos-- // adjust error position
|
||||
s.error('number part of this octal is not provided')
|
||||
} else if has_wrong_digit {
|
||||
|
@ -546,8 +541,7 @@ fn (mut s Scanner) ident_dec_number() string {
|
|||
// error check: 5e
|
||||
s.pos-- // adjust error position
|
||||
s.error('exponent has no digits')
|
||||
} else if s.pos < s.text.len &&
|
||||
s.text[s.pos] == `.` && !is_range && !call_method {
|
||||
} else if s.pos < s.text.len && s.text[s.pos] == `.` && !is_range && !call_method {
|
||||
// error check: 1.23.4, 123.e+3.4
|
||||
if has_exp {
|
||||
s.error('exponential part should be integer')
|
||||
|
@ -608,7 +602,7 @@ pub fn (mut s Scanner) scan_all_tokens_in_buffer() {
|
|||
cmode := s.comments_mode
|
||||
s.comments_mode = .parse_comments
|
||||
for {
|
||||
mut t := s.text_scan()
|
||||
t := s.text_scan()
|
||||
s.all_tokens << t
|
||||
if t.kind == .eof {
|
||||
break
|
||||
|
@ -1216,7 +1210,8 @@ fn (mut s Scanner) ident_string() string {
|
|||
}
|
||||
// Don't allow \0
|
||||
if c == `0` && s.pos > 2 && s.text[s.pos - 1] == slash {
|
||||
if (s.pos < s.text.len - 1 && s.text[s.pos + 1].is_digit()) || s.count_symbol_before(s.pos - 1, slash) % 2 == 0 {
|
||||
if (s.pos < s.text.len - 1 && s.text[s.pos + 1].is_digit()) ||
|
||||
s.count_symbol_before(s.pos - 1, slash) % 2 == 0 {
|
||||
} else if !is_cstr && !is_raw {
|
||||
s.error(r'cannot use `\0` (NULL character) in the string literal')
|
||||
}
|
||||
|
@ -1236,8 +1231,8 @@ fn (mut s Scanner) ident_string() string {
|
|||
break
|
||||
}
|
||||
// $var
|
||||
if prevc == `$` && util.is_name_char(c) && !is_raw &&
|
||||
s.count_symbol_before(s.pos - 2, slash) % 2 == 0 {
|
||||
if prevc == `$` && util.is_name_char(c) && !is_raw && s.count_symbol_before(s.pos - 2, slash) %
|
||||
2 == 0 {
|
||||
s.is_inside_string = true
|
||||
s.is_inter_start = true
|
||||
s.pos -= 2
|
||||
|
|
|
@ -13,7 +13,7 @@ const (
|
|||
|
||||
// compile_file compiles the content of a file by the given path as a template
|
||||
pub fn compile_file(path, fn_name string) string {
|
||||
mut html := os.read_file(path) or {
|
||||
html := os.read_file(path) or {
|
||||
panic('html failed')
|
||||
}
|
||||
return compile_template(html, fn_name)
|
||||
|
@ -82,7 +82,7 @@ _ = footer
|
|||
pos := line.index('@include ') or {
|
||||
continue
|
||||
}
|
||||
mut file_name := line[pos + 9..]
|
||||
file_name := line[pos + 9..]
|
||||
file_path := os.join_path('templates', '${file_name}.html')
|
||||
mut file_content := os.read_file(file_path) or {
|
||||
panic('reading file $file_name failed')
|
||||
|
|
Loading…
Reference in New Issue