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