Please help to understand, what is wrong with following code:
proc strsubsmart(s: string, start: int, fl0wlen: int): string =
if start >= 0 and fl0wlen > 0:
substring(s, start, fl0wlen)
else:
var slen: int =
strlen(s)
var trueStart: int =
if start >= 0:
start
else:
var ss: int =
slen+start
if ss >= 0:
ss
else:
0
var trueLength: int =
if fl0wlen > 0:
fl0wlen
else:
slen+fl0wlen-trueStart
substring(s, trueStart, trueLength)
It produces error
fc.nim(2237, 9) Error: invalid indentation where line 2237 is
if ss >= 0:
This code is derived from
strsubsmart(s : string, start : int, len : int) -> string {
if (start >= 0 && len > 0) {
substring(s, start, len)
} else {
slen = strlen(s);
trueStart = if (start >= 0) start else { ss = slen + start; if (ss >= 0) ss else 0; };
trueLength = if (len > 0) len else slen + len - trueStart;
substring(s, trueStart, trueLength)
}
}
'if' expression with issue follows var declaration in one code block and is a result of outer if expression.
The else branch does not consist of a single expression. You can use block to wrap a few statements in a single expression.
By the way, I advise you to use let for immutable variables, and avoid specifying all the types of variables (the compiler will infer them just fine)
var a = 1
var b : int = if a == 1:
1
else:
block:
var c = 4
c + 5
echo b
t.nim(6, 17) Error: expression expected, but found 'keyword block'
Having types is cheap for me, I have types during my code generation after type checking.
'let' instead of 'var' is next step after syntactically correct conversion :)
If you generate code automatically, then just flooding a little exptressions with parentheses may be the easiest way (parenthesize all subexpressions, not statements). Yet add semicolons after statements in expressions. E.g. your code works in the following version:
proc strsubsmart(s: string, start: int, fl0wlen: int): string =
if start >= 0 and fl0wlen > 0:
substring(s, start, fl0wlen)
else:
var slen: int =
strlen(s)
var trueStart: int = (
if start >= 0: (
start
) else: (
var ss: int =
slen+start;
if ss >= 0: (
ss
) else:
0
)
)
var trueLength: int =
if fl0wlen > 0:
fl0wlen
else:
slen+fl0wlen-trueStart
substring(s, trueStart, trueLength)
Thank you, @LeuGim, it solved issue.
I surprised usage of parentheses is not mentioned in documentation (or hidden somehow).