Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ Full migration table (when reading older docs that say `var inscope` or `<-` for
- `try/recover` — NOT `try/catch` (`recover` is the keyword)
- `panic("message")`, `assert(condition)`, `verify(condition)` (stays in release)
- **Postfix conditional:** `return expr if (cond)`, `break if (cond)`, `continue if (cond)` — early-exit guard on one line
- **Braceless early-exit:** prefer `if (cond) return X` (or postfix `return X if (cond)`) over `if (cond) { return X }` — STYLE005 flags the braced single-terminator form as noise

### Generic function dispatch

Expand Down Expand Up @@ -258,6 +259,10 @@ Full migration table (when reading older docs that say `var inscope` or `<-` for
| `if (true) { ... }` | `{ ... }` | bare blocks create lexical scope in gen2 |
| `var inscope r <- expr; return <- r` | `return <- expr` | direct return avoids intermediate |
| `unsafe { (reinterpret<ExprBlock?> blk).list }` / `unsafe(reinterpret<T?> x)` | make param `var` + plain `x.list` | `var` param gives non-const field access without reinterpret |
| `if (cond) { return X }` (or `{ break }` / `{ continue }`) | `if (cond) return X` or postfix `return X if (cond)` | STYLE005: braces around a single-statement early-exit are noise |
| `for (i in range(length(arr))) { ... arr[i] ... }` where `i` is used only as `arr[i]` | `for (c in arr) { ... c ... }` | PERF018: direct iteration drops the index variable |
| `from_JV(v, type<int>, 13)` | `v ?? 13` | STYLE020: json_boost provides `operator ??` for every scalar `from_JV` overload |
| `var args : table<string; JsonValue?>; args \|> insert("k1", JV(v1)); args \|> insert("k2", JV(v2))` | `var args = JV((k1=v1, k2=v2))` | STYLE021: named-tuple JV form (json_boost.das:638) is one line instead of N |

For path/filename ops use `fio` helpers (`base_name`/`dir_name`/`path_join`/etc.) — see `skills/filesystem.md`. Never hand-roll `rfind("/")` / slice — misses Windows separators.

Expand Down
48 changes: 12 additions & 36 deletions daslib/algorithm.das
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ def sort_unique(var a : array<auto(TT)>) {
//! Returns an array of elements from a, sorted and with duplicates removed.
//! The elements are sorted in ascending order.
//! The resulting array has only unique elements.
if (empty(a)) {
return
}
if (empty(a)) return
sort(a)
var b <- unique(a)
delete a
Expand Down Expand Up @@ -432,19 +430,15 @@ def fill(var a; value) {
def is_sorted(a : array<auto(TT)>) : bool {
//! Returns true if the array is sorted in non-descending order.
for (i in range(1, length(a))) {
if (a[i] < a[i - 1]) {
return false
}
if (a[i] < a[i - 1]) return false
}
return true
}

def is_sorted(a : array<auto(TT)>; less : block<(a, b : TT const -&) : bool>) : bool {
//! Returns true if the array is sorted according to the provided less function.
for (i in range(1, length(a))) {
if (invoke(less, a[i], a[i - 1])) {
return false
}
if (invoke(less, a[i], a[i - 1])) return false
}
return true
}
Expand All @@ -463,9 +457,7 @@ def rotate(var a : array<auto>; mid : int) {
//! Rotates the array so that the element at index mid becomes the first element.
//! Elements before mid are moved to the end.
let l = length(a)
if (l == 0 || mid == 0 || mid == l) {
return
}
if (l == 0 || mid == 0 || mid == l) return
assert(mid > 0 && mid < l, "rotate mid out of range")
// reverse [0, mid), [mid, l), then reverse all
let lm1 = l - 1
Expand Down Expand Up @@ -494,9 +486,7 @@ def rotate(var a; mid : int) {

def min_element(a : array<auto(TT)>) : int {
//! Returns the index of the minimum element in the array, or -1 if the array is empty.
if (length(a) == 0) {
return -1
}
if (length(a) == 0) return -1
var best = 0
for (i in range(1, length(a))) {
if (a[i] < a[best]) {
Expand All @@ -508,9 +498,7 @@ def min_element(a : array<auto(TT)>) : int {

def min_element(a : array<auto(TT)>; less : block<(a, b : TT const -&) : bool>) : int {
//! Returns the index of the minimum element according to the provided less function, or -1 if the array is empty.
if (length(a) == 0) {
return -1
}
if (length(a) == 0) return -1
var best = 0
for (i in range(1, length(a))) {
if (invoke(less, a[i], a[best])) {
Expand All @@ -522,9 +510,7 @@ def min_element(a : array<auto(TT)>; less : block<(a, b : TT const -&) : bool>)

def max_element(a : array<auto(TT)>) : int {
//! Returns the index of the maximum element in the array, or -1 if the array is empty.
if (length(a) == 0) {
return -1
}
if (length(a) == 0) return -1
var best = 0
for (i in range(1, length(a))) {
if (a[best] < a[i]) {
Expand All @@ -536,9 +522,7 @@ def max_element(a : array<auto(TT)>) : int {

def max_element(a : array<auto(TT)>; less : block<(a, b : TT const -&) : bool>) : int {
//! Returns the index of the maximum element according to the provided less function, or -1 if the array is empty.
if (length(a) == 0) {
return -1
}
if (length(a) == 0) return -1
var best = 0
for (i in range(1, length(a))) {
if (invoke(less, a[best], a[i])) {
Expand Down Expand Up @@ -647,13 +631,9 @@ def difference(a, b : table<auto(TT)>) : table<TT> {

def identical(a, b : table<auto(TT)>) : bool {
//! Returns true if the two sets are identical.
if (length(a) != length(b)) {
return false
}
if (length(a) != length(b)) return false
for (k in keys(a)) {
if (!b |> key_exists(k)) {
return false
}
if (!b |> key_exists(k)) return false
}
return true
}
Expand All @@ -676,13 +656,9 @@ def symmetric_difference(a, b : table<auto(TT)>) : table<TT> {

def is_subset(a, b : table<auto(TT)>) : bool {
//! Returns true if all elements of a are contained in b.
if (length(a) > length(b)) {
return false
}
if (length(a) > length(b)) return false
for (k in keys(a)) {
if (!b |> key_exists(k)) {
return false
}
if (!b |> key_exists(k)) return false
}
return true
}
4 changes: 1 addition & 3 deletions daslib/ansi_colors.das
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ def reset_str() : string {

def private has_value(args : array<string>; val : string) : bool {
for (a in args) {
if (a == val) {
return true
}
if (a == val) return true
}
return false
}
97 changes: 28 additions & 69 deletions daslib/aot_cpp.das
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ def aotModuleName(pm : Module?) {

def isSequencialMask(fields : dasvector`uint8) {
for (i in range(1, length(fields))) {
if (int(fields[i - 1]) + 1 != int(fields[i])) {
return false;
}
if (int(fields[i - 1]) + 1 != int(fields[i])) return false;
}
return true;
}
Expand Down Expand Up @@ -149,8 +147,8 @@ def das_to_cppCTypeString(t : Type) {


def isConstRedundantForCpp(typeDecl : TypeDeclPtr) {
if (!empty(typeDecl.dim)) { return false; }
if (typeDecl.isVectorType) { return true; }
if (!empty(typeDecl.dim)) return false;
if (typeDecl.isVectorType) return true;
match (typeDecl.baseType) {
if (Type.tBool) { return true; }
if (Type.tInt8) { return true; }
Expand Down Expand Up @@ -415,7 +413,7 @@ def describeCppTypeEx(typeDecl : TypeDeclPtr;
write(writer, ",{typeDecl.dim[dim_count - 1 - i]}>")
}

if (cfg.skip_const == false && typeDecl.flags.constant) {
if (!cfg.skip_const && typeDecl.flags.constant) {
write(writer, " const ");
}
// Value-annotation handles (e.g. Handle<T>) are POD and always passed by value,
Expand All @@ -424,7 +422,7 @@ def describeCppTypeEx(typeDecl : TypeDeclPtr;
// Keep the * suffix when substitute_ref is requested (e.g. iteration variables),
// since das_iterator::first(Context*, QQ*&) demands a real pointer regardless.
let valueHandle = baseType == Type.tHandle && !typeDecl.isRefType
if (typeDecl.flags.ref && cfg.skip_ref == false) {
if (typeDecl.flags.ref && !cfg.skip_ref) {
if (cfg.substitute_ref) {
write(writer, " *");
} elif (!valueHandle) {
Expand Down Expand Up @@ -691,11 +689,11 @@ class public AotDebugInfoHelper {
write(writer, " ann.resolveAnnotation();\n")
write(writer, " \}\n")
helper |> debug_helper_iter_structs($(name, si) {
if (si.fields == null) { return ; }
if (si.fields == null) return ;
for (fi in range(si.count)) {
let fld & = unsafe(si.fields[fi])
if (fld.annotation_arguments == null) { continue; }
if (length(*fld.annotation_arguments) == 0) { continue; }
if (fld.annotation_arguments == null) continue;
if (length(*fld.annotation_arguments) == 0) continue;
write(writer, " {structInfoName(si)}_field_{fi}.annotation_arguments = &{structInfoName(si)}_field_{fi}_ann;\n")
}
})
Expand Down Expand Up @@ -1332,8 +1330,7 @@ class public CppAot : AstVisitor {
// function
def override canVisitFunction(fun : Function?) {
if (fun.flags.noAot) return false;
if (fun.moreFlags.isTemplate) return false;
return true;
return !fun.moreFlags.isTemplate;
}
def override preVisitFunction(fn : FunctionPtr) {
if (!empty(aot_filter_function) && (fn.name == aot_filter_function || aotFuncName(fn) == aot_filter_function)) {
Expand Down Expand Up @@ -1686,9 +1683,7 @@ class public CppAot : AstVisitor {
}
}
def isOpPolicy1(that : ExprOp1?) {
if (is_alpha(first_character(that.op))) {
return true;
}
if (is_alpha(first_character(that.op))) return true;
return that.subexpr._type.isPolicyType;
}
def override preVisitExprOp1(var that : ExprOp1?) {
Expand Down Expand Up @@ -3320,26 +3315,16 @@ class public CppAot : AstVisitor {
}
// call
def policyArgNeedCast(polType : TypeDeclPtr; argType : TypeDeclPtr) {
if (argType.isVectorType) {
return false;
}
if (argType.isVectorType) return false;
if (!polType.isHandle) {
if (polType.isVecPolicyType && argType.isVecPolicyType) {
return false;
}
}
if (!polType.isPolicyType) {
return false;
if (polType.isVecPolicyType && argType.isVecPolicyType) return false;
}
if (!polType.isPolicyType) return false;
return true;
}
def policyResultNeedCast(polType : TypeDeclPtr; resType : TypeDeclPtr) {
if (resType.isVoid) {
return false;
}
if (!resType.isPolicyType) {
return false;
}
if (resType.isVoid) return false;
if (!resType.isPolicyType) return false;
return policyArgNeedCast(polType, resType);
}
def isPolicyBasedCall(call : ExprCall?) {
Expand All @@ -3356,9 +3341,7 @@ class public CppAot : AstVisitor {
def isPolicyBasedCallFunc(call : ExprCallFunc?) {
if (call.func.flags.builtIn) {
let bif = call.func as BuiltInFunction;
if (bif.flags.policyBased) {
return true;
}
if (bif.flags.policyBased) return true;
}
return false;
}
Expand All @@ -3371,10 +3354,7 @@ class public CppAot : AstVisitor {
if (func.flags.callBased) {
panic("we should not be here. call-based calls handled elsewhere");
}
if (length(bif.cppName) == 0) {
return true;
}
return false;
return length(bif.cppName) == 0;
}
if (func.flags.noAot) return true;
if (func.flags.aotHybrid) return true;
Expand All @@ -3388,9 +3368,7 @@ class public CppAot : AstVisitor {
if (expr is ExprMakeBlock) {
let mkblk = expr as ExprMakeBlock;
let blk = mkblk._block as ExprBlock;
if (blk.blockFlags.aotSkipMakeBlock) {
return false;
}
if (blk.blockFlags.aotSkipMakeBlock) return false;
}
return needsArgPassType(expr._type);
}
Expand Down Expand Up @@ -3512,9 +3490,7 @@ class public CppAot : AstVisitor {
if (call.func.moreFlags.propertyFunction) return ; // property function goes ((arg0).name()). we do nothing here
var argIndex = 0;
for (it in range(length(call.arguments))) {
if (call.arguments[it] == arg) {
break;
}
if (call.arguments[it] == arg) break;
argIndex++;
}
assert(argIndex != length(call.arguments));
Expand Down Expand Up @@ -3555,9 +3531,7 @@ class public CppAot : AstVisitor {
if (call.func.moreFlags.propertyFunction) return ; // property function goes ((arg0).name()). we do nothing here
var argIndex = 0;
for (it in range(length(call.arguments))) {
if (call.arguments[it] == arg) {
break;
}
if (call.arguments[it] == arg) break;
argIndex++;
}

Expand Down Expand Up @@ -3670,19 +3644,15 @@ class public CppAot : AstVisitor {
write(*ss, "{tabs()}");
}
def isCountOrUCount(expr : ExpressionPtr) {
if (!(isExprCallFunc(expr))) {
return false;
}
if (!(isExprCallFunc(expr))) return false;
assume call = unsafe(reinterpret<ExprCallFunc?>(expr));
return call.func != null && call.func.flags.builtIn && call.func._module.name == "$" && (call.name == "count" || call.name == "ucount");
}
def override preVisitExprForSource(ffor : ExprFor?; that : ExpressionPtr; last : bool) {
var idx = 0;
let idxs = length(ffor.sources);
for (id in range(idxs)) {
if (ffor.sources[id] == that) {
break;
}
if (ffor.sources[id] == that) break;
idx++
}
assume src = ffor.sources[idx];
Expand All @@ -3699,9 +3669,7 @@ class public CppAot : AstVisitor {
var idx = 0;
let idxs = length(ffor.sources);
for (id in range(idxs)) {
if (ffor.sources[id] == that) {
break;
}
if (ffor.sources[id] == that) break;
idx++
}
assume src = ffor.sources[idx];
Expand Down Expand Up @@ -3749,17 +3717,13 @@ def public dumpDependencies(program : ProgramPtr; var aotVisitor : CppAot?) {
}
let remUS = program._options |> find_arg("remove_unused_symbols") ?as tBool ?? true;
program.get_ptr() |> for_each_module_no_order($(pm) {
if (pm.moduleFlags.fromExtraDependency) {
return ;
}
if (pm.moduleFlags.fromExtraDependency) return ;
pm |> for_each_structure($(ps) {
write(*aotVisitor.ss, "namespace {aotModuleName(ps._module)} \{ struct {aotStructName(ps)}; \};\n");
});
});
program.get_ptr() |> for_each_module_no_order($(pm) {
if (pm == program.getThisModule || pm.moduleFlags.fromExtraDependency) {
return ;
}
if (pm == program.getThisModule || pm.moduleFlags.fromExtraDependency) return ;
pm |> for_each_enumeration($(penum) {
if (!remUS || utm.useEnums |> key_exists(penum)) {
program |> visit_enumeration(penum, aotVisitor.adapter)
Expand Down Expand Up @@ -3788,8 +3752,7 @@ class ArgsConverter : AstVisitor {

def override canVisitFunction(fun : Function?) {
if (fun.flags.noAot) return false;
if (fun.moreFlags.isTemplate) return false;
return true;
return !fun.moreFlags.isTemplate;
}

def override preVisitFunction(fn : FunctionPtr) {
Expand Down Expand Up @@ -3853,9 +3816,7 @@ def collectUsedFunctions(modules : array<Module?>; totalFunctions : int; this_mo
fnn.reserve(totalFunctions);
for (pm in modules) {
pm |> for_each_module_function($(pfun) {
if (!all_modules && pfun._module != this_module) {
return ;
}
if (!all_modules && pfun._module != this_module) return ;
if (pfun.index < 0 || !pfun.flags.used) return ;
if (!is_all) {
if (pfun.flags.builtIn || pfun.flags.noAot) return ;
Expand Down Expand Up @@ -4111,9 +4072,7 @@ def public run_aot_function(prog : Program?; var pctx : Context?; cop : CodeOfPo
let program <- unsafe(reinterpret<ProgramPtr>(prog));
return build_string() $(writer) {
let (modules_str, noAotModule) = getRequiredModulesFor(program)
if ((program._options |> find_arg("no_aot") ?as tBool ?? false) || noAotModule) {
return
}
if ((program._options |> find_arg("no_aot") ?as tBool ?? false) || noAotModule) return
build_string() $(tmp_writer) {
let marker_vis = new NoAotMarker();
make_visitor(*marker_vis) $(adapter_marker) {
Expand Down
Loading
Loading