fix(compiler): allow integer coercion in range bounds; use for loops in boko-framework
- sema: range bounds now accept compatible integer types (e.g. int..uint) instead of requiring exact type equality. - hir_lower: derive loop variable type from the common range type. - boko-framework: replace manual while loops with for loops in Query_Parse, Request_Parse, Path_Match and App_Run.
This commit is contained in:
@@ -242,8 +242,7 @@ func Query_Parse(queryString: String) -> StringMap<String> {
|
||||
}
|
||||
|
||||
let pairCount: uint = String_SplitCount(queryString, "&");
|
||||
var i: uint = 0;
|
||||
while i < pairCount {
|
||||
for i in 0..pairCount {
|
||||
let pair: String = String_SplitPart(queryString, "&", i);
|
||||
let eqPos: String = String_Find(pair, "=");
|
||||
var key: String = pair;
|
||||
@@ -258,7 +257,6 @@ func Query_Parse(queryString: String) -> StringMap<String> {
|
||||
}
|
||||
}
|
||||
StringMap_Set<String>(&map, key, value);
|
||||
i = i + 1;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
@@ -317,8 +315,7 @@ func Request_Parse(raw: String) -> Request {
|
||||
}
|
||||
|
||||
// Parse headers
|
||||
var i: uint = 1;
|
||||
while i < lineCount {
|
||||
for i in 1..lineCount {
|
||||
let line: String = String_SplitPart(headerBlock, "\r\n", i);
|
||||
let colonPos: String = String_Find(line, ": ");
|
||||
if !String_IsNull(colonPos) {
|
||||
@@ -332,7 +329,6 @@ func Request_Parse(raw: String) -> Request {
|
||||
}
|
||||
StringMap_Set<String>(&req.headers, key, value);
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return req;
|
||||
@@ -349,8 +345,7 @@ func Path_Match(pattern: String, path: String, req: *Request) -> bool {
|
||||
|
||||
req.pathParams = StringMap_New<String>(8);
|
||||
|
||||
var i: uint = 0;
|
||||
while i < patParts {
|
||||
for i in 0..patParts {
|
||||
let patPart: String = String_SplitPart(pattern, "/", i);
|
||||
let pathPart: String = String_SplitPart(path, "/", i);
|
||||
|
||||
@@ -361,7 +356,6 @@ func Path_Match(pattern: String, path: String, req: *Request) -> bool {
|
||||
} else {
|
||||
if !String_Eq(patPart, pathPart) { return false; }
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -462,10 +456,8 @@ func App_Run(app: *App) {
|
||||
PrintLine("");
|
||||
|
||||
// Spawn workers
|
||||
var i: int = 0;
|
||||
while i < app.threadCount - 1 {
|
||||
for i in 0..(app.threadCount - 1) {
|
||||
spawn App_Worker(fd);
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
// Main thread is the last worker
|
||||
|
||||
+11
-2
@@ -481,7 +481,15 @@ proc resolveExprType(ctx: var LowerCtx, expr: Expr): Type =
|
||||
return makeSlice(makeUnknown())
|
||||
of ekRange:
|
||||
let loType = ctx.resolveExprType(expr.exprRangeLo)
|
||||
return makeRange(loType)
|
||||
let hiType = ctx.resolveExprType(expr.exprRangeHi)
|
||||
if loType == hiType:
|
||||
return makeRange(loType)
|
||||
elif loType.isAssignableTo(hiType):
|
||||
return makeRange(hiType)
|
||||
elif hiType.isAssignableTo(loType):
|
||||
return makeRange(loType)
|
||||
else:
|
||||
return makeRange(loType)
|
||||
of ekTuple:
|
||||
var elems: seq[Type] = @[]
|
||||
for e in expr.exprTupleElements:
|
||||
@@ -1377,7 +1385,8 @@ proc lowerStmt(ctx: var LowerCtx, stmt: Stmt): HirNode =
|
||||
let inclusive = iterExpr.exprRangeInclusive
|
||||
|
||||
# Determine loop variable type from range bounds
|
||||
let varType = ctx.resolveExprType(iterExpr.exprRangeLo)
|
||||
let rangeType = ctx.resolveExprType(iterExpr)
|
||||
let varType = if rangeType.inner.len > 0: rangeType.inner[0] else: ctx.resolveExprType(iterExpr.exprRangeLo)
|
||||
|
||||
# Create: var i = lo; while i < hi { body; i = i + 1; }
|
||||
let initStmt = hirAlloca(varName, varType, loc)
|
||||
|
||||
+9
-2
@@ -1007,9 +1007,16 @@ proc checkExpr(sema: var Sema, expr: Expr, scope: Scope): Type =
|
||||
of ekRange:
|
||||
let lo = sema.checkExpr(expr.exprRangeLo, scope)
|
||||
let hi = sema.checkExpr(expr.exprRangeHi, scope)
|
||||
if lo != hi:
|
||||
var rangeType: Type = lo
|
||||
if lo == hi:
|
||||
rangeType = lo
|
||||
elif lo.isAssignableTo(hi):
|
||||
rangeType = hi
|
||||
elif hi.isAssignableTo(lo):
|
||||
rangeType = lo
|
||||
else:
|
||||
sema.emitError(expr.loc, "range bounds must have same type")
|
||||
return makeRange(lo)
|
||||
return makeRange(rangeType)
|
||||
of ekCall:
|
||||
if expr.exprCallCallee == nil:
|
||||
sema.emitError(expr.loc, "internal error: nil callee in call expression")
|
||||
|
||||
Reference in New Issue
Block a user