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
4 changes: 3 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ All code MUST use gen2 syntax (add `options gen2` at the top of every file). Key
- `modules/` — External plugin modules
- `modules/dasLiveHost/` — C++ module for live-reload host lifecycle (dynamic module)
- `utils/daslang-live/` — Live-reloading application host (`daslang-live.exe`)
- `utils/mcp/` — MCP server for AI coding assistants (28 tools, stdio transport, no extra deps)
- `utils/mcp/` — MCP server for AI coding assistants (30 tools, stdio transport, no extra deps)
- `utils/daspkg/` — Package manager (install, update, build, search packages)
- `examples/daslive/` — Live-reload examples (hello, triangle, tank_game, etc.)
- `examples/daspkg/` — Package manager example projects
Expand Down Expand Up @@ -273,6 +273,8 @@ The daslang MCP server (`utils/mcp/main.das`) exposes compiler diagnostics, prog
| `grep_usage` | Using built-in Grep tool to search for symbol names in `.das` files (parse-aware via ast-grep + tree-sitter — no false positives from comments/strings) |
| `outline` | Manually scanning files for function/struct/enum declarations |
| `aot` | Manually running AOT generation and extracting function C++ |
| `perf_lint` | Running `perf_lint.das` manually or requiring the module for performance warnings |
| `lint` | Running `lint.das` manually or requiring the module for code quality checks |
| `live_launch` | Manually starting `daslang-live.exe` from shell |
| `live_status` | `curl http://localhost:9090/status` |
| `live_error` | `curl http://localhost:9090/error` |
Expand Down
15 changes: 7 additions & 8 deletions daslib/aot_cpp.das
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ def describeCppTypeEx(typeDecl : TypeDeclPtr;
let baseType = typeDecl.baseType;

return build_string() $(writer) {
for (d in range(length(typeDecl.dim))) {
for (_ in range(length(typeDecl.dim))) {
write(writer, "TDim<");
}
if (useAlias == CpptUseAlias.yes && typeDecl.flags.aotAlias && !typeDecl.alias.empty()) {
Expand Down Expand Up @@ -385,7 +385,7 @@ def describeCppTypeEx(typeDecl : TypeDeclPtr;
write(writer, "Sequence")
}
} elif (baseType == Type.tBlock || baseType == Type.tFunction || baseType == Type.tLambda) {
var maybe_const = !typeDecl.flags.constant && typeDecl.baseType == Type.tBlock ? "const " : ""
let maybe_const = !typeDecl.flags.constant && typeDecl.baseType == Type.tBlock ? "const " : ""
var type_name = "void"
if (typeDecl.firstType != null) {
type_name = describeCppTypeEx(typeDecl.firstType, DescribeConfig(redundant_const = true, cross_platform = cfg.cross_platform), useAlias)
Expand All @@ -399,7 +399,7 @@ def describeCppTypeEx(typeDecl : TypeDeclPtr;
} else {
write(writer, das_to_cppString(baseType));
}
var args <- to_array(map(each(typeDecl.dim).reverse(), @(itd) { return ",{itd}>"; }))
let args <- to_array(map(each(typeDecl.dim).reverse(), @(itd) { return ",{itd}>"; }))
reverse(args);
write(writer, "{join(args, "")}")

Expand Down Expand Up @@ -474,8 +474,8 @@ class public PrologueMarker : AstVisitor {
// ExprMakeBlock
def override preVisitExprMakeBlock(expr : smart_ptr<ExprMakeBlock>) {
if (func != null && func.flags.hasMakeBlock) {
let _blk = expr._block as ExprBlock;
if (!_blk.blockFlags.aotSkipMakeBlock) {
let blk = expr._block as ExprBlock;
if (!blk.blockFlags.aotSkipMakeBlock) {
func.flags |= FunctionFlags.aotNeedPrologue;
}
}
Expand Down Expand Up @@ -2842,7 +2842,7 @@ class public CppAot : AstVisitor {
CallFunc_visitCallArg(enew, arg, last);
} else {
panic("we should not even be here. we are visiting arguments of a new, but it has no initializer???");
write(*ss, ",");
// write(*ss, ",");
}
return arg;
}
Expand Down Expand Up @@ -2883,7 +2883,6 @@ class public CppAot : AstVisitor {
panic("should not infer otherwise");
}
let type_str = describeCppType(expr._type.argTypes[variantIndex], DescribeConfig(cross_platform = cross_platform));
let offset_str = expr._type.get_variant_field_offset(variantIndex);
write(*ss, "{tabs()}{get_variant_field(expr._type, variantIndex)}::set(");
write(*ss, "{mkvName(expr)}");
if (length(expr.variants) != 1) write(*ss, "({index},__context__)");
Expand Down Expand Up @@ -3785,7 +3784,7 @@ class ArgsConverter : AstVisitor {

def override preVisitFunctionArgument(fn : FunctionPtr, arg : VariablePtr, last : bool) {
// arg
var type_name = build_string() $(writer) {
let type_name = build_string() $(writer) {
if (isLocalVec(arg._type)) {
describeLocalCppType(unsafe(addr(writer)), arg._type, cross_platform)
} else {
Expand Down
6 changes: 3 additions & 3 deletions daslib/aot_standalone.das
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def writeStandaloneContextMethods(var prog : ProgramPtr; var logs : StringBuilde
write(logs, "auto {prefix}{aotFunctionName(string(fn.origin != null ? fn.origin.name : fn.name))} ( ");
// describe arguments
var vars : array<string>
vars |> reserve(length(fn.arguments))
for (variable in fn.arguments) {
if (variable._type.baseType == Type.tStructure && declare_only) {
// It doesn't cover all cases, but anyway we'll get CE.
Expand Down Expand Up @@ -95,7 +96,6 @@ def writeStandaloneContextMethods(var prog : ProgramPtr; var logs : StringBuilde
}

def writeStandaloneCtor(cfg : StandaloneContextCfg; initFunctions : string; var tw : StringBuilderWriter, program : ProgramPtr) {
let disableInit = program._options |> find_arg("no_init") ?as tBool ?? program.policies.no_init;
var lookupVariableTable : array<Variable?>;
if (program.totalVariables > 0) {
program.get_ptr() |> for_each_module_no_order($(pm) {
Expand Down Expand Up @@ -313,7 +313,8 @@ def GetFunctionInfo(pfun : Function?, info : string) {

def addFunctionInfo(disableInit : bool; rtti : bool, fnn : array<Function?>, var helper : AotDebugInfoHelper?) {
helper.helper.rtti = rtti;
var lookupFunctionTable : array<tuple<Function?, FuncInfo?>>;
var lookupFunctionTable : array<tuple<Function?, FuncInfo?>>
lookupFunctionTable |> reserve(length(fnn))
for (pfun in fnn) {
let info = helper.helper |> make_function_debug_info(pfun);
lookupFunctionTable.push((pfun, info));
Expand Down Expand Up @@ -455,7 +456,6 @@ def public standalone_aot(input : string; output_dir : string; cross_platform :
compile_and_simulate(input, access, unsafe(addr(mg)), cop) $(var program : ProgramPtr; var pctx : smart_ptr<Context>) {
result = build_string() $(writer) {
// lets comment on required modules
var modules_str : array<string>
let (modules_str, noAotModule) = getRequiredModulesFor(program)
if (program._options |> find_arg("no_aot") ?as tBool ?? false) {
panic("Standalone context called on non aot module {input}")
Expand Down
10 changes: 10 additions & 0 deletions daslib/apply.das
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,21 @@ def for_each_subrange(total : int; blk : block<(r : range) : void>) {
def generateApplyVisitStruct(stype : TypeDeclPtr; frange : range; fnname : string; at : LineInfo; var names : array<string>; hasExtraArg : bool) {
assert(stype.baseType == Type.tStructure)
assert(stype.dim |> length == 0)
let nfields = frange.y - frange.x
var inscope selfT <- clone_type(stype)
selfT.flags |= TypeDeclFlags.isExplicit | TypeDeclFlags.explicitConst
var inscope blkList : array<ExpressionPtr>
var inscope func_args : array<VariablePtr>
names |> reserve(nfields)
blkList |> reserve(nfields)
// for fld in stype.structType.fields
for (fldi in frange) {
{
let fld & = unsafe(stype.structType.fields[fldi])
names |> push(string(fld.name))
if (hasExtraArg) {
var rttiAnnValues : array<tuple<name : string; data : RttiValue>>
rttiAnnValues |> reserve(length(fld.annotation))
for (ann in fld.annotation) {
var value : tuple<name : string; data : RttiValue>
value.name = string(ann.name)
Expand Down Expand Up @@ -121,10 +125,13 @@ def generateApplyVisitStruct(stype : TypeDeclPtr; fnname : string; at : LineInfo
def generateApplyVisitTuple(stype : TypeDeclPtr; frange : range; fnname : string; at : LineInfo; var names : array<string>) {
assert(stype.baseType == Type.tTuple)
assert(stype.dim |> length == 0)
let nfields = frange.y - frange.x
var inscope selfT <- clone_type(stype)
selfT.flags |= TypeDeclFlags.isExplicit | TypeDeclFlags.explicitConst
var inscope blkList : array<ExpressionPtr>
var inscope func_args : array<VariablePtr>
names |> reserve(nfields)
blkList |> reserve(nfields)
for (fldi in frange) {
{
assume flda = stype.argTypes[fldi]
Expand Down Expand Up @@ -175,10 +182,13 @@ def generateApplyVisitTuple(stype : TypeDeclPtr; fnname : string; at : LineInfo)
def generateApplyVisitVariant(stype : TypeDeclPtr; frange : range; fnname : string; at : LineInfo; var names : array<string>) {
assert(stype.baseType == Type.tVariant)
assert(stype.dim |> length == 0)
let nfields = frange.y - frange.x
var inscope selfT <- clone_type(stype)
selfT.flags |= TypeDeclFlags.isExplicit | TypeDeclFlags.explicitConst
var inscope blkList : array<ExpressionPtr>
var inscope func_args : array<VariablePtr>
names |> reserve(nfields)
blkList |> reserve(nfields)
for (fldi in frange) {
{
assume flda = stype.argTypes[fldi]
Expand Down
1 change: 1 addition & 0 deletions daslib/ast_cursor.das
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class CursorVisitor : AstVisitor {

def private reverse_hits(var src : array<CursorHit>) : array<CursorHit> {
var result : array<CursorHit>
result |> reserve(length(src))
var i = length(src) - 1
while (i >= 0) {
result |> emplace <| src[i]
Expand Down
6 changes: 3 additions & 3 deletions daslib/ast_print.das
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class PrintVisitor : AstVisitor {
// write(*writer, "// {describe_bitfield(fun.sideEffectFlags)}\n");
}
}
let bfa : FunctionFlags = fun.flags & function_annotation_flags;
// let bfa : FunctionFlags = fun.flags & function_annotation_flags;
// // todo: describe_bitfield not supported in aot yet
// write(*writer, "{describe_bitfield(bfa,"\n")}");
if (fun.annotations |> length != 0) {
Expand Down Expand Up @@ -1105,7 +1105,7 @@ def Foo(x, y : int) {
def add(a, b : int) {
//! Adds two integers with an extra constant, used for AST print testing.
// todo make global, after globals supported in standalone ctx
var add_extra = 13;
let add_extra = 13;
print("a={a} b={b}");
return a + b + add_extra;
}
Expand Down Expand Up @@ -1194,7 +1194,7 @@ def allExpr(arg : int) {
verify(ta == tg);
}
// ExprTypeInfo
var tinfo = typeinfo rtti_typeinfo(type<int>).basicType;
let tinfo = typeinfo rtti_typeinfo(type<int>).basicType;
print("{tinfo}\n");
// ExprPtr2Ref
print("{*pFoo1}");
Expand Down
10 changes: 7 additions & 3 deletions daslib/coverage.das
Original file line number Diff line number Diff line change
Expand Up @@ -516,10 +516,14 @@ class CoveragePass : AstPassMacro {
}

// register branches
let nbranches = reg_data.allBranches |> length()
var blines : array<uint>
var block_nums : array<uint>
var branch_nums : array<uint>
for (i in range(reg_data.allBranches |> length())) {
blines |> reserve(nbranches)
block_nums |> reserve(nbranches)
branch_nums |> reserve(nbranches)
for (i in range(nbranches)) {
blines |> push(reg_data.allBranches[i]._0)
block_nums |> push(reg_data.allBranches[i]._1)
branch_nums |> push(reg_data.allBranches[i]._2)
Expand Down Expand Up @@ -551,7 +555,7 @@ def get_coverage_summary(cov_data : table<string; CoverageData>;
}
}
if (per_function) {
for (file, data in keys(cov_data), values(cov_data)) {
for (_file, data in keys(cov_data), values(cov_data)) {
for (fname in keys(data.func_cov)) {
if (fname |> length > max_len) {
max_len = fname |> length
Expand Down Expand Up @@ -680,7 +684,7 @@ def parse_lcov(lcov_path : string; exclude_prefixes : array<string>) : table<str
} elif (line |> starts_with("BRDA:")) {
// BRDA:line,block,branch,taken
let rest = slice(line, 5)
var last_comma = rfind(rest, ",")
let last_comma = rfind(rest, ",")
if (last_comma >= 0) {
let taken = slice(rest, last_comma + 1)
let hits = taken == "-" ? 0u : uint(to_int(taken))
Expand Down
2 changes: 2 additions & 0 deletions daslib/dap.das
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def SetDataBreakpointsArguments(data : JsonValue?) {
var res <- SetDataBreakpointsArguments()
var breakpoints = joj(data, "breakpoints")
if (breakpoints != null) {
res.breakpoints |> reserve(length(breakpoints.value as _array))
for (it in breakpoints.value as _array) {
res.breakpoints |> emplace(DataBreakpoint(it))
}
Expand Down Expand Up @@ -154,6 +155,7 @@ def SetBreakpointsArguments(data : JsonValue?) {
sourceModified = job(data, "sourceModified"))
var breakpoints = joj(data, "breakpoints")
if (breakpoints != null) {
res.breakpoints |> reserve(length(breakpoints.value as _array))
for (it in breakpoints.value as _array) {
res.breakpoints |> emplace(SourceBreakpoint(it))
}
Expand Down
1 change: 1 addition & 0 deletions daslib/das_source_formatter.das
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ def parse_all_tokens(var ctx : FormatterCtx) {
ctx |> parse_token()
}

ctx.tokens |> reserve(length(ctx.tokens) + 8)
for (_ in range(8)) {
ctx.tokens |> push(emptyToken)
}
Expand Down
1 change: 1 addition & 0 deletions daslib/daspkg.das
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def package_tag(tag : string) {
}

def package_tags(tags : array<string>) {
_pkg_meta.tags |> reserve(length(_pkg_meta.tags) + length(tags))
for (t in tags) {
_pkg_meta.tags |> push_clone(t)
}
Expand Down
3 changes: 3 additions & 0 deletions daslib/debug.das
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,9 @@ class private DAgent : DapiDebugAgent {
breakpoints |> erase(path)
if (length(ini.breakpoints) >= 0) {
var breaks <- array<DABreakpoint>()
let nbp = length(ini.breakpoints)
breaks |> reserve(nbp)
res.breakpoints |> reserve(length(res.breakpoints) + nbp)
for (b in ini.breakpoints) {
breaks |> emplace(DABreakpoint(line = uint(b.line), id = breakpointId))
res.breakpoints |> emplace(Breakpoint(
Expand Down
2 changes: 1 addition & 1 deletion daslib/decs_boost.das
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ def private append_index_lookup(arch_name : string; var qblock : smart_ptr<ExprB
name := "{prefix}{a.name}{suffix}",
_type <- vtype,
init <- iget,
flags = VariableFlags.can_shadow
flags = VariableFlags.can_shadow | VariableFlags.generated
)
qblock.list |> emplace(vlet)
return true
Expand Down
1 change: 1 addition & 0 deletions daslib/decs_state.das
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class ContextStateAgent : DapiDebugAgent {
var arq : EcsArchetypeView
arq.hash = arch.hash
arq.size = arch.size
arq.components |> reserve(length(arch.components))
for (c in arch.components) {
var cv : EcsComponentView
cv.name = c.name
Expand Down
4 changes: 4 additions & 0 deletions daslib/json_boost.das
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ def from_JV(v : JsonValue const explicit?; anything : auto(TT)) {
}
unsafe {
let arr & = v.value as _array
ret |> reserve(arr |> length)
for (i in range(arr |> length)) {
if (typeinfo can_copy(anything[0])) {
ret |> push_clone <| _::from_JV(arr[i], decltype_noref(anything[0]))
Expand Down Expand Up @@ -657,6 +658,9 @@ def JV(value : auto(TT)) : JsonValue? {
return _::JV(map)
} static_elif (typeinfo is_iterable(value)) {
var arr : array<JsonValue?>
static_if (typeinfo is_array(value) || typeinfo is_dim(value)) {
arr |> reserve(length(value))
}
for (x in value) {
arr |> push <| _::JV(x)
}
Expand Down
8 changes: 8 additions & 0 deletions daslib/linq.das
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ options no_unused_function_arguments = false

module linq shared public

require math

//! LINQ-style query operations on iterators and arrays.
//!
//! Comprehensive collection of chainable operations: ``where``, ``select``,
Expand Down Expand Up @@ -2643,6 +2645,9 @@ def select_many_to_array(var src : iterator<auto(TT)>; collection_selector; resu
def private zip_impl(var a; tt : auto(TT); var b; var uu : auto(UU)) : array<tuple<TT -const -&, UU -const -&>> {
//! Merges two iterators into an array of tuples
var buffer : array<tuple<TT -const -&, UU -const -&>>
static_if ((typeinfo is_array(a) || typeinfo is_dim(a)) && (typeinfo is_array(b) || typeinfo is_dim(b))) {
buffer |> reserve(min(length(a), length(b)))
}
for (itA, itB in a, b) {
buffer.emplace((itA, itB))
}
Expand Down Expand Up @@ -2704,6 +2709,9 @@ def zip_to_array(var a : iterator<auto(TT)>; var b : iterator<auto(UU)>; result_
def private zip3_impl(var a; tt : auto(TT); var b; uu : auto(UU); var c; ww : auto(WW)) : array<tuple<TT -const -&, UU -const -&, WW -const -&>> {
//! Merges three iterators into an array of tuples
var buffer : array<tuple<TT -const -&, UU -const -&, WW -const -&>>
static_if ((typeinfo is_array(a) || typeinfo is_dim(a)) && (typeinfo is_array(b) || typeinfo is_dim(b)) && (typeinfo is_array(c) || typeinfo is_dim(c))) {
buffer |> reserve(min(length(a), min(length(b), length(c))))
}
for (itA, itB, itC in a, b, c) {
buffer.emplace((itA, itB, itC))
}
Expand Down
Loading
Loading