#include #include #include #include "_runtime.h" #include "Amalgame_String.h" #include "Amalgame_Collections.h" #include "Amalgame_IO.h" #include "Amalgame_Net.h" #include "Amalgame_Console.h" #include "Amalgame_Process.h" typedef enum _Amalgame_Compiler_TokenType Amalgame_Compiler_TokenType; typedef struct _Amalgame_Compiler_Token Amalgame_Compiler_Token; typedef enum _Amalgame_Compiler_NodeKind Amalgame_Compiler_NodeKind; typedef struct _Amalgame_Compiler_AstNode Amalgame_Compiler_AstNode; typedef struct _Amalgame_Compiler_Ast Amalgame_Compiler_Ast; typedef struct _Amalgame_Compiler_Lexer Amalgame_Compiler_Lexer; typedef struct _Amalgame_Compiler_Parser Amalgame_Compiler_Parser; typedef enum _Amalgame_Compiler_TomlKind Amalgame_Compiler_TomlKind; typedef struct _Amalgame_Compiler_TomlValue Amalgame_Compiler_TomlValue; typedef struct _Amalgame_Compiler_TomlParser Amalgame_Compiler_TomlParser; typedef struct _Amalgame_Compiler_Toml Amalgame_Compiler_Toml; typedef struct _Amalgame_Compiler_LoadedPackage Amalgame_Compiler_LoadedPackage; typedef struct _Amalgame_Compiler_PackageRegistry Amalgame_Compiler_PackageRegistry; typedef struct _Amalgame_Compiler_CalibrationSample Amalgame_Compiler_CalibrationSample; typedef struct _Amalgame_Compiler_Calibration Amalgame_Compiler_Calibration; typedef struct _Amalgame_Compiler_Emitter Amalgame_Compiler_Emitter; typedef struct _Amalgame_Compiler_CGen Amalgame_Compiler_CGen; typedef struct _Amalgame_Compiler_Formatter Amalgame_Compiler_Formatter; typedef struct _Amalgame_Compiler_Ansi Amalgame_Compiler_Ansi; typedef struct _Amalgame_Compiler_SourceMap Amalgame_Compiler_SourceMap; typedef struct _Amalgame_Compiler_SourceSnippet Amalgame_Compiler_SourceSnippet; typedef enum _Amalgame_Compiler_DiagSeverity Amalgame_Compiler_DiagSeverity; typedef struct _Amalgame_Compiler_Diagnostic Amalgame_Compiler_Diagnostic; typedef struct _Amalgame_Compiler_DiagnosticFormatter Amalgame_Compiler_DiagnosticFormatter; typedef enum _Amalgame_Compiler_SymKind Amalgame_Compiler_SymKind; typedef struct _Amalgame_Compiler_Symbol Amalgame_Compiler_Symbol; typedef struct _Amalgame_Compiler_SymbolTable Amalgame_Compiler_SymbolTable; typedef struct _Amalgame_Compiler_Resolver Amalgame_Compiler_Resolver; typedef struct _Amalgame_Compiler_MemberTable Amalgame_Compiler_MemberTable; typedef struct _Amalgame_Compiler_ResolverError Amalgame_Compiler_ResolverError; typedef struct _Amalgame_Compiler_FullResolver Amalgame_Compiler_FullResolver; typedef struct _Amalgame_Compiler_TypeError Amalgame_Compiler_TypeError; typedef struct _Amalgame_Compiler_TypeCheckResult Amalgame_Compiler_TypeCheckResult; typedef struct _Amalgame_Compiler_TypeChecker Amalgame_Compiler_TypeChecker; typedef struct _Amalgame_Compiler_LintWarning Amalgame_Compiler_LintWarning; typedef struct _Amalgame_Compiler_Linter Amalgame_Compiler_Linter; typedef enum _Amalgame_Compiler_JsonKind Amalgame_Compiler_JsonKind; typedef struct _Amalgame_Compiler_JsonValue Amalgame_Compiler_JsonValue; typedef struct _Amalgame_Compiler_JsonError Amalgame_Compiler_JsonError; typedef struct _Amalgame_Compiler_JsonResult Amalgame_Compiler_JsonResult; typedef struct _Amalgame_Compiler_JsonParser Amalgame_Compiler_JsonParser; typedef struct _Amalgame_Compiler_Json Amalgame_Compiler_Json; typedef struct _Amalgame_Compiler_MsgPackCursor Amalgame_Compiler_MsgPackCursor; typedef struct _Amalgame_Compiler_MsgPack Amalgame_Compiler_MsgPack; typedef struct _Amalgame_Compiler_BuildInfo Amalgame_Compiler_BuildInfo; typedef struct _Amalgame_Compiler_LspServer Amalgame_Compiler_LspServer; typedef struct _Amalgame_Compiler_MiValue Amalgame_Compiler_MiValue; typedef struct _Amalgame_Compiler_MiRecord Amalgame_Compiler_MiRecord; typedef struct _Amalgame_Compiler_MiParser Amalgame_Compiler_MiParser; /* inline-C top-level */ #ifndef _WIN32 #include #include #include #include #include #include #endif typedef struct _Amalgame_Compiler_DapServer Amalgame_Compiler_DapServer; typedef struct _Amalgame_Compiler_CurlResponse Amalgame_Compiler_CurlResponse; typedef struct _Amalgame_Compiler_MigrateResult Amalgame_Compiler_MigrateResult; typedef struct _Amalgame_Compiler_MigrateCommand Amalgame_Compiler_MigrateCommand; typedef struct _Amalgame_Compiler_GenerateCommand Amalgame_Compiler_GenerateCommand; typedef struct _Amalgame_Compiler_ExplainCommand Amalgame_Compiler_ExplainCommand; typedef struct _Amalgame_Compiler_NewCommand Amalgame_Compiler_NewCommand; typedef struct _Amalgame_Compiler_McuCommand Amalgame_Compiler_McuCommand; typedef struct _Amalgame_Compiler_DocCommand Amalgame_Compiler_DocCommand; typedef struct _Amalgame_Compiler_ArgParser Amalgame_Compiler_ArgParser; /* inline-C top-level */ #include #include #include #include #ifdef _WIN32 #include #include #else #include #include #endif /* Recursive mkdir — POSIX `mkdir -p`. Walks each prefix segment, * ignoring EEXIST. Returns 1 on success, 0 on a hard error. */ static int amalgame_pm_mkdirp(const char* path) { if (!path || !*path) return 0; size_t len = strlen(path); char* buf = (char*) GC_MALLOC(len + 1); memcpy(buf, path, len + 1); size_t start = 1; #ifdef _WIN32 if (len >= 2 && buf[1] == ':') { start = (len >= 3 && (buf[2] == '\\' || buf[2] == '/')) ? 3 : 2; } #endif for (size_t i = start; i <= len; i++) { char c = (i < len) ? buf[i] : '\0'; if (i == len || c == '/' || c == '\\') { buf[i] = '\0'; int rc; #ifdef _WIN32 rc = _mkdir(buf); #else rc = mkdir(buf, 0755); #endif buf[i] = c; if (rc != 0 && errno != EEXIST) return 0; } } return 1; } /* Recursive delete — POSIX `rm -rf`. Missing path = success * (idempotent). Returns 1 on success, 0 on a hard error. */ static int amalgame_pm_rmrf(const char* path) { if (!path || !*path) return 0; struct stat st; if (stat(path, &st) != 0) return 1; /* already gone */ if (!S_ISDIR(st.st_mode)) { #ifdef _WIN32 /* git leaves pack files read-only; remove()/DeleteFile fail on * those unless we clear the attribute first — otherwise the * parent dir stays non-empty and RemoveDirectory fails, leaving * a half-deleted cache entry. */ SetFileAttributesA(path, FILE_ATTRIBUTE_NORMAL); #endif return remove(path) == 0 ? 1 : 0; } size_t plen = strlen(path); #ifdef _WIN32 { char* pattern = (char*) GC_MALLOC(plen + 3); memcpy(pattern, path, plen); pattern[plen] = '\\'; pattern[plen+1] = '*'; pattern[plen+2] = '\0'; WIN32_FIND_DATAA fd; HANDLE h = FindFirstFileA(pattern, &fd); if (h != INVALID_HANDLE_VALUE) { do { if (strcmp(fd.cFileName, ".") == 0) continue; if (strcmp(fd.cFileName, "..") == 0) continue; size_t nl = strlen(fd.cFileName); char* child = (char*) GC_MALLOC(plen + 1 + nl + 1); memcpy(child, path, plen); child[plen] = '\\'; memcpy(child + plen + 1, fd.cFileName, nl + 1); amalgame_pm_rmrf(child); } while (FindNextFileA(h, &fd)); FindClose(h); } SetFileAttributesA(path, FILE_ATTRIBUTE_NORMAL); return RemoveDirectoryA(path) ? 1 : 0; } #else { DIR* d = opendir(path); if (d) { struct dirent* e; while ((e = readdir(d)) != NULL) { if (strcmp(e->d_name, ".") == 0) continue; if (strcmp(e->d_name, "..") == 0) continue; size_t nl = strlen(e->d_name); char* child = (char*) GC_MALLOC(plen + 1 + nl + 1); memcpy(child, path, plen); child[plen] = '/'; memcpy(child + plen + 1, e->d_name, nl + 1); amalgame_pm_rmrf(child); } closedir(d); } return rmdir(path) == 0 ? 1 : 0; } #endif } /* Rename/move within a volume — `mv`. 1 on success, 0 on error. */ static int amalgame_pm_rename(const char* from, const char* to) { if (!from || !to) return 0; return rename(from, to) == 0 ? 1 : 0; } /* Directory entry names (excluding "." / ".."), one per line with a * trailing newline — like `ls -1`. "" for a missing/unreadable dir. * Order is filesystem-native; callers sort if needed. */ static char* amalgame_pm_listdir(const char* path) { size_t cap = 256, len = 0; char* out = (char*) GC_MALLOC(cap); out[0] = '\0'; if (!path || !*path) return out; #ifdef _WIN32 { size_t plen = strlen(path); char* pattern = (char*) GC_MALLOC(plen + 3); memcpy(pattern, path, plen); pattern[plen] = '\\'; pattern[plen+1] = '*'; pattern[plen+2] = '\0'; WIN32_FIND_DATAA fd; HANDLE h = FindFirstFileA(pattern, &fd); if (h == INVALID_HANDLE_VALUE) return out; do { if (strcmp(fd.cFileName, ".") == 0) continue; if (strcmp(fd.cFileName, "..") == 0) continue; size_t nl = strlen(fd.cFileName); if (len + nl + 2 > cap) { while (len + nl + 2 > cap) cap *= 2; char* n2 = (char*) GC_MALLOC(cap); memcpy(n2, out, len + 1); out = n2; } memcpy(out + len, fd.cFileName, nl); len += nl; out[len++] = '\n'; out[len] = '\0'; } while (FindNextFileA(h, &fd)); FindClose(h); } #else { DIR* d = opendir(path); if (!d) return out; struct dirent* e; while ((e = readdir(d)) != NULL) { if (strcmp(e->d_name, ".") == 0) continue; if (strcmp(e->d_name, "..") == 0) continue; size_t nl = strlen(e->d_name); if (len + nl + 2 > cap) { while (len + nl + 2 > cap) cap *= 2; char* n2 = (char*) GC_MALLOC(cap); memcpy(n2, out, len + 1); out = n2; } memcpy(out + len, e->d_name, nl); len += nl; out[len++] = '\n'; out[len] = '\0'; } closedir(d); } #endif return out; } typedef struct _Amalgame_Compiler_AddCommand Amalgame_Compiler_AddCommand; /* inline-C top-level */ #include #include #ifndef _WIN32 #include #endif #ifdef _WIN32 #include #endif #ifdef __APPLE__ // macOS-specific: dyld for _NSGetExecutablePath (ResolveSelfPath), // stdlib for realpath(). MUST live at file scope — including // mach-o/dyld.h inside a function body pulls in OSByteOrder.h // whose inline definitions trip clang ("function definition is // not allowed here"). gcc is more permissive but the file-scope // include is the portable place anyway. #include #include #endif typedef struct _Amalgame_Compiler_MonoTimer Amalgame_Compiler_MonoTimer; typedef struct _Amalgame_Compiler_AmalgameCompiler Amalgame_Compiler_AmalgameCompiler; typedef struct _Amalgame_Compiler_Telemetry Amalgame_Compiler_Telemetry; typedef struct _Amalgame_Compiler_Program Amalgame_Compiler_Program; Amalgame_Compiler_Token* Amalgame_Compiler_Token_new(Amalgame_Compiler_TokenType t, code_string value, i64 line, i64 col, code_string file); code_string Amalgame_Compiler_Token_ToString(Amalgame_Compiler_Token* self); code_bool Amalgame_Compiler_Token_IsKeyword(Amalgame_Compiler_Token* self); Amalgame_Compiler_AstNode* Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind kind, i64 line, i64 col); Amalgame_Compiler_Ast* Amalgame_Compiler_Ast_new(); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Program(i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Class(code_string name, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Method(code_string name, code_string retType, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Param(code_string name, code_string typeName, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Block(i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_VarDecl(code_string name, code_bool isMut, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Return(Amalgame_Compiler_AstNode* value, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_If(Amalgame_Compiler_AstNode* cond, Amalgame_Compiler_AstNode* then, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Binary(Amalgame_Compiler_AstNode* left, code_string op, Amalgame_Compiler_AstNode* right, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Call(Amalgame_Compiler_AstNode* callee, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Member(Amalgame_Compiler_AstNode* target, code_string member, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Ident(code_string name, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_IntLit(code_string raw, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_StrLit(code_string raw, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_BoolLit(code_bool val, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_FloatLit(code_string raw, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_NewExpr(code_string typeName, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_This(i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_InlineC(code_string body, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_InlineCInclude(code_string arg, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_InlineCLink(code_string lib, i64 line, i64 col); Amalgame_Compiler_Lexer* Amalgame_Compiler_Lexer_new(code_string source, code_string filename); static code_bool Amalgame_Compiler_Lexer_IsSpace(Amalgame_Compiler_Lexer* self, code_string c); static code_bool Amalgame_Compiler_Lexer_IsDigit(Amalgame_Compiler_Lexer* self, code_string c); static code_bool Amalgame_Compiler_Lexer_IsHexDigit(Amalgame_Compiler_Lexer* self, code_string c); static code_bool Amalgame_Compiler_Lexer_IsBinDigit(Amalgame_Compiler_Lexer* self, code_string c); static code_bool Amalgame_Compiler_Lexer_IsAlpha(Amalgame_Compiler_Lexer* self, code_string c); static code_bool Amalgame_Compiler_Lexer_IsAlphaNum(Amalgame_Compiler_Lexer* self, code_string c); static code_string Amalgame_Compiler_Lexer_CharAt(Amalgame_Compiler_Lexer* self, i64 i); static void Amalgame_Compiler_Lexer_AddToken(Amalgame_Compiler_Lexer* self, Amalgame_Compiler_TokenType t, code_string value); static code_string Amalgame_Compiler_Lexer_Advance(Amalgame_Compiler_Lexer* self); static void Amalgame_Compiler_Lexer_SkipWhitespace(Amalgame_Compiler_Lexer* self); static void Amalgame_Compiler_Lexer_ReadLineComment(Amalgame_Compiler_Lexer* self); AmalgameList* Amalgame_Compiler_Lexer_Tokenize(Amalgame_Compiler_Lexer* self); static void Amalgame_Compiler_Lexer_ReadString(Amalgame_Compiler_Lexer* self); static void Amalgame_Compiler_Lexer_ReadTripleQuoted(Amalgame_Compiler_Lexer* self); static void Amalgame_Compiler_Lexer_TryReadInlineCOrAt(Amalgame_Compiler_Lexer* self, i64 startCol); static void Amalgame_Compiler_Lexer_ReadInlineCBody(Amalgame_Compiler_Lexer* self, i64 startCol); static i64 Amalgame_Compiler_Lexer_HexNibble(Amalgame_Compiler_Lexer* self, code_string ch); static void Amalgame_Compiler_Lexer_ReadNumber(Amalgame_Compiler_Lexer* self); static void Amalgame_Compiler_Lexer_ReadIdentifier(Amalgame_Compiler_Lexer* self); static Amalgame_Compiler_TokenType Amalgame_Compiler_Lexer_LookupKeyword(Amalgame_Compiler_Lexer* self, code_string word); static void Amalgame_Compiler_Lexer_ReadSymbol(Amalgame_Compiler_Lexer* self); Amalgame_Compiler_Parser* Amalgame_Compiler_Parser_new(AmalgameList* tokens); static void Amalgame_Compiler_Parser_ParseDecoratorList(Amalgame_Compiler_Parser* self); static code_string Amalgame_Compiler_Parser_TakeDecorators(Amalgame_Compiler_Parser* self); Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_Parse(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseInlineCDirective(Amalgame_Compiler_Parser* self); code_bool Amalgame_Compiler_Parser_HasErrors(Amalgame_Compiler_Parser* self); code_string Amalgame_Compiler_Parser_GetErrors(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_Current(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_Peek(Amalgame_Compiler_Parser* self, i64 offset); static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_Advance(Amalgame_Compiler_Parser* self); static code_bool Amalgame_Compiler_Parser_IsEnd(Amalgame_Compiler_Parser* self); static code_bool Amalgame_Compiler_Parser_CheckType(Amalgame_Compiler_Parser* self, Amalgame_Compiler_TokenType t); static code_bool Amalgame_Compiler_Parser_CheckKw(Amalgame_Compiler_Parser* self, code_string word); static code_bool Amalgame_Compiler_Parser_CheckValue(Amalgame_Compiler_Parser* self, code_string v); static void Amalgame_Compiler_Parser_SkipNewlines(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_Expect(Amalgame_Compiler_Parser* self, code_string value); static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_ExpectIdent(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_Unknown(Amalgame_Compiler_Parser* self); static code_string Amalgame_Compiler_Parser_ParseQualifiedName(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseDecl(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseClass(Amalgame_Compiler_Parser* self, code_bool isPublic); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseDataClass(Amalgame_Compiler_Parser* self, code_bool isPublic); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMember(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseField(Amalgame_Compiler_Parser* self, code_bool isPublic); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMethod(Amalgame_Compiler_Parser* self, code_string retType, code_bool isPublic, code_bool isStatic, code_bool isAsync, i64 line, i64 col); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseParam(Amalgame_Compiler_Parser* self); static code_string Amalgame_Compiler_Parser_ParseTypeName(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseBlock(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseStmt(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseLoop(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseRegion(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseSetup(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseTry(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseThrow(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseInlineC(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseVarDecl(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseReturn(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseIf(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseGuard(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseWhile(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseForIn(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseEnum(Amalgame_Compiler_Parser* self, code_bool isPublic); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseInterface(Amalgame_Compiler_Parser* self, code_bool isPublic); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseExpr(Amalgame_Compiler_Parser* self); static code_bool Amalgame_Compiler_Parser_IsLambdaParenStart(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseLambdaSingle(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseLambdaMulti(Amalgame_Compiler_Parser* self); static void Amalgame_Compiler_Parser_ParseLambdaBody(Amalgame_Compiler_Parser* self, Amalgame_Compiler_AstNode* lam); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseAssign(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseTernary(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseRange(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseOr(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseBitwiseOr(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseBitwiseXor(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseBitwiseAnd(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseAnd(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseEquality(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseRelational(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseShift(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseAdd(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMul(Amalgame_Compiler_Parser* self); static code_bool Amalgame_Compiler_Parser_LookaheadAfterNewlinesIs(Amalgame_Compiler_Parser* self, code_string s1, code_string s2, code_string s3); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseUnary(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParsePostfix(Amalgame_Compiler_Parser* self); static code_bool Amalgame_Compiler_Parser_LookaheadStartsWithDot(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseCallArgs(Amalgame_Compiler_Parser* self, Amalgame_Compiler_AstNode* callee); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParsePrimary(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseListItem(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseListComp(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMatch(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMatchPattern(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseNew(Amalgame_Compiler_Parser* self); Amalgame_Compiler_TomlValue* Amalgame_Compiler_TomlValue_new(); Amalgame_Compiler_TomlParser* Amalgame_Compiler_TomlParser_new(code_string src); Amalgame_Compiler_Toml* Amalgame_Compiler_Toml_new(); code_bool Amalgame_Compiler_TomlValue_IsNull(Amalgame_Compiler_TomlValue* self); code_bool Amalgame_Compiler_TomlValue_IsBool(Amalgame_Compiler_TomlValue* self); code_bool Amalgame_Compiler_TomlValue_IsInt(Amalgame_Compiler_TomlValue* self); code_bool Amalgame_Compiler_TomlValue_IsString(Amalgame_Compiler_TomlValue* self); code_bool Amalgame_Compiler_TomlValue_IsArray(Amalgame_Compiler_TomlValue* self); code_bool Amalgame_Compiler_TomlValue_IsTable(Amalgame_Compiler_TomlValue* self); code_bool Amalgame_Compiler_TomlValue_AsBool(Amalgame_Compiler_TomlValue* self); i64 Amalgame_Compiler_TomlValue_AsInt(Amalgame_Compiler_TomlValue* self); code_string Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue* self); AmalgameList* Amalgame_Compiler_TomlValue_AsArray(Amalgame_Compiler_TomlValue* self); i64 Amalgame_Compiler_TomlValue_Count(Amalgame_Compiler_TomlValue* self); Amalgame_Compiler_TomlValue* Amalgame_Compiler_TomlValue_At(Amalgame_Compiler_TomlValue* self, i64 idx); Amalgame_Compiler_TomlValue* Amalgame_Compiler_TomlValue_Get(Amalgame_Compiler_TomlValue* self, code_string key); code_bool Amalgame_Compiler_TomlValue_Has(Amalgame_Compiler_TomlValue* self, code_string key); AmalgameList* Amalgame_Compiler_TomlValue_Keys(Amalgame_Compiler_TomlValue* self); void Amalgame_Compiler_TomlValue_SetBool(Amalgame_Compiler_TomlValue* self, code_bool v); void Amalgame_Compiler_TomlValue_SetInt(Amalgame_Compiler_TomlValue* self, i64 v); void Amalgame_Compiler_TomlValue_SetString(Amalgame_Compiler_TomlValue* self, code_string v); void Amalgame_Compiler_TomlValue_BecomeArray(Amalgame_Compiler_TomlValue* self); void Amalgame_Compiler_TomlValue_BecomeTable(Amalgame_Compiler_TomlValue* self); void Amalgame_Compiler_TomlValue_AppendItem(Amalgame_Compiler_TomlValue* self, Amalgame_Compiler_TomlValue* v); void Amalgame_Compiler_TomlValue_SetEntry(Amalgame_Compiler_TomlValue* self, code_string key, Amalgame_Compiler_TomlValue* v); void Amalgame_Compiler_TomlParser_Fail(Amalgame_Compiler_TomlParser* self, code_string msg); code_bool Amalgame_Compiler_TomlParser_AtEnd(Amalgame_Compiler_TomlParser* self); code_string Amalgame_Compiler_TomlParser_Peek(Amalgame_Compiler_TomlParser* self); code_string Amalgame_Compiler_TomlParser_PeekAt(Amalgame_Compiler_TomlParser* self, i64 offset); code_string Amalgame_Compiler_TomlParser_Advance(Amalgame_Compiler_TomlParser* self); void Amalgame_Compiler_TomlParser_SkipInlineSpace(Amalgame_Compiler_TomlParser* self); void Amalgame_Compiler_TomlParser_SkipBlankLines(Amalgame_Compiler_TomlParser* self); static code_bool Amalgame_Compiler_TomlParser_IsBareKeyChar(Amalgame_Compiler_TomlParser* self, code_string c); static code_bool Amalgame_Compiler_TomlParser_IsDigit(Amalgame_Compiler_TomlParser* self, code_string c); code_string Amalgame_Compiler_TomlParser_ReadKey(Amalgame_Compiler_TomlParser* self); code_string Amalgame_Compiler_TomlParser_ReadStringLiteral(Amalgame_Compiler_TomlParser* self); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_Parse(code_string source); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ParseWithError(code_string source, Amalgame_Compiler_TomlParser* parser); static Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_RunParse(Amalgame_Compiler_TomlParser* p, code_string source); AmalgameList* Amalgame_Compiler_Toml_ReadHeaderPath(Amalgame_Compiler_TomlParser* p); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_NavigateOrCreate(Amalgame_Compiler_TomlValue* root, AmalgameList* path); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_AppendArrayTable(Amalgame_Compiler_TomlValue* root, AmalgameList* path); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadValue(Amalgame_Compiler_TomlParser* p); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadArray(Amalgame_Compiler_TomlParser* p); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadInlineTable(Amalgame_Compiler_TomlParser* p); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadBool(Amalgame_Compiler_TomlParser* p); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadInt(Amalgame_Compiler_TomlParser* p); void Amalgame_Compiler_Toml_SkipWsAndNewlines(Amalgame_Compiler_TomlParser* p); code_string Amalgame_Compiler_Toml_Serialize(Amalgame_Compiler_TomlValue* doc); static code_string Amalgame_Compiler_Toml_WriteTable(Amalgame_Compiler_TomlValue* t, AmalgameList* path, code_string out); static code_string Amalgame_Compiler_Toml_WriteValue(Amalgame_Compiler_TomlValue* v); static code_string Amalgame_Compiler_Toml_EscapeString(code_string s); static code_string Amalgame_Compiler_Toml_JoinPath(AmalgameList* path); Amalgame_Compiler_LoadedPackage* Amalgame_Compiler_LoadedPackage_new(); Amalgame_Compiler_PackageRegistry* Amalgame_Compiler_PackageRegistry_new(); Amalgame_Compiler_CalibrationSample* Amalgame_Compiler_CalibrationSample_new(); Amalgame_Compiler_Calibration* Amalgame_Compiler_Calibration_new(); Amalgame_Compiler_PackageRegistry* Amalgame_Compiler_PackageRegistry_Load(); Amalgame_Compiler_PackageRegistry* Amalgame_Compiler_PackageRegistry_LoadFrom(code_string lockPath, code_string cacheRoot); AmalgameList* Amalgame_Compiler_PackageRegistry_ClassNames(Amalgame_Compiler_PackageRegistry* self); AmalgameList* Amalgame_Compiler_PackageRegistry_Headers(Amalgame_Compiler_PackageRegistry* self); code_bool Amalgame_Compiler_PackageRegistry_HasCxxSources(Amalgame_Compiler_PackageRegistry* self); code_string Amalgame_Compiler_PackageRegistry_FacadeArchivePath(Amalgame_Compiler_LoadedPackage* p); AmalgameList* Amalgame_Compiler_PackageRegistry_CollectFacadeArchives(Amalgame_Compiler_PackageRegistry* self); AmalgameList* Amalgame_Compiler_PackageRegistry_CollectLibs(Amalgame_Compiler_PackageRegistry* self); code_bool Amalgame_Compiler_PackageRegistry_IsCxxSource(code_string path); code_string Amalgame_Compiler_PackageRegistry_AmalgameHome(); code_string Amalgame_Compiler_PackageRegistry_AmalgameStateDir(); code_string Amalgame_Compiler_PackageRegistry_DefaultCacheRoot(); code_string Amalgame_Compiler_PackageRegistry_CalibrationPath(); code_string Amalgame_Compiler_PackageRegistry_PrecompileCacheDir(code_string pkgDir); code_string Amalgame_Compiler_PackageRegistry_PlatformTag(); code_string Amalgame_Compiler_PackageRegistry_ManglePackageSymbol(code_string ns, code_string method); code_string Amalgame_Compiler_PackageRegistry_AmalgameTypeFromC(code_string cType); code_string Amalgame_Compiler_PackageRegistry_AmcVersion(); i64 Amalgame_Compiler_PackageRegistry_SupportedManifestSchema(); AmalgameList* Amalgame_Compiler_PackageRegistry_ParseVersion(code_string v); code_string Amalgame_Compiler_PackageRegistry_ReadCalibrationFile(); code_bool Amalgame_Compiler_PackageRegistry_VersionSatisfies(code_string current, code_string constraint); i64 Amalgame_Compiler_PackageRegistry_CompareCmp(code_string a, code_string b); code_bool Amalgame_Compiler_PackageRegistry_CaretSatisfies(code_string current, code_string base); code_bool Amalgame_Compiler_PackageRegistry_TildeSatisfies(code_string current, code_string base); Amalgame_Compiler_Calibration* Amalgame_Compiler_Calibration_Load(); void Amalgame_Compiler_Calibration_Add(Amalgame_Compiler_Calibration* self, code_string lang, i64 sizeKb, i64 elapsedS, code_string pkgVer); i64 Amalgame_Compiler_Calibration_EstimateSeconds(Amalgame_Compiler_Calibration* self, code_string lang, i64 sizeKb); i64 Amalgame_Compiler_Calibration_SampleCount(Amalgame_Compiler_Calibration* self, code_string lang); code_bool Amalgame_Compiler_Calibration_Save(Amalgame_Compiler_Calibration* self); Amalgame_Compiler_Emitter* Amalgame_Compiler_Emitter_new(); Amalgame_Compiler_CGen* Amalgame_Compiler_CGen_new(); void Amalgame_Compiler_Emitter_SetStreaming(Amalgame_Compiler_Emitter* self, code_bool v); void Amalgame_Compiler_Emitter_Emit(Amalgame_Compiler_Emitter* self, code_string text); void Amalgame_Compiler_Emitter_EmitLine(Amalgame_Compiler_Emitter* self, code_string text); void Amalgame_Compiler_Emitter_EmitBlank(Amalgame_Compiler_Emitter* self); void Amalgame_Compiler_Emitter_Indent_(Amalgame_Compiler_Emitter* self); void Amalgame_Compiler_Emitter_Dedent(Amalgame_Compiler_Emitter* self); code_string Amalgame_Compiler_Emitter_GetOutput(Amalgame_Compiler_Emitter* self); code_string Amalgame_Compiler_CGen_Generate(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); void Amalgame_Compiler_CGen_SetStreaming(Amalgame_Compiler_CGen* self, code_bool v); void Amalgame_Compiler_CGen_BeginMulti(Amalgame_Compiler_CGen* self, code_string ns); void Amalgame_Compiler_CGen_AddFilePass1(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); void Amalgame_Compiler_CGen_EmitSeparator(Amalgame_Compiler_CGen* self); void Amalgame_Compiler_CGen_AddFilePass2(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog, code_string sourcePath); void Amalgame_Compiler_CGen_AddFilePass2Forwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); void Amalgame_Compiler_CGen_AddFilePass2Bodies(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog, code_string sourcePath); static void Amalgame_Compiler_CGen_EmitMethodForwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); static void Amalgame_Compiler_CGen_EmitConstructorForwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); static void Amalgame_Compiler_CGen_EmitLambdaForwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* node); static void Amalgame_Compiler_CGen_EmitLambdaBodies(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* node); static void Amalgame_Compiler_CGen_EmitOneLambdaForward(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* lam); static void Amalgame_Compiler_CGen_EmitOneLambdaBody(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* lam); code_string Amalgame_Compiler_CGen_FinishMulti(Amalgame_Compiler_CGen* self); AmalgameList* Amalgame_Compiler_CGen_GetLines(Amalgame_Compiler_CGen* self); static code_string Amalgame_Compiler_CGen_SymName(Amalgame_Compiler_CGen* self, code_string name); static void Amalgame_Compiler_CGen_LocalTypeSet(Amalgame_Compiler_CGen* self, code_string varName, code_string ctype); static code_string Amalgame_Compiler_CGen_LocalTypeGet(Amalgame_Compiler_CGen* self, code_string varName); static void Amalgame_Compiler_CGen_LocalTypeClear(Amalgame_Compiler_CGen* self); static void Amalgame_Compiler_CGen_FieldTypeSet(Amalgame_Compiler_CGen* self, code_string className, code_string fieldName, code_string ctype); static code_string Amalgame_Compiler_CGen_FieldTypeGet(Amalgame_Compiler_CGen* self, code_string className, code_string fieldName); static code_string Amalgame_Compiler_CGen_ResolveReceiverClass(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* node); static void Amalgame_Compiler_CGen_TrackMapResultElem(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_CGen_TrackGenericLocal(Amalgame_Compiler_CGen* self, code_string varName, code_string rawType); static code_string Amalgame_Compiler_CGen_PeelOneGenericLayer(Amalgame_Compiler_CGen* self, code_string rawType); static code_string Amalgame_Compiler_CGen_RecoverChainedListElemRaw(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* recv); static void Amalgame_Compiler_CGen_ListElemSet(Amalgame_Compiler_CGen* self, code_string className, code_string fieldName, code_string elemCType); static code_string Amalgame_Compiler_CGen_ListElemGet(Amalgame_Compiler_CGen* self, code_string className, code_string fieldName); static void Amalgame_Compiler_CGen_MethodRetSet(Amalgame_Compiler_CGen* self, code_string className, code_string methodName, code_string ctype); static void Amalgame_Compiler_CGen_MethodRetRawSet(Amalgame_Compiler_CGen* self, code_string className, code_string methodName, code_string rawType); static code_string Amalgame_Compiler_CGen_MethodRetRawGet(Amalgame_Compiler_CGen* self, code_string className, code_string methodName); static code_string Amalgame_Compiler_CGen_MethodRetGet(Amalgame_Compiler_CGen* self, code_string className, code_string methodName); static void Amalgame_Compiler_CGen_MethodVariadicSet(Amalgame_Compiler_CGen* self, code_string cname, i64 fixedArity); static i64 Amalgame_Compiler_CGen_MethodVariadicGet(Amalgame_Compiler_CGen* self, code_string cname); static code_string Amalgame_Compiler_CGen_InferTypeFromExpr(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* expr); static code_string Amalgame_Compiler_CGen_InferTypeFromExprUncached(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* expr); static code_bool Amalgame_Compiler_CGen_IsValidInterpExpr(Amalgame_Compiler_CGen* self, code_string s); static code_string Amalgame_Compiler_CGen_EmitInterpolatedString(Amalgame_Compiler_CGen* self, code_string raw); static code_string Amalgame_Compiler_CGen_WrapForInterp(Amalgame_Compiler_CGen* self, code_string cExpr, code_string cType); static code_string Amalgame_Compiler_CGen_BuiltinCallReturnType(Amalgame_Compiler_CGen* self, code_string cName); static code_string Amalgame_Compiler_CGen_InterpExprToC(Amalgame_Compiler_CGen* self, code_string expr); static code_string Amalgame_Compiler_CGen_EscapeStringForC(Amalgame_Compiler_CGen* self, code_string raw); static void Amalgame_Compiler_CGen_EmitHeader(Amalgame_Compiler_CGen* self); code_bool Amalgame_Compiler_CGen_NamespaceImported(Amalgame_Compiler_CGen* self, code_string ns); void Amalgame_Compiler_CGen_SetImportedNamespaces(Amalgame_Compiler_CGen* self, AmalgameList* imports); void Amalgame_Compiler_CGen_SetEmbedded(Amalgame_Compiler_CGen* self, code_bool v); static code_string Amalgame_Compiler_CGen_AllocFn(Amalgame_Compiler_CGen* self); void Amalgame_Compiler_CGen_EmitNetHeader(Amalgame_Compiler_CGen* self); void Amalgame_Compiler_CGen_RegisterPackages(Amalgame_Compiler_CGen* self, Amalgame_Compiler_PackageRegistry* reg); void Amalgame_Compiler_CGen_RegisterExternalProg(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); void Amalgame_Compiler_CGen_RegisterExternalProgPass1(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); void Amalgame_Compiler_CGen_RegisterExternalProgPass2(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); static code_string Amalgame_Compiler_CGen_ExternalMethodSig(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string mangledClass, code_string shortClassName); code_string Amalgame_Compiler_CGen_ExternalClassMangled(Amalgame_Compiler_CGen* self, code_string tname); code_string Amalgame_Compiler_CGen_ExternalEnumMangled(Amalgame_Compiler_CGen* self, code_string tname); static code_bool Amalgame_Compiler_CGen_IsExternalClass(Amalgame_Compiler_CGen* self, code_string tname); static AmalgameList* Amalgame_Compiler_CGen_SplitTopLevelCommas(Amalgame_Compiler_CGen* self, code_string s); static code_bool Amalgame_Compiler_CGen_IsLocalClass(Amalgame_Compiler_CGen* self, code_string tname); static void Amalgame_Compiler_CGen_RegisterIface(Amalgame_Compiler_CGen* self, code_string shortName, code_string mangled, Amalgame_Compiler_AstNode* node); void Amalgame_Compiler_CGen_PreNoteInterfaces(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); static code_bool Amalgame_Compiler_CGen_IsInterface(Amalgame_Compiler_CGen* self, code_string tname); static code_string Amalgame_Compiler_CGen_IfaceMangledFor(Amalgame_Compiler_CGen* self, code_string tname); static Amalgame_Compiler_AstNode* Amalgame_Compiler_CGen_IfaceNodeFor(Amalgame_Compiler_CGen* self, code_string nameOrMangled); static code_string Amalgame_Compiler_CGen_IfaceItabSym(Amalgame_Compiler_CGen* self, code_string classMangled, code_string ifaceMangled); static code_string Amalgame_Compiler_CGen_IfaceFnPtrField(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* m); static code_string Amalgame_Compiler_CGen_IfaceFnPtrCast(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* m); static void Amalgame_Compiler_CGen_RegisterParamIfaces(Amalgame_Compiler_CGen* self, code_string mangled, Amalgame_Compiler_AstNode* m); static code_string Amalgame_Compiler_CGen_CoerceArg(Amalgame_Compiler_CGen* self, code_string callee, i64 idx, Amalgame_Compiler_AstNode* argExpr); static code_string Amalgame_Compiler_CGen_CoerceToIface(Amalgame_Compiler_CGen* self, code_string ifaceMangled, Amalgame_Compiler_AstNode* argExpr); static code_string Amalgame_Compiler_CGen_BoxIface(Amalgame_Compiler_CGen* self, code_string ifaceMangled, code_string fatExpr); static code_string Amalgame_Compiler_CGen_ResolveListElemC(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* callee); static code_string Amalgame_Compiler_CGen_PkgClassMangledPrefix(Amalgame_Compiler_CGen* self, code_string tname); static code_string Amalgame_Compiler_CGen_ClassMangledFor(Amalgame_Compiler_CGen* self, code_string tname); static void Amalgame_Compiler_CGen_EmitForwardDecl(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_CGen_EmitDecl(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_CGen_EmitEnum(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* en); static void Amalgame_Compiler_CGen_EmitClass(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* cls); static void Amalgame_Compiler_CGen_EmitClassItabs(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* cls, code_string name); static code_string Amalgame_Compiler_CGen_TupleStructName(Amalgame_Compiler_CGen* self, code_string tupleType); static void Amalgame_Compiler_CGen_EnsureTupleStruct(Amalgame_Compiler_CGen* self, code_string tupleType); static code_string Amalgame_Compiler_CGen_MethodSig(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string className); static code_string Amalgame_Compiler_CGen_AsyncEnvName(Amalgame_Compiler_CGen* self, code_string mangledClass, code_string mname); static code_string Amalgame_Compiler_CGen_AsyncImplSig(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string className); static code_string Amalgame_Compiler_CGen_AsyncWrapperSig(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string className); static code_string Amalgame_Compiler_CGen_AsyncRetCType(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method); static void Amalgame_Compiler_CGen_EmitAsyncForwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string mangledClass); static void Amalgame_Compiler_CGen_EmitAsyncMethod(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string mangledClass); static code_string Amalgame_Compiler_CGen_BoxAsVoidI64(Amalgame_Compiler_CGen* self, code_string expr); static code_string Amalgame_Compiler_CGen_ResolveAwaitRetC(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* operand); static void Amalgame_Compiler_CGen_EmitMethod(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string className); static code_string Amalgame_Compiler_CGen_EmitIfBranch(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* block); static void Amalgame_Compiler_CGen_EmitMatch(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_CGen_EmitMatchBody(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* body); static void Amalgame_Compiler_CGen_EmitIf(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_CGen_EmitIfTail(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_CGen_EmitBlock(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* block); static void Amalgame_Compiler_CGen_EmitLineDirective(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_CGen_EmitStmt(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt); static code_string Amalgame_Compiler_CGen_EmitExprStr(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* expr); static code_string Amalgame_Compiler_CGen_EmitListLiteral(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_CGen_EmitVariadicTail(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* call, i64 fixedArity); static code_string Amalgame_Compiler_CGen_EmitMatchExpr(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_CGen_EmitListComp(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_CGen_TryEmitListCall(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* callExpr); static code_string Amalgame_Compiler_CGen_EmitClosureArg(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* arg); static code_string Amalgame_Compiler_CGen_EmitLambdaAsClosure(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* lam); static code_string Amalgame_Compiler_CGen_EmitLambdaCaptureCopy(Amalgame_Compiler_CGen* self, code_string envVar, Amalgame_Compiler_AstNode* cap); static code_string Amalgame_Compiler_CGen_EmitCalleeStr(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* callee); static code_bool Amalgame_Compiler_CGen_IsEnum(Amalgame_Compiler_CGen* self, code_string t); static code_bool Amalgame_Compiler_CGen_IsCPointerType(Amalgame_Compiler_CGen* self, code_string ct); static code_string Amalgame_Compiler_CGen_BoxAsVoid(Amalgame_Compiler_CGen* self, code_string expr); static code_string Amalgame_Compiler_CGen_UnboxScalar(Amalgame_Compiler_CGen* self, code_string ctype, code_string expr); static code_string Amalgame_Compiler_CGen_TypeToC(Amalgame_Compiler_CGen* self, code_string t); Amalgame_Compiler_Formatter* Amalgame_Compiler_Formatter_new(AmalgameList* comments); code_string Amalgame_Compiler_Formatter_Format(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* prog); static code_string Amalgame_Compiler_Formatter_IndentStr(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_Begin(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_Write(Amalgame_Compiler_Formatter* self, code_string s); static void Amalgame_Compiler_Formatter_End(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_Line(Amalgame_Compiler_Formatter* self, code_string s); static void Amalgame_Compiler_Formatter_Close(Amalgame_Compiler_Formatter* self, code_string s); static void Amalgame_Compiler_Formatter_Blank(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_In_(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_De_(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_AttachToLastEmitted(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_Token* c); static void Amalgame_Compiler_Formatter_DrainTrailingForLastLine(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_Sync(Amalgame_Compiler_Formatter* self, i64 line); static void Amalgame_Compiler_Formatter_FlushTrailingComments(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_EmitProgram(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* prog); static void Amalgame_Compiler_Formatter_EmitTopDecl(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitClass(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitClassMember(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* m, code_string className); static void Amalgame_Compiler_Formatter_EmitMethod(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n, code_string className); static code_string Amalgame_Compiler_Formatter_EmitParams(Amalgame_Compiler_Formatter* self, AmalgameList* params); static void Amalgame_Compiler_Formatter_EmitField(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitEnum(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static i64 Amalgame_Compiler_Formatter_MaxLineInTree(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static i64 Amalgame_Compiler_Formatter_BlockEndLine(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* body); static void Amalgame_Compiler_Formatter_EmitBlockStmts(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* body); static void Amalgame_Compiler_Formatter_EmitInline(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* body); static void Amalgame_Compiler_Formatter_EmitStmt(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitTry(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitThrow(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitInlineC(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitBlock(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitIf(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitElseTail(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitMatch(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitPattern(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitWhile(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitForIn(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitVarDecl(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n, code_bool topLevel); static void Amalgame_Compiler_Formatter_EmitReturn(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitExpr(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitBinary(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitUnary(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitCall(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitMember(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitIndex(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitMatchExpr(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitIfExpr(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitLambda(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_LambdaParamName(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* p); static code_string Amalgame_Compiler_Formatter_EmitBlockAsExpr(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* body); static code_string Amalgame_Compiler_Formatter_EmitNew(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_QuoteString(Amalgame_Compiler_Formatter* self, code_string content); static code_string Amalgame_Compiler_Formatter_KindName(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_NodeKind k); Amalgame_Compiler_Ansi* Amalgame_Compiler_Ansi_new(); Amalgame_Compiler_SourceMap* Amalgame_Compiler_SourceMap_new(); Amalgame_Compiler_SourceSnippet* Amalgame_Compiler_SourceSnippet_new(); Amalgame_Compiler_Diagnostic* Amalgame_Compiler_Diagnostic_new(Amalgame_Compiler_DiagSeverity sev, code_string kind, code_string msg, code_string file, i64 line, i64 col); Amalgame_Compiler_DiagnosticFormatter* Amalgame_Compiler_DiagnosticFormatter_new(); code_string Amalgame_Compiler_Ansi_Reset(); code_string Amalgame_Compiler_Ansi_Bold(); code_string Amalgame_Compiler_Ansi_Dim(); code_string Amalgame_Compiler_Ansi_Red(); code_string Amalgame_Compiler_Ansi_Yellow(); code_string Amalgame_Compiler_Ansi_Cyan(); code_string Amalgame_Compiler_Ansi_Green(); code_string Amalgame_Compiler_Ansi_Blue(); code_string Amalgame_Compiler_Ansi_BoldRed(); code_string Amalgame_Compiler_Ansi_BoldYellow(); code_string Amalgame_Compiler_Ansi_BoldCyan(); code_string Amalgame_Compiler_Ansi_BoldGreen(); code_string Amalgame_Compiler_Ansi_BoldBlue(); void Amalgame_Compiler_SourceMap_Add(Amalgame_Compiler_SourceMap* self, code_string path, code_string text); code_string Amalgame_Compiler_SourceMap_GetLine(Amalgame_Compiler_SourceMap* self, code_string path, i64 line); code_string Amalgame_Compiler_SourceSnippet_Format(code_string lineText, i64 line, i64 col); static code_string Amalgame_Compiler_SourceSnippet_Spaces(i64 n); void Amalgame_Compiler_DiagnosticFormatter_EnableColor(Amalgame_Compiler_DiagnosticFormatter* self, code_bool v); void Amalgame_Compiler_DiagnosticFormatter_SetQuiet(Amalgame_Compiler_DiagnosticFormatter* self, code_bool v); void Amalgame_Compiler_DiagnosticFormatter_LoadSource(Amalgame_Compiler_DiagnosticFormatter* self, code_string path, code_string text); static code_string Amalgame_Compiler_DiagnosticFormatter_SevLabel(Amalgame_Compiler_DiagnosticFormatter* self, Amalgame_Compiler_DiagSeverity sev); code_string Amalgame_Compiler_DiagnosticFormatter_FormatDiag(Amalgame_Compiler_DiagnosticFormatter* self, Amalgame_Compiler_Diagnostic* d); code_string Amalgame_Compiler_DiagnosticFormatter_FormatError(Amalgame_Compiler_DiagnosticFormatter* self, code_string kind, code_string message, code_string filename, i64 line, i64 col); code_string Amalgame_Compiler_DiagnosticFormatter_FormatWarning(Amalgame_Compiler_DiagnosticFormatter* self, code_string kind, code_string message, code_string filename, i64 line, i64 col); code_string Amalgame_Compiler_DiagnosticFormatter_FormatNote(Amalgame_Compiler_DiagnosticFormatter* self, code_string kind, code_string message, code_string filename, i64 line, i64 col); void Amalgame_Compiler_DiagnosticFormatter_PrintPhaseOk(Amalgame_Compiler_DiagnosticFormatter* self, code_string phase); void Amalgame_Compiler_DiagnosticFormatter_PrintPhaseError(Amalgame_Compiler_DiagnosticFormatter* self, code_string phase, code_string detail); void Amalgame_Compiler_DiagnosticFormatter_PrintCompileOk(Amalgame_Compiler_DiagnosticFormatter* self, code_string phase); void Amalgame_Compiler_DiagnosticFormatter_PrintCompileError(Amalgame_Compiler_DiagnosticFormatter* self, code_string phase, code_string detail); code_string Amalgame_Compiler_DiagnosticFormatter_FormatSummary(Amalgame_Compiler_DiagnosticFormatter* self, i64 errorCount, i64 warningCount); code_string Amalgame_Compiler_DiagnosticFormatter_FormatCompact(Amalgame_Compiler_DiagnosticFormatter* self, code_string severity, code_string kind, code_string message, code_string filename, i64 line, i64 col); Amalgame_Compiler_Symbol* Amalgame_Compiler_Symbol_new(code_string name, Amalgame_Compiler_SymKind kind); Amalgame_Compiler_SymbolTable* Amalgame_Compiler_SymbolTable_new(); Amalgame_Compiler_Resolver* Amalgame_Compiler_Resolver_new(); void Amalgame_Compiler_SymbolTable_Declare(Amalgame_Compiler_SymbolTable* self, Amalgame_Compiler_Symbol* sym); code_bool Amalgame_Compiler_SymbolTable_Has(Amalgame_Compiler_SymbolTable* self, code_string name); Amalgame_Compiler_Symbol* Amalgame_Compiler_SymbolTable_Lookup(Amalgame_Compiler_SymbolTable* self, code_string name); code_bool Amalgame_Compiler_SymbolTable_HasSymbol(Amalgame_Compiler_SymbolTable* self, code_string name); code_string Amalgame_Compiler_SymbolTable_GetTypeName(Amalgame_Compiler_SymbolTable* self, code_string name); void Amalgame_Compiler_SymbolTable_SetTypeName(Amalgame_Compiler_SymbolTable* self, code_string name, code_string typeName); static void Amalgame_Compiler_Resolver_RegisterBuiltins(Amalgame_Compiler_Resolver* self); void Amalgame_Compiler_Resolver_Resolve(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* prog); void Amalgame_Compiler_Resolver_ResolvePrograms(Amalgame_Compiler_Resolver* self); code_bool Amalgame_Compiler_Resolver_HasErrors(Amalgame_Compiler_Resolver* self); code_string Amalgame_Compiler_Resolver_GetErrors(Amalgame_Compiler_Resolver* self); static void Amalgame_Compiler_Resolver_CollectDecl(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_Resolver_ResolveDecl(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_Resolver_ResolveClass(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* cls); static void Amalgame_Compiler_Resolver_ResolveMethod(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* method, Amalgame_Compiler_SymbolTable* classScope); static void Amalgame_Compiler_Resolver_ResolveBlock(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* block); static void Amalgame_Compiler_Resolver_ResolveStmt(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_Resolver_ResolveExpr(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* expr); static code_bool Amalgame_Compiler_Resolver_LookupInScopes(Amalgame_Compiler_Resolver* self, code_string name); Amalgame_Compiler_MemberTable* Amalgame_Compiler_MemberTable_new(); Amalgame_Compiler_ResolverError* Amalgame_Compiler_ResolverError_new(code_string msg, code_string file, i64 line, i64 col); Amalgame_Compiler_FullResolver* Amalgame_Compiler_FullResolver_new(); void Amalgame_Compiler_MemberTable_Set(Amalgame_Compiler_MemberTable* self, code_string className, code_string memberName, code_string typeName); code_string Amalgame_Compiler_MemberTable_Get(Amalgame_Compiler_MemberTable* self, code_string className, code_string memberName); code_bool Amalgame_Compiler_MemberTable_Has(Amalgame_Compiler_MemberTable* self, code_string className, code_string memberName); i64 Amalgame_Compiler_MemberTable_MemberCountFor(Amalgame_Compiler_MemberTable* self, code_string className); code_string Amalgame_Compiler_MemberTable_MemberNameForAt(Amalgame_Compiler_MemberTable* self, code_string className, i64 idx); void Amalgame_Compiler_FullResolver_RegisterPackages(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_PackageRegistry* reg); static void Amalgame_Compiler_FullResolver_RegisterBuiltins(Amalgame_Compiler_FullResolver* self); static void Amalgame_Compiler_FullResolver_PushScope(Amalgame_Compiler_FullResolver* self, code_string label); static void Amalgame_Compiler_FullResolver_PopScope(Amalgame_Compiler_FullResolver* self); static i64 Amalgame_Compiler_FullResolver_CurrentScopeStart(Amalgame_Compiler_FullResolver* self); static void Amalgame_Compiler_FullResolver_DeclareGlobal(Amalgame_Compiler_FullResolver* self, code_string name, code_string typeName, code_bool isLet); static void Amalgame_Compiler_FullResolver_DeclareLambdaParam(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* p); static code_bool Amalgame_Compiler_FullResolver_DeclareCurrent(Amalgame_Compiler_FullResolver* self, code_string name, code_string typeName, code_bool isLet); static code_bool Amalgame_Compiler_FullResolver_LookupInScopes(Amalgame_Compiler_FullResolver* self, code_string name); static code_string Amalgame_Compiler_FullResolver_LookupType(Amalgame_Compiler_FullResolver* self, code_string name); static code_bool Amalgame_Compiler_FullResolver_LookupIsLet(Amalgame_Compiler_FullResolver* self, code_string name); static i64 Amalgame_Compiler_FullResolver_IndexOfLocal(Amalgame_Compiler_FullResolver* self, code_string name); static void Amalgame_Compiler_FullResolver_AddCapture(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* lam, code_string name, code_string typeName, i64 line, i64 col); static void Amalgame_Compiler_FullResolver_TryCaptureLocalByName(Amalgame_Compiler_FullResolver* self, code_string name, i64 line, i64 col); static void Amalgame_Compiler_FullResolver_CaptureIdentsInInterpExpr(Amalgame_Compiler_FullResolver* self, code_string inner, i64 line, i64 col); static void Amalgame_Compiler_FullResolver_Error(Amalgame_Compiler_FullResolver* self, code_string msg, Amalgame_Compiler_AstNode* node); static void Amalgame_Compiler_FullResolver_ErrorMsg(Amalgame_Compiler_FullResolver* self, code_string msg); static void Amalgame_Compiler_FullResolver_EmitError(Amalgame_Compiler_FullResolver* self, code_string msg, i64 line, i64 col); code_bool Amalgame_Compiler_FullResolver_HasErrors(Amalgame_Compiler_FullResolver* self); code_string Amalgame_Compiler_FullResolver_GetErrors(Amalgame_Compiler_FullResolver* self); i64 Amalgame_Compiler_FullResolver_ProgramCount(Amalgame_Compiler_FullResolver* self); Amalgame_Compiler_AstNode* Amalgame_Compiler_FullResolver_ProgramAt(Amalgame_Compiler_FullResolver* self, i64 i); i64 Amalgame_Compiler_FullResolver_GlobalCount(Amalgame_Compiler_FullResolver* self); code_string Amalgame_Compiler_FullResolver_GlobalNameAt(Amalgame_Compiler_FullResolver* self, i64 i); code_string Amalgame_Compiler_FullResolver_GlobalTypeAt(Amalgame_Compiler_FullResolver* self, i64 i); void Amalgame_Compiler_FullResolver_ResolvePrograms(Amalgame_Compiler_FullResolver* self); void Amalgame_Compiler_FullResolver_CollectAll(Amalgame_Compiler_FullResolver* self); void Amalgame_Compiler_FullResolver_ResolveAll(Amalgame_Compiler_FullResolver* self); static void Amalgame_Compiler_FullResolver_CollectProgram(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* prog); static void Amalgame_Compiler_FullResolver_CollectDecl(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_FullResolver_CollectClassMembers(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* cls); static void Amalgame_Compiler_FullResolver_CollectClassMember(Amalgame_Compiler_FullResolver* self, code_string className, Amalgame_Compiler_AstNode* m); static void Amalgame_Compiler_FullResolver_CollectEnumMembers(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* en); static void Amalgame_Compiler_FullResolver_CollectEnumMember(Amalgame_Compiler_FullResolver* self, code_string enumName, Amalgame_Compiler_AstNode* m); static void Amalgame_Compiler_FullResolver_ResolveEnumChild(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* m); static void Amalgame_Compiler_FullResolver_ResolveProgram(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* prog); static void Amalgame_Compiler_FullResolver_ResolveDecl(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_FullResolver_ResolveClass(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* cls); static void Amalgame_Compiler_FullResolver_PreRegisterMember(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* m); static void Amalgame_Compiler_FullResolver_ResolveMember(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* m); static void Amalgame_Compiler_FullResolver_ResolveMethod(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* method); static void Amalgame_Compiler_FullResolver_ResolveBlock(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* block); static void Amalgame_Compiler_FullResolver_ResolveStmt(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_FullResolver_ResolveIf(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_FullResolver_ResolveElseBranch(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* branch); static void Amalgame_Compiler_FullResolver_ResolveForIn(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_FullResolver_ResolveAssign(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_FullResolver_ResolveMatch(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_FullResolver_ResolveMatchArm(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* arm); static void Amalgame_Compiler_FullResolver_ResolveArmBody(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* body); static code_bool Amalgame_Compiler_FullResolver_HasLambdaArg(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* call); static void Amalgame_Compiler_FullResolver_PatchLambdaParamTypes(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* call); static Amalgame_Compiler_AstNode* Amalgame_Compiler_FullResolver_FindMethodInPrograms(Amalgame_Compiler_FullResolver* self, code_string className, code_string methodName); static void Amalgame_Compiler_FullResolver_PatchLambdasFromTypedClosureParams(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* call, Amalgame_Compiler_AstNode* methodDecl); static AmalgameList* Amalgame_Compiler_FullResolver_SplitTopLevelCommasResolver(Amalgame_Compiler_FullResolver* self, code_string s); static void Amalgame_Compiler_FullResolver_PatchLambdaParamTypesGeneric(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_FullResolver_ResolveExpr(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* expr); static code_string Amalgame_Compiler_FullResolver_InferExprType(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* expr); static code_string Amalgame_Compiler_FullResolver_CollectionElemType(Amalgame_Compiler_FullResolver* self, code_string typeKey); code_string Amalgame_Compiler_FullResolver_GetMemberType(Amalgame_Compiler_FullResolver* self, code_string className, code_string memberName); code_bool Amalgame_Compiler_FullResolver_HasMember(Amalgame_Compiler_FullResolver* self, code_string className, code_string memberName); code_string Amalgame_Compiler_FullResolver_GetVarType(Amalgame_Compiler_FullResolver* self, code_string name); code_bool Amalgame_Compiler_FullResolver_HasSymbol(Amalgame_Compiler_FullResolver* self, code_string name); code_string Amalgame_Compiler_FullResolver_GetTypeName(Amalgame_Compiler_FullResolver* self, code_string name); void Amalgame_Compiler_FullResolver_SetTypeName(Amalgame_Compiler_FullResolver* self, code_string name, code_string typeName); Amalgame_Compiler_TypeError* Amalgame_Compiler_TypeError_new(code_string msg, code_string file, i64 line, i64 col); Amalgame_Compiler_TypeCheckResult* Amalgame_Compiler_TypeCheckResult_new(); Amalgame_Compiler_TypeChecker* Amalgame_Compiler_TypeChecker_new(Amalgame_Compiler_FullResolver* symbols, code_string filename); code_string Amalgame_Compiler_TypeError_ToString(Amalgame_Compiler_TypeError* self); static void Amalgame_Compiler_TypeChecker_PushScope(Amalgame_Compiler_TypeChecker* self); static void Amalgame_Compiler_TypeChecker_PopScope(Amalgame_Compiler_TypeChecker* self); static void Amalgame_Compiler_TypeChecker_DeclareLocal(Amalgame_Compiler_TypeChecker* self, code_string name, code_string typeName); static code_string Amalgame_Compiler_TypeChecker_LookupLocal(Amalgame_Compiler_TypeChecker* self, code_string name); Amalgame_Compiler_TypeCheckResult* Amalgame_Compiler_TypeChecker_Check(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* program); static code_string Amalgame_Compiler_TypeChecker_NodeKey(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node); static void Amalgame_Compiler_TypeChecker_SetType(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node, code_string typeKey); static code_string Amalgame_Compiler_TypeChecker_GetType(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node); code_string Amalgame_Compiler_TypeChecker_LookupNodeType(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node); static code_bool Amalgame_Compiler_TypeChecker_IsAssignable(Amalgame_Compiler_TypeChecker* self, code_string expected, code_string actual); static code_bool Amalgame_Compiler_TypeChecker_IsPrimitiveValue(Amalgame_Compiler_TypeChecker* self, code_string t); static code_string Amalgame_Compiler_TypeChecker_GenericBase(Amalgame_Compiler_TypeChecker* self, code_string t); static code_bool Amalgame_Compiler_TypeChecker_IsNumericWiden(Amalgame_Compiler_TypeChecker* self, code_string to, code_string from); static code_bool Amalgame_Compiler_TypeChecker_IsBool(Amalgame_Compiler_TypeChecker* self, code_string t); static code_bool Amalgame_Compiler_TypeChecker_IsNumeric(Amalgame_Compiler_TypeChecker* self, code_string t); static code_bool Amalgame_Compiler_TypeChecker_IsNullable(Amalgame_Compiler_TypeChecker* self, code_string t); static code_string Amalgame_Compiler_TypeChecker_BinaryResultType(Amalgame_Compiler_TypeChecker* self, code_string op, code_string left, code_string right); static code_string Amalgame_Compiler_TypeChecker_CollectionElementType(Amalgame_Compiler_TypeChecker* self, code_string typeKey); static code_bool Amalgame_Compiler_TypeChecker_SymbolFound(Amalgame_Compiler_TypeChecker* self, code_string name); static code_string Amalgame_Compiler_TypeChecker_SymbolTypeName(Amalgame_Compiler_TypeChecker* self, code_string name); static void Amalgame_Compiler_TypeChecker_Error(Amalgame_Compiler_TypeChecker* self, code_string msg, Amalgame_Compiler_AstNode* node); static void Amalgame_Compiler_TypeChecker_CheckBool(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node, code_string context); static code_string Amalgame_Compiler_TypeChecker_SymbolType(Amalgame_Compiler_TypeChecker* self, code_string name); static code_string Amalgame_Compiler_TypeChecker_MemberTypeOf(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* classDecl, code_string memberName); static void Amalgame_Compiler_TypeChecker_CheckProgram(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* prog); static void Amalgame_Compiler_TypeChecker_CheckDecl(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_TypeChecker_CheckClass(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* cls); static void Amalgame_Compiler_TypeChecker_CheckImplementsContract(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* cls); static void Amalgame_Compiler_TypeChecker_CheckOneInterface(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* cls, code_string iref); static void Amalgame_Compiler_TypeChecker_CheckOneInterfaceMethod(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* cls, code_string ifaceLabel, Amalgame_Compiler_AstNode* imethod); static Amalgame_Compiler_AstNode* Amalgame_Compiler_TypeChecker_FindInterface(Amalgame_Compiler_TypeChecker* self, code_string name); static Amalgame_Compiler_AstNode* Amalgame_Compiler_TypeChecker_FindInterfaceInProgram(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* prog, code_string name); static AmalgameList* Amalgame_Compiler_TypeChecker_SplitTopLevelCommas(Amalgame_Compiler_TypeChecker* self, code_string s); static code_string Amalgame_Compiler_TypeChecker_SubstType(Amalgame_Compiler_TypeChecker* self, code_string t); static code_string Amalgame_Compiler_TypeChecker_LookupParam(Amalgame_Compiler_TypeChecker* self, code_string t); static void Amalgame_Compiler_TypeChecker_CheckFieldDecl(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* field); static void Amalgame_Compiler_TypeChecker_CheckMethod(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* method); static code_bool Amalgame_Compiler_TypeChecker_HasDecorator(Amalgame_Compiler_TypeChecker* self, code_string list, code_string name); static void Amalgame_Compiler_TypeChecker_IsrCheckNoAlloc(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node); static code_bool Amalgame_Compiler_TypeChecker_NameIn(Amalgame_Compiler_TypeChecker* self, AmalgameList* xs, code_string n); static code_bool Amalgame_Compiler_TypeChecker_IsArenaOrigin(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* e); static code_bool Amalgame_Compiler_TypeChecker_IsPersistOrigin(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* e); static void Amalgame_Compiler_TypeChecker_TrackLocalOrigin(Amalgame_Compiler_TypeChecker* self, code_string name, Amalgame_Compiler_AstNode* init); static void Amalgame_Compiler_TypeChecker_CheckBlock(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* block); static void Amalgame_Compiler_TypeChecker_CheckStmt(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckVarDecl(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckReturn(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckIf(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckElseBranch(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* branch); static void Amalgame_Compiler_TypeChecker_CheckForIn(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckAssign(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckMatch(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckMatchArm(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* arm); static void Amalgame_Compiler_TypeChecker_CheckExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); static code_string Amalgame_Compiler_TypeChecker_CheckIfBranch(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* block); static void Amalgame_Compiler_TypeChecker_CheckBinaryExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_TypeChecker_CheckUnaryExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_TypeChecker_CheckMemberExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_TypeChecker_CheckCallExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_TypeChecker_CheckNewExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_TypeChecker_CheckIndexExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); code_bool Amalgame_Compiler_TypeChecker_HasErrors(Amalgame_Compiler_TypeChecker* self); code_string Amalgame_Compiler_TypeChecker_FormatErrors(Amalgame_Compiler_TypeChecker* self); Amalgame_Compiler_LintWarning* Amalgame_Compiler_LintWarning_new(code_string msg, code_string file, i64 line, i64 col); Amalgame_Compiler_Linter* Amalgame_Compiler_Linter_new(); code_string Amalgame_Compiler_LintWarning_Format(Amalgame_Compiler_LintWarning* self); void Amalgame_Compiler_Linter_Lint(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* prog); code_bool Amalgame_Compiler_Linter_HasWarnings(Amalgame_Compiler_Linter* self); code_string Amalgame_Compiler_Linter_FormatWarnings(Amalgame_Compiler_Linter* self); static void Amalgame_Compiler_Linter_LintDecl(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_Linter_LintMethod(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* method); static void Amalgame_Compiler_Linter_LintBlock(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* block); static code_bool Amalgame_Compiler_Linter_IsTerminator(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_Linter_LintStmt(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* stmt); static code_bool Amalgame_Compiler_Linter_IsAssignOp(Amalgame_Compiler_Linter* self, code_string op); static void Amalgame_Compiler_Linter_LintBlockOrStmt(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Linter_LintExpr(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_Linter_PushScope(Amalgame_Compiler_Linter* self); static void Amalgame_Compiler_Linter_PopScope(Amalgame_Compiler_Linter* self); static void Amalgame_Compiler_Linter_DeclareLocal(Amalgame_Compiler_Linter* self, code_string name, i64 line, i64 col, code_bool isParam); static void Amalgame_Compiler_Linter_DeclareLocalMut(Amalgame_Compiler_Linter* self, code_string name, i64 line, i64 col, code_bool isParam, code_bool isMut); static code_bool Amalgame_Compiler_Linter_IsShadowing(Amalgame_Compiler_Linter* self, code_string name); static void Amalgame_Compiler_Linter_MarkUsed(Amalgame_Compiler_Linter* self, code_string name); static code_bool Amalgame_Compiler_Linter_UsedAfter(Amalgame_Compiler_Linter* self, code_string name, i64 fromIdx); static code_bool Amalgame_Compiler_Linter_AssignedAfter(Amalgame_Compiler_Linter* self, code_string name, i64 fromIdx); static void Amalgame_Compiler_Linter_Warn(Amalgame_Compiler_Linter* self, code_string msg, Amalgame_Compiler_AstNode* node); Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonValue_new(); Amalgame_Compiler_JsonError* Amalgame_Compiler_JsonError_new(code_string msg, i64 line, i64 col); Amalgame_Compiler_JsonResult* Amalgame_Compiler_JsonResult_new(); Amalgame_Compiler_JsonParser* Amalgame_Compiler_JsonParser_new(code_string source); Amalgame_Compiler_Json* Amalgame_Compiler_Json_new(); code_bool Amalgame_Compiler_JsonValue_IsNull(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsBool(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsInt(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsFloat(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsNumber(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsString(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsArray(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsObject(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_AsBool(Amalgame_Compiler_JsonValue* self); i64 Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue* self); double Amalgame_Compiler_JsonValue_AsFloat(Amalgame_Compiler_JsonValue* self); code_string Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue* self); AmalgameList* Amalgame_Compiler_JsonValue_AsArray(Amalgame_Compiler_JsonValue* self); Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonValue_Get(Amalgame_Compiler_JsonValue* self, code_string key); code_bool Amalgame_Compiler_JsonValue_Has(Amalgame_Compiler_JsonValue* self, code_string key); AmalgameList* Amalgame_Compiler_JsonValue_Keys(Amalgame_Compiler_JsonValue* self); Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonValue_At(Amalgame_Compiler_JsonValue* self, i64 i); i64 Amalgame_Compiler_JsonValue_Length(Amalgame_Compiler_JsonValue* self); void Amalgame_Compiler_JsonValue_SetNull(Amalgame_Compiler_JsonValue* self); void Amalgame_Compiler_JsonValue_SetBool(Amalgame_Compiler_JsonValue* self, code_bool b); void Amalgame_Compiler_JsonValue_SetInt(Amalgame_Compiler_JsonValue* self, i64 n); void Amalgame_Compiler_JsonValue_SetFloat(Amalgame_Compiler_JsonValue* self, double f); void Amalgame_Compiler_JsonValue_SetString(Amalgame_Compiler_JsonValue* self, code_string s); void Amalgame_Compiler_JsonValue_SetArray(Amalgame_Compiler_JsonValue* self, AmalgameList* xs); void Amalgame_Compiler_JsonValue_SetObject(Amalgame_Compiler_JsonValue* self, AmalgameList* keys, AmalgameList* vals); void Amalgame_Compiler_JsonValue_AppendItem(Amalgame_Compiler_JsonValue* self, Amalgame_Compiler_JsonValue* v); void Amalgame_Compiler_JsonValue_AppendEntry(Amalgame_Compiler_JsonValue* self, code_string key, Amalgame_Compiler_JsonValue* v); code_bool Amalgame_Compiler_JsonParser_HasFailed(Amalgame_Compiler_JsonParser* self); code_string Amalgame_Compiler_JsonParser_ErrorMsg(Amalgame_Compiler_JsonParser* self); i64 Amalgame_Compiler_JsonParser_ErrorLine(Amalgame_Compiler_JsonParser* self); i64 Amalgame_Compiler_JsonParser_ErrorCol(Amalgame_Compiler_JsonParser* self); static void Amalgame_Compiler_JsonParser_Fail(Amalgame_Compiler_JsonParser* self, code_string msg); static code_bool Amalgame_Compiler_JsonParser_AtEnd(Amalgame_Compiler_JsonParser* self); static code_string Amalgame_Compiler_JsonParser_Peek(Amalgame_Compiler_JsonParser* self); static code_string Amalgame_Compiler_JsonParser_PeekAt(Amalgame_Compiler_JsonParser* self, i64 offset); static code_string Amalgame_Compiler_JsonParser_Advance(Amalgame_Compiler_JsonParser* self); static void Amalgame_Compiler_JsonParser_SkipWs(Amalgame_Compiler_JsonParser* self); static code_bool Amalgame_Compiler_JsonParser_MatchLit(Amalgame_Compiler_JsonParser* self, code_string lit); Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseTopLevel(Amalgame_Compiler_JsonParser* self); Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseValue(Amalgame_Compiler_JsonParser* self); static code_bool Amalgame_Compiler_JsonParser_IsDigit(code_string c); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseObject(Amalgame_Compiler_JsonParser* self); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseArray(Amalgame_Compiler_JsonParser* self); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseString(Amalgame_Compiler_JsonParser* self); static i64 Amalgame_Compiler_JsonParser_ParseHex4(Amalgame_Compiler_JsonParser* self); static i64 Amalgame_Compiler_JsonParser_HexDigit(code_string c); static code_string Amalgame_Compiler_JsonParser_Bs(); static code_string Amalgame_Compiler_JsonParser_Ff(); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseNumber(Amalgame_Compiler_JsonParser* self); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseBool(Amalgame_Compiler_JsonParser* self); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseNull(Amalgame_Compiler_JsonParser* self); Amalgame_Compiler_JsonResult* Amalgame_Compiler_Json_Parse(code_string source); code_string Amalgame_Compiler_Json_Encode(Amalgame_Compiler_JsonValue* v); static code_string Amalgame_Compiler_Json_EncodeArray(Amalgame_Compiler_JsonValue* v); static code_string Amalgame_Compiler_Json_EncodeObject(Amalgame_Compiler_JsonValue* v); code_string Amalgame_Compiler_Json_EscapeString(code_string s); Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_NullValue(); Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfBool(code_bool b); Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfInt(i64 n); Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfFloat(double f); Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfString(code_string s); Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfArray(AmalgameList* xs); Amalgame_Compiler_MsgPackCursor* Amalgame_Compiler_MsgPackCursor_new(AmalgameList* bytes); Amalgame_Compiler_MsgPack* Amalgame_Compiler_MsgPack_new(); code_bool Amalgame_Compiler_MsgPackCursor_AtEnd(Amalgame_Compiler_MsgPackCursor* self); i64 Amalgame_Compiler_MsgPackCursor_Read(Amalgame_Compiler_MsgPackCursor* self); AmalgameList* Amalgame_Compiler_MsgPack_EncodeJson(Amalgame_Compiler_JsonValue* value); static void Amalgame_Compiler_MsgPack_EncodeJsonInto(Amalgame_Compiler_JsonValue* value, AmalgameList* out); static void Amalgame_Compiler_MsgPack_EncodeInt(i64 v, AmalgameList* out); static void Amalgame_Compiler_MsgPack_EncodeString(code_string s, AmalgameList* out); static void Amalgame_Compiler_MsgPack_EncodeArrayHeader(i64 n, AmalgameList* out); static void Amalgame_Compiler_MsgPack_EncodeMapHeader(i64 n, AmalgameList* out); static i64 Amalgame_Compiler_MsgPack_ByteOf(i64 v, i64 byteIdx); static i64 Amalgame_Compiler_MsgPack_ByteOfI64(i64 v, i64 byteIdx); static i64 Amalgame_Compiler_MsgPack_Pow256(i64 n); static i64 Amalgame_Compiler_MsgPack_ByteOfChar(code_string c); static code_string Amalgame_Compiler_MsgPack_AsciiTable(); Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_DecodeJson(AmalgameList* bytes); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_DecodeOne(Amalgame_Compiler_MsgPackCursor* c); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_ReadStrInto(Amalgame_Compiler_MsgPackCursor* c, i64 n); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_ReadArrayInto(Amalgame_Compiler_MsgPackCursor* c, i64 n); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_ReadMapInto(Amalgame_Compiler_MsgPackCursor* c, i64 n); Amalgame_Compiler_BuildInfo* Amalgame_Compiler_BuildInfo_new(); code_string Amalgame_Compiler_BuildInfo_GitRev(); code_string Amalgame_Compiler_BuildInfo_BuildDate(); Amalgame_Compiler_LspServer* Amalgame_Compiler_LspServer_new(); static void Amalgame_Compiler_LspServer_InvalidateResolverCache(Amalgame_Compiler_LspServer* self); i64 Amalgame_Compiler_LspServer_Run(Amalgame_Compiler_LspServer* self); static void Amalgame_Compiler_LspServer_UpsertDoc(Amalgame_Compiler_LspServer* self, code_string uri, code_string text); static void Amalgame_Compiler_LspServer_RemoveDoc(Amalgame_Compiler_LspServer* self, code_string uri); static code_string Amalgame_Compiler_LspServer_LookupDoc(Amalgame_Compiler_LspServer* self, code_string uri); static code_string Amalgame_Compiler_LspServer_ReadMessage(Amalgame_Compiler_LspServer* self); code_string Amalgame_Compiler_LspServer_Cr(); static void Amalgame_Compiler_LspServer_Send(Amalgame_Compiler_LspServer* self, code_string body); static void Amalgame_Compiler_LspServer_SendInit(Amalgame_Compiler_LspServer* self, i64 id); static void Amalgame_Compiler_LspServer_SendShutdown(Amalgame_Compiler_LspServer* self, i64 id); static void Amalgame_Compiler_LspServer_PublishDiagnostics(Amalgame_Compiler_LspServer* self, code_string uri, code_string source); static Amalgame_Compiler_FullResolver* Amalgame_Compiler_LspServer_BuildWorkspaceResolver(Amalgame_Compiler_LspServer* self, code_string path, Amalgame_Compiler_AstNode* prog); code_string Amalgame_Compiler_LspServer_DetectLocalPackageClass(code_string root); static void Amalgame_Compiler_LspServer_DeclareDependencyClasses(Amalgame_Compiler_FullResolver* resolver, code_string root); static code_string Amalgame_Compiler_LspServer_TomlFirstString(code_string line); static void Amalgame_Compiler_LspServer_DeclareManifestClasses(Amalgame_Compiler_FullResolver* resolver, code_string manifestPath); static void Amalgame_Compiler_LspServer_DeclareQuotedNames(Amalgame_Compiler_FullResolver* resolver, code_string line); static code_bool Amalgame_Compiler_LspServer_HasCachedSibling(Amalgame_Compiler_LspServer* self, code_string path); static void Amalgame_Compiler_LspServer_EnsureWorkspaceCache(Amalgame_Compiler_LspServer* self, code_string currentPath); code_string Amalgame_Compiler_LspServer_FindWorkspaceRoot(code_string startPath); code_string Amalgame_Compiler_LspServer_Dirname(code_string path); code_bool Amalgame_Compiler_LspServer_ProjectIsEmbedded(code_string startPath); static code_string Amalgame_Compiler_LspServer_Compile(Amalgame_Compiler_LspServer* self, code_string uri, code_string source); static void Amalgame_Compiler_LspServer_HandleHover(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static void Amalgame_Compiler_LspServer_HandleSignatureHelp(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static void Amalgame_Compiler_LspServer_SendNullResult(Amalgame_Compiler_LspServer* self, i64 id); static void Amalgame_Compiler_LspServer_HandleDefinition(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static code_string Amalgame_Compiler_LspServer_BareTypeName(code_string raw); static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindEnclosingMethod(Amalgame_Compiler_AstNode* prog, i64 targetLine); static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_LookupLocalInMethod(Amalgame_Compiler_AstNode* method, code_string name); static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindLocalVarDecl(Amalgame_Compiler_AstNode* node, code_string name); static void Amalgame_Compiler_LspServer_HandleDocumentSymbol(Amalgame_Compiler_LspServer* self, i64 id, code_string uri); static code_string Amalgame_Compiler_LspServer_SymbolForDecl(Amalgame_Compiler_AstNode* decl); static code_string Amalgame_Compiler_LspServer_SymbolEntry(code_string name, i64 kind, i64 line, i64 col, code_string childrenJson); static void Amalgame_Compiler_LspServer_HandleReferences(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static void Amalgame_Compiler_LspServer_CollectReferences(Amalgame_Compiler_AstNode* node, code_string target, code_string filePath, AmalgameList* out); static code_string Amalgame_Compiler_LspServer_LocationJson(code_string filePath, i64 line, i64 col, code_string name); static void Amalgame_Compiler_LspServer_HandleDocumentHighlight(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static void Amalgame_Compiler_LspServer_CollectHighlights(Amalgame_Compiler_AstNode* node, code_string target, AmalgameList* out); static code_string Amalgame_Compiler_LspServer_HighlightJson(i64 line, i64 col, code_string name); static void Amalgame_Compiler_LspServer_HandleRename(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character, code_string newName); static void Amalgame_Compiler_LspServer_CollectRenameEdits(Amalgame_Compiler_AstNode* node, code_string target, code_string newName, AmalgameList* out); static code_string Amalgame_Compiler_LspServer_TextEditJson(i64 line, i64 col, code_string oldName, code_string newName); static void Amalgame_Compiler_LspServer_HandlePrepareRename(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static void Amalgame_Compiler_LspServer_HandlePrepareCallHierarchy(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static void Amalgame_Compiler_LspServer_HandleIncomingCalls(Amalgame_Compiler_LspServer* self, i64 id, Amalgame_Compiler_JsonValue* item); static void Amalgame_Compiler_LspServer_HandleOutgoingCalls(Amalgame_Compiler_LspServer* self, i64 id, Amalgame_Compiler_JsonValue* item); static void Amalgame_Compiler_LspServer_CollectCallSitesForName(Amalgame_Compiler_AstNode* node, code_string target, AmalgameList* out); static void Amalgame_Compiler_LspServer_CollectOutgoingCalls(Amalgame_Compiler_AstNode* node, AmalgameList* names, AmalgameList* rangesOut); static code_string Amalgame_Compiler_LspServer_CallHierarchyItemJson(Amalgame_Compiler_AstNode* method, code_string filePath); static code_string Amalgame_Compiler_LspServer_RangeJsonForName(i64 line, i64 col, code_string name); static void Amalgame_Compiler_LspServer_HandleInlayHint(Amalgame_Compiler_LspServer* self, i64 id, code_string uri); static void Amalgame_Compiler_LspServer_CollectInlayHints(Amalgame_Compiler_AstNode* node, Amalgame_Compiler_TypeChecker* tc, AmalgameList* out); static code_string Amalgame_Compiler_LspServer_InlayHintJson(i64 line, i64 col, code_string name, code_string typeStr); static void Amalgame_Compiler_LspServer_HandleCodeAction(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 startLine, i64 startChr, i64 endLine, i64 endChr); static void Amalgame_Compiler_LspServer_CollectPackageInstallSuggestions(Amalgame_Compiler_LspServer* self, Amalgame_Compiler_FullResolver* resolver, code_string uri, code_string path, i64 sLine, i64 eLine, AmalgameList* out); static code_string Amalgame_Compiler_LspServer_AmcBinaryPath(); static code_string Amalgame_Compiler_LspServer_PackageInstallActionJson(code_string pkgName, code_string pkgTag, code_string pkgDesc, code_string symName); static code_string Amalgame_Compiler_LspServer_SegmentToNamespacePart(code_string seg); static code_string Amalgame_Compiler_LspServer_InferNamespaceFromUrl(code_string url); static i64 Amalgame_Compiler_LspServer_FindImportInsertionLine(code_string source); static code_bool Amalgame_Compiler_LspServer_HasImport(code_string source, code_string ns); static code_string Amalgame_Compiler_LspServer_PackageImportActionJson(code_string uri, i64 insertLine, code_string ns, code_string symName); static void Amalgame_Compiler_LspServer_CollectAnnotationFixes(Amalgame_Compiler_AstNode* node, Amalgame_Compiler_TypeChecker* tc, code_string uri, i64 sLine, i64 eLine, AmalgameList* out); static code_string Amalgame_Compiler_LspServer_AnnotationFixJson(code_string uri, i64 line, i64 col, code_string name, code_string typeStr); static void Amalgame_Compiler_LspServer_HandleFoldingRange(Amalgame_Compiler_LspServer* self, i64 id, code_string uri); static code_string Amalgame_Compiler_LspServer_FoldEntry(i64 startLine, i64 endLine, code_string kind); static void Amalgame_Compiler_LspServer_HandleWorkspaceSymbol(Amalgame_Compiler_LspServer* self, i64 id, code_string query); static code_string Amalgame_Compiler_LspServer_WorkspaceSymbolEntry(Amalgame_Compiler_AstNode* decl, code_string path, code_string lowerQuery); static void Amalgame_Compiler_LspServer_SendDefinitionLocation(Amalgame_Compiler_LspServer* self, i64 id, code_string path, i64 line, i64 col, code_string name); static code_string Amalgame_Compiler_LspServer_PercentEncodePath(code_string path); static code_bool Amalgame_Compiler_LspServer_IsUriSafeChar(code_string c); static i64 Amalgame_Compiler_LspServer_AsciiCodeOf(code_string c); static void Amalgame_Compiler_LspServer_HandleCompletion(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 chr); static code_bool Amalgame_Compiler_LspServer_IsImportLine(code_string source, i64 line); static void Amalgame_Compiler_LspServer_SendImportCompletion(Amalgame_Compiler_LspServer* self, i64 id); static code_bool Amalgame_Compiler_LspServer_ContainsString(AmalgameList* xs, code_string needle); static AmalgameList* Amalgame_Compiler_LspServer_BundledNamespaces(); static void Amalgame_Compiler_LspServer_SendGlobalCompletion(Amalgame_Compiler_LspServer* self, i64 id, Amalgame_Compiler_FullResolver* resolver); static void Amalgame_Compiler_LspServer_SendMemberCompletion(Amalgame_Compiler_LspServer* self, i64 id, Amalgame_Compiler_FullResolver* resolver, code_string typeName); code_string Amalgame_Compiler_LspServer_ReceiverTypeAt(code_string source, i64 line, i64 chr, Amalgame_Compiler_FullResolver* resolver); static code_string Amalgame_Compiler_LspServer_EnclosingClassAt(code_string source, i64 before); static code_bool Amalgame_Compiler_LspServer_MatchKeywordAt(code_string source, i64 pos, code_string kw); static code_string Amalgame_Compiler_LspServer_ScanLocalDeclType(code_string source, i64 before, code_string ident); static code_string Amalgame_Compiler_LspServer_ExtractTypeAfterDecl(code_string source, i64 start, i64 n); static code_bool Amalgame_Compiler_LspServer_IsIdentChar(code_string c); static void Amalgame_Compiler_LspServer_SendEmptyCompletion(Amalgame_Compiler_LspServer* self, i64 id); code_string Amalgame_Compiler_LspServer_DiagnosticFromResolver(code_string source, Amalgame_Compiler_ResolverError* e); code_string Amalgame_Compiler_LspServer_DiagnosticFromTc(code_string source, Amalgame_Compiler_TypeError* e); static code_string Amalgame_Compiler_LspServer_DiagnosticBody(code_string source, i64 line, i64 col, code_string msg); static i64 Amalgame_Compiler_LspServer_TokenEndCol(code_string source, i64 line, i64 col); static code_bool Amalgame_Compiler_LspServer_IsWordChar(code_string ch); code_string Amalgame_Compiler_LspServer_UriToPath(code_string uri); static code_string Amalgame_Compiler_LspServer_PercentDecode(code_string s); static i64 Amalgame_Compiler_LspServer_HexDigit(code_string c); Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindNodeAtPosition(Amalgame_Compiler_AstNode* root, i64 line, i64 col); code_string Amalgame_Compiler_LspServer_FormatMethodSignatureMarkdown(Amalgame_Compiler_AstNode* method); Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindMethodDeclByName(Amalgame_Compiler_AstNode* prog, code_string methodName); Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindCallAtPosition(Amalgame_Compiler_AstNode* root, i64 line, i64 col); static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindCallWalk(Amalgame_Compiler_AstNode* node, i64 line, i64 col, Amalgame_Compiler_AstNode* best); code_string Amalgame_Compiler_LspServer_CallCalleeName(Amalgame_Compiler_AstNode* call); static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindNodeWalk(Amalgame_Compiler_AstNode* node, i64 line, i64 col, Amalgame_Compiler_AstNode* best); static code_bool Amalgame_Compiler_LspServer_NodeCovers(Amalgame_Compiler_AstNode* node, i64 line, i64 col); Amalgame_Compiler_MiValue* Amalgame_Compiler_MiValue_new(); Amalgame_Compiler_MiRecord* Amalgame_Compiler_MiRecord_new(); Amalgame_Compiler_MiParser* Amalgame_Compiler_MiParser_new(code_string input); Amalgame_Compiler_MiValue* Amalgame_Compiler_MiValue_FieldOrNull(Amalgame_Compiler_MiValue* self, code_string key); code_string Amalgame_Compiler_MiValue_FieldString(Amalgame_Compiler_MiValue* self, code_string key); Amalgame_Compiler_MiValue* Amalgame_Compiler_MiRecord_ResultOrNull(Amalgame_Compiler_MiRecord* self, code_string key); static code_string Amalgame_Compiler_MiParser_Peek(Amalgame_Compiler_MiParser* self); static code_bool Amalgame_Compiler_MiParser_IsAlpha(code_string c); static code_bool Amalgame_Compiler_MiParser_IsDigit(code_string c); static code_bool Amalgame_Compiler_MiParser_IsOctalDigit(code_string c); static code_string Amalgame_Compiler_MiParser_ParseIdent(Amalgame_Compiler_MiParser* self); static code_string Amalgame_Compiler_MiParser_ParseCString(Amalgame_Compiler_MiParser* self); Amalgame_Compiler_MiValue* Amalgame_Compiler_MiParser_ParseValue(Amalgame_Compiler_MiParser* self); static Amalgame_Compiler_MiValue* Amalgame_Compiler_MiParser_ParseTuple(Amalgame_Compiler_MiParser* self); static Amalgame_Compiler_MiValue* Amalgame_Compiler_MiParser_ParseList(Amalgame_Compiler_MiParser* self); Amalgame_Compiler_MiRecord* Amalgame_Compiler_MiParser_ParseRecord(Amalgame_Compiler_MiParser* self); static void Amalgame_Compiler_MiParser_ParseResultList(Amalgame_Compiler_MiParser* self, Amalgame_Compiler_MiRecord* rec); Amalgame_Compiler_DapServer* Amalgame_Compiler_DapServer_new(); i64 Amalgame_Compiler_DapServer_Run(Amalgame_Compiler_DapServer* self); static code_bool Amalgame_Compiler_DapServer_HasFlag(Amalgame_Compiler_DapServer* self, code_string needle); static i64 Amalgame_Compiler_DapServer_RunSelfTestMi(); static void Amalgame_Compiler_DapServer_ParseFlags(Amalgame_Compiler_DapServer* self); i64 Amalgame_Compiler_DapServer_RunBridge(Amalgame_Compiler_DapServer* self); static i64 Amalgame_Compiler_DapServer_SpawnGdb(Amalgame_Compiler_DapServer* self, code_string gdbPath); static i64 Amalgame_Compiler_DapServer_PollLoop(Amalgame_Compiler_DapServer* self); static i64 Amalgame_Compiler_DapServer_PollOnce(Amalgame_Compiler_DapServer* self); static code_string Amalgame_Compiler_DapServer_ReadFromFd(Amalgame_Compiler_DapServer* self, i64 which); void Amalgame_Compiler_DapServer_WriteToFd(Amalgame_Compiler_DapServer* self, i64 which, code_string s); void Amalgame_Compiler_DapServer_CloseGdbStdin(Amalgame_Compiler_DapServer* self); static void Amalgame_Compiler_DapServer_OnDapInput(Amalgame_Compiler_DapServer* self, code_string chunk); static code_string Amalgame_Compiler_DapServer_Crlf(); static code_string Amalgame_Compiler_DapServer_CrlfCrlf(); static code_string Amalgame_Compiler_DapServer_TryExtractDapFrame(Amalgame_Compiler_DapServer* self); void Amalgame_Compiler_DapServer_SendDapFrame(Amalgame_Compiler_DapServer* self, code_string body); static void Amalgame_Compiler_DapServer_OnGdbOutput(Amalgame_Compiler_DapServer* self, code_string chunk); static void Amalgame_Compiler_DapServer_HandleMiLine(Amalgame_Compiler_DapServer* self, code_string line); static void Amalgame_Compiler_DapServer_HandleMiResult(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_HandleMiExecAsync(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_HandleMiNotifyAsync(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static code_bool Amalgame_Compiler_DapServer_IsHiddenFrameFunc(Amalgame_Compiler_DapServer* self, code_string funcS); static void Amalgame_Compiler_DapServer_EmitStoppedEvent(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static i64 Amalgame_Compiler_DapServer_IssueMiCommand(Amalgame_Compiler_DapServer* self, i64 dapSeq, code_string command, code_string mi); static i64 Amalgame_Compiler_DapServer_FindMiTokenIndex(Amalgame_Compiler_DapServer* self, i64 tok); static void Amalgame_Compiler_DapServer_ReleaseMiTokenAt(Amalgame_Compiler_DapServer* self, i64 idx); static void Amalgame_Compiler_DapServer_HandleDapMessage(Amalgame_Compiler_DapServer* self, code_string body); static void Amalgame_Compiler_DapServer_SendDapAck(Amalgame_Compiler_DapServer* self, i64 seq, code_string command); static void Amalgame_Compiler_DapServer_HandleTerminate(Amalgame_Compiler_DapServer* self, i64 seq); static void Amalgame_Compiler_DapServer_HandleThreads(Amalgame_Compiler_DapServer* self, i64 seq); static void Amalgame_Compiler_DapServer_HandleContinue(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleStep(Amalgame_Compiler_DapServer* self, i64 seq, code_string dapCmd, code_string miCmd); static void Amalgame_Compiler_DapServer_HandlePause(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleLaunch(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleSetBreakpoints(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_RespondSetBreakpoints(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_SendBkptResponse(Amalgame_Compiler_DapServer* self, i64 seq, AmalgameList* entries); static void Amalgame_Compiler_DapServer_HandleSetFunctionBreakpoints(Amalgame_Compiler_DapServer* self, i64 seq); static void Amalgame_Compiler_DapServer_HandleSetExceptionBreakpoints(Amalgame_Compiler_DapServer* self, i64 seq); static void Amalgame_Compiler_DapServer_HandleConfigurationDone(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleStackTrace(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleScopes(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleVariables(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleChildVariables(Amalgame_Compiler_DapServer* self, i64 seq, i64 vref); static void Amalgame_Compiler_DapServer_StartMapDiscovery(Amalgame_Compiler_DapServer* self, i64 seq, code_string kind, code_string baseExpr); static void Amalgame_Compiler_DapServer_HandleMapDiscCapResponse(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_FireNextSlotProbe(Amalgame_Compiler_DapServer* self); static void Amalgame_Compiler_DapServer_HandleMapDiscSlotResponse(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_EmitMapChildren(Amalgame_Compiler_DapServer* self); static void Amalgame_Compiler_DapServer_FinishMapDiscoveryEmpty(Amalgame_Compiler_DapServer* self); static void Amalgame_Compiler_DapServer_FailMapDiscovery(Amalgame_Compiler_DapServer* self, code_string msg); static void Amalgame_Compiler_DapServer_ResetMapDiscovery(Amalgame_Compiler_DapServer* self); static i64 Amalgame_Compiler_DapServer_FindChildRefIndex(Amalgame_Compiler_DapServer* self, i64 vref); static i64 Amalgame_Compiler_DapServer_AllocChildRef(Amalgame_Compiler_DapServer* self, code_string typeS, code_string addr, i64 size); static void Amalgame_Compiler_DapServer_HandleEvaluate(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_RespondLaunch(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_RespondConfigurationDone(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_RespondStackTrace(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_RespondVariables(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_ProcessNextVarFollowup(Amalgame_Compiler_DapServer* self); static code_string Amalgame_Compiler_DapServer_PrettyPrintQuery(code_string name, code_string typeS); static code_string Amalgame_Compiler_DapServer_PrettyPrintFormat(code_string typeS, code_string evalResult); static void Amalgame_Compiler_DapServer_HandleVarFollowupResponse(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static code_string Amalgame_Compiler_DapServer_ContainerKind(code_string typeS); static void Amalgame_Compiler_DapServer_RewriteRefAt(Amalgame_Compiler_DapServer* self, i64 idx, i64 newRef); static void Amalgame_Compiler_DapServer_RewriteValueAt(Amalgame_Compiler_DapServer* self, i64 idx, code_string newValue); static void Amalgame_Compiler_DapServer_SendVariablesResponse(Amalgame_Compiler_DapServer* self); static void Amalgame_Compiler_DapServer_RespondEvaluate(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_HandleInitialize(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleDisconnect(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_SendDapErrorResponse(Amalgame_Compiler_DapServer* self, i64 seq, code_string command, code_string reason); static i64 Amalgame_Compiler_DapServer_NextOutSeq(Amalgame_Compiler_DapServer* self); static void Amalgame_Compiler_DapServer_Cleanup(Amalgame_Compiler_DapServer* self); i64 Amalgame_Compiler_DapServer_RunRaw(Amalgame_Compiler_DapServer* self); static code_string Amalgame_Compiler_DapServer_DetectBackend(Amalgame_Compiler_DapServer* self); static code_string Amalgame_Compiler_DapServer_Probe(code_string candidate); static i64 Amalgame_Compiler_DapServer_ExecBackend(Amalgame_Compiler_DapServer* self, code_string exe); Amalgame_Compiler_CurlResponse* Amalgame_Compiler_CurlResponse_new(); Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateResult_new(); Amalgame_Compiler_MigrateCommand* Amalgame_Compiler_MigrateCommand_new(); void Amalgame_Compiler_MigrateCommand_PrintUsage(); i64 Amalgame_Compiler_MigrateCommand_Run(i64 argc); static i64 Amalgame_Compiler_MigrateCommand_RunMigrateOne(code_string input, code_string output, code_string langHint, code_string provider, code_string model, code_bool force, code_bool dryRun, code_bool promptOnly, code_bool noCheck, i64 maxLines, code_bool noCache); static i64 Amalgame_Compiler_MigrateCommand_RunMigrateDirectory(code_string dir, code_string langHint, code_string provider, code_string model, code_bool force, code_bool dryRun, code_bool promptOnly, code_bool noCheck, i64 maxLines, code_bool noCache); static code_bool Amalgame_Compiler_MigrateCommand_IsDirectory(code_string path); static code_string Amalgame_Compiler_MigrateCommand_DetectLanguage(code_string path); static code_string Amalgame_Compiler_MigrateCommand_DefaultOutputPath(code_string input); static i64 Amalgame_Compiler_MigrateCommand_CountLines(code_string s); static code_string Amalgame_Compiler_MigrateCommand_BuildPrompt(code_string lang, code_string source); static code_string Amalgame_Compiler_MigrateCommand_BuildSystemPrompt(code_string lang); static code_string Amalgame_Compiler_MigrateCommand_BuildUserPrompt(code_string lang, code_string source); code_string Amalgame_Compiler_MigrateCommand_LoadDocsHeader(); static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallProvider(code_string provider, code_string model, code_string lang, code_string source); Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallProviderRaw(code_string provider, code_string model, code_string systemPrompt, code_string userPrompt); code_string Amalgame_Compiler_MigrateCommand_AutoSelectProvider(); code_string Amalgame_Compiler_MigrateCommand_EstimateCost(code_string provider, code_string model, code_string systemPrompt, code_string userPrompt); code_string Amalgame_Compiler_MigrateCommand_FormatActualCost(code_string provider, code_string model, i64 inputToks, i64 outputToks); static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallClaudeApiRaw(code_string model, code_string systemPrompt, code_string userPrompt); static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallChatGptApi(code_string model, code_string systemPrompt, code_string userPrompt); static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallGeminiApi(code_string model, code_string systemPrompt, code_string userPrompt); static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallCustomScript(code_string systemPrompt, code_string userPrompt); static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallClaudeCli(code_string model, code_string prompt); static code_bool Amalgame_Compiler_MigrateCommand_IsCommandAvailable(code_string cmd); code_string Amalgame_Compiler_MigrateCommand_CacheHash(code_string source, code_string systemPrompt); code_string Amalgame_Compiler_MigrateCommand_CachePath(code_string hash); code_string Amalgame_Compiler_MigrateCommand_CacheLookup(code_string source, code_string systemPrompt); void Amalgame_Compiler_MigrateCommand_CacheStore(code_string source, code_string systemPrompt, code_string content); i64 Amalgame_Compiler_MigrateCommand_StreamClaudeCli(code_string model, code_string prompt); static Amalgame_Compiler_CurlResponse* Amalgame_Compiler_MigrateCommand_CurlPost(code_string url, code_string body, AmalgameMap* headers); static code_string Amalgame_Compiler_MigrateCommand_ShellEscape(code_string s); static code_string Amalgame_Compiler_MigrateCommand_StripFences(code_string s); Amalgame_Compiler_GenerateCommand* Amalgame_Compiler_GenerateCommand_new(); void Amalgame_Compiler_GenerateCommand_PrintUsage(); i64 Amalgame_Compiler_GenerateCommand_Run(i64 argc); static code_string Amalgame_Compiler_GenerateCommand_BuildSystemPrompt(); static code_string Amalgame_Compiler_GenerateCommand_BuildUserPrompt(code_string task); static code_string Amalgame_Compiler_GenerateCommand_StripFences(code_string s); Amalgame_Compiler_ExplainCommand* Amalgame_Compiler_ExplainCommand_new(); void Amalgame_Compiler_ExplainCommand_PrintUsage(); i64 Amalgame_Compiler_ExplainCommand_Run(i64 argc); static code_string Amalgame_Compiler_ExplainCommand_BuildSystemPrompt(code_string outLang); static code_string Amalgame_Compiler_ExplainCommand_BuildUserPrompt(code_string path, code_string source); Amalgame_Compiler_NewCommand* Amalgame_Compiler_NewCommand_new(); void Amalgame_Compiler_NewCommand_PrintUsage(); i64 Amalgame_Compiler_NewCommand_Run(i64 argc); static i64 Amalgame_Compiler_NewCommand_ScaffoldExe(code_string path, code_string base); static i64 Amalgame_Compiler_NewCommand_ScaffoldLib(code_string path, code_string base); static i64 Amalgame_Compiler_NewCommand_ScaffoldService(code_string path, code_string base); static i64 Amalgame_Compiler_NewCommand_ScaffoldForms(code_string path, code_string base); static i64 Amalgame_Compiler_NewCommand_ScaffoldTest(code_string path, code_string base); static i64 Amalgame_Compiler_NewCommand_ScaffoldMcu(code_string path, code_string base, code_string board); static code_string Amalgame_Compiler_NewCommand_McuAppAm(code_string base, code_bool isQemu); static code_string Amalgame_Compiler_NewCommand_McuToml(code_string base, code_string board, code_string target, code_bool isQemu); static code_string Amalgame_Compiler_NewCommand_McuTasksJson(code_string target, code_bool isQemu); static code_string Amalgame_Compiler_NewCommand_McuLaunchJson(code_bool isQemu); static code_string Amalgame_Compiler_NewCommand_McuGitignore(); static code_string Amalgame_Compiler_NewCommand_McuStartupF767(); static code_string Amalgame_Compiler_NewCommand_McuLinkerF767(); static code_string Amalgame_Compiler_NewCommand_McuHeaderF767(); static code_string Amalgame_Compiler_NewCommand_McuReadme(code_string base, code_string board, code_string target, code_bool isQemu); static i64 Amalgame_Compiler_NewCommand_WriteVscodeConfig(code_string path, code_string base, code_string template); static code_string Amalgame_Compiler_NewCommand_VscodeLaunchJson(code_string base); static code_string Amalgame_Compiler_NewCommand_VscodeSettingsJson(); static code_string Amalgame_Compiler_NewCommand_VscodeTasksJson(); static code_string Amalgame_Compiler_NewCommand_MainAmExe(code_string name); static code_string Amalgame_Compiler_NewCommand_TestAmExe(code_string name); static code_string Amalgame_Compiler_NewCommand_BuildShExe(code_string name); static code_string Amalgame_Compiler_NewCommand_ReadmeExe(code_string name); static code_string Amalgame_Compiler_NewCommand_LibAm(code_string name); static code_string Amalgame_Compiler_NewCommand_BuildShLib(code_string name); static code_string Amalgame_Compiler_NewCommand_ReadmeLib(code_string name); static code_string Amalgame_Compiler_NewCommand_TestAmTest(code_string name); static code_string Amalgame_Compiler_NewCommand_ReadmeTest(code_string name); static code_string Amalgame_Compiler_NewCommand_MainAmService(code_string name); static code_string Amalgame_Compiler_NewCommand_ManifestService(code_string name); static code_string Amalgame_Compiler_NewCommand_SystemdUnit(code_string name); static code_string Amalgame_Compiler_NewCommand_InstallShService(code_string name); static code_string Amalgame_Compiler_NewCommand_PlistMacosService(code_string name); static code_string Amalgame_Compiler_NewCommand_InstallMacosShService(code_string name); static code_string Amalgame_Compiler_NewCommand_BuildShService(code_string name); static code_string Amalgame_Compiler_NewCommand_BuildPs1Service(code_string name); static code_string Amalgame_Compiler_NewCommand_InstallPs1Service(code_string name); static code_string Amalgame_Compiler_NewCommand_ReadmeService(code_string name); static code_string Amalgame_Compiler_NewCommand_GitignoreCommon(); static code_string Amalgame_Compiler_NewCommand_GitignoreService(code_string name); static code_bool Amalgame_Compiler_NewCommand_WriteFile(code_string path, code_string content); static code_string Amalgame_Compiler_NewCommand_ShellEscape(code_string s); static code_bool Amalgame_Compiler_NewCommand_IsSafeName(code_string s); static code_string Amalgame_Compiler_NewCommand_Capitalize(code_string s); static code_string Amalgame_Compiler_NewCommand_SanitizeIdent(code_string s); static code_string Amalgame_Compiler_NewCommand_Basename(code_string p); static code_string Amalgame_Compiler_NewCommand_MainAmForms(code_string name); static code_string Amalgame_Compiler_NewCommand_ManifestForms(code_string name); static code_string Amalgame_Compiler_NewCommand_BuildShForms(code_string name); static code_string Amalgame_Compiler_NewCommand_ReadmeForms(code_string name); static i64 Amalgame_Compiler_NewCommand_ScaffoldUiWebForm(code_string path, code_string base); static code_string Amalgame_Compiler_NewCommand_MainAmUiWebForm(code_string name); static code_string Amalgame_Compiler_NewCommand_ManifestUiWebForm(code_string name); static code_string Amalgame_Compiler_NewCommand_BuildShUiWebForm(code_string name); static code_string Amalgame_Compiler_NewCommand_ReadmeUiWebForm(code_string name); Amalgame_Compiler_McuCommand* Amalgame_Compiler_McuCommand_new(); i64 Amalgame_Compiler_McuCommand_Run(i64 argc); code_bool Amalgame_Compiler_McuCommand_IsWin(); code_bool Amalgame_Compiler_McuCommand_IsInteractive(); code_string Amalgame_Compiler_McuCommand_DetectOs(); code_bool Amalgame_Compiler_McuCommand_Has(code_string tool); static void Amalgame_Compiler_McuCommand_Report(code_string tool, code_string role); i64 Amalgame_Compiler_McuCommand_Doctor(); code_string Amalgame_Compiler_McuCommand_Libopencm3Dir(); i64 Amalgame_Compiler_McuCommand_Setup(code_bool assumeYes); Amalgame_Compiler_DocCommand* Amalgame_Compiler_DocCommand_new(); i64 Amalgame_Compiler_DocCommand_Run(i64 argc); static void Amalgame_Compiler_DocCommand_PrintUsage(); static code_string Amalgame_Compiler_DocCommand_EmitMarkdown(code_string path, Amalgame_Compiler_AstNode* prog, AmalgameList* comments); static code_string Amalgame_Compiler_DocCommand_EmitClass(Amalgame_Compiler_AstNode* cls, AmalgameList* comments); static code_string Amalgame_Compiler_DocCommand_EmitField(code_string clsName, Amalgame_Compiler_AstNode* field, AmalgameList* comments); static code_string Amalgame_Compiler_DocCommand_EmitMethod(code_string clsName, Amalgame_Compiler_AstNode* method, AmalgameList* comments); static code_string Amalgame_Compiler_DocCommand_EmitEnum(Amalgame_Compiler_AstNode* en, AmalgameList* comments); static code_string Amalgame_Compiler_DocCommand_CollectCommentsBefore(AmalgameList* comments, i64 declLine, i64 indent); static code_string Amalgame_Compiler_DocCommand_RenderRange(AmalgameList* comments, i64 lastIdx, i64 declLine, i64 indent); static code_string Amalgame_Compiler_DocCommand_StripCommentMarker(code_string raw); static code_string Amalgame_Compiler_DocCommand_Basename(code_string path); Amalgame_Compiler_ArgParser* Amalgame_Compiler_ArgParser_new(); Amalgame_Compiler_ArgParser* Amalgame_Compiler_ArgParser_Flag(Amalgame_Compiler_ArgParser* self, code_string name); Amalgame_Compiler_ArgParser* Amalgame_Compiler_ArgParser_Option(Amalgame_Compiler_ArgParser* self, code_string name); Amalgame_Compiler_ArgParser* Amalgame_Compiler_ArgParser_Parse(Amalgame_Compiler_ArgParser* self, i64 argc, i64 startIdx); code_bool Amalgame_Compiler_ArgParser_HasFlag(Amalgame_Compiler_ArgParser* self, code_string name); code_string Amalgame_Compiler_ArgParser_GetOption(Amalgame_Compiler_ArgParser* self, code_string name); AmalgameList* Amalgame_Compiler_ArgParser_GetPositionals(Amalgame_Compiler_ArgParser* self); code_string Amalgame_Compiler_ArgParser_GetUnknown(Amalgame_Compiler_ArgParser* self); code_bool Amalgame_Compiler_ArgParser_HelpRequested(Amalgame_Compiler_ArgParser* self); static code_bool Amalgame_Compiler_ArgParser_IsRegisteredFlag(Amalgame_Compiler_ArgParser* self, code_string name); static code_bool Amalgame_Compiler_ArgParser_IsRegisteredOption(Amalgame_Compiler_ArgParser* self, code_string name); Amalgame_Compiler_AddCommand* Amalgame_Compiler_AddCommand_new(); static code_bool Amalgame_Compiler_AddCommand_MkdirP(code_string path); static code_bool Amalgame_Compiler_AddCommand_RmRf(code_string path); static code_bool Amalgame_Compiler_AddCommand_RenamePath(code_string from, code_string to); static code_string Amalgame_Compiler_AddCommand_ListDir(code_string path); void Amalgame_Compiler_AddCommand_PrintUsage(); i64 Amalgame_Compiler_AddCommand_Run(i64 argc, i64 startIdx); i64 Amalgame_Compiler_AddCommand_RunOne(code_string spec, code_bool noPrecompile); void Amalgame_Compiler_AddCommand_PrecompilePackage(code_string pkgDir, Amalgame_Compiler_TomlValue* stdlibTbl, code_string pkgVer); void Amalgame_Compiler_AddCommand_PrecompileFacade(code_string pkgDir, Amalgame_Compiler_TomlValue* stdlibTbl, Amalgame_Compiler_TomlValue* depsTbl); code_string Amalgame_Compiler_AddCommand_ResolveSelfPath(); i64 Amalgame_Compiler_AddCommand_NowSeconds(); code_string Amalgame_Compiler_AddCommand_HumanDuration(i64 seconds); AmalgameList* Amalgame_Compiler_AddCommand_ParseSpec(code_string spec); code_bool Amalgame_Compiler_AddCommand_IsSafeUrl(code_string url); code_bool Amalgame_Compiler_AddCommand_IsSafeTag(code_string tag); code_string Amalgame_Compiler_AddCommand_SlugFromUrl(code_string url); code_string Amalgame_Compiler_AddCommand_DepNameFromSlug(code_string slug); code_string Amalgame_Compiler_AddCommand_StripV(code_string tag); code_string Amalgame_Compiler_AddCommand_CacheRoot(); code_string Amalgame_Compiler_AddCommand_IndexCachePath(); static code_bool Amalgame_Compiler_AddCommand_IsShortname(code_string lhs); code_string Amalgame_Compiler_AddCommand_FetchIndex(); code_bool Amalgame_Compiler_AddCommand_IndexCacheIsFresh(code_string cachePath); i64 Amalgame_Compiler_AddCommand_RunPackage(i64 argc); void Amalgame_Compiler_AddCommand_PrintPackageUsage(); i64 Amalgame_Compiler_AddCommand_RunVersions(i64 argc, i64 startIdx); i64 Amalgame_Compiler_AddCommand_EnsureInstalled(); i64 Amalgame_Compiler_AddCommand_RunCache(i64 argc, i64 startIdx); i64 Amalgame_Compiler_AddCommand_RunUpdate(i64 argc, i64 startIdx); i64 Amalgame_Compiler_AddCommand_RunInstallSpec(code_string spec); i64 Amalgame_Compiler_AddCommand_RunList(i64 argc, i64 startIdx); i64 Amalgame_Compiler_AddCommand_RunRemove(i64 argc, i64 startIdx); void Amalgame_Compiler_AddCommand_RebuildLockFromTomlDeps(Amalgame_Compiler_TomlValue* depsTable, code_string lockPath); i64 Amalgame_Compiler_AddCommand_RunSearch(i64 argc, i64 startIdx); void Amalgame_Compiler_AddCommand_PrintVersionsForPackage(Amalgame_Compiler_TomlValue* verArr, code_string pkgName, code_string amcVer); void Amalgame_Compiler_AddCommand_PrintVersionsJsonForPackage(Amalgame_Compiler_TomlValue* verArr, code_string pkgName, code_string urlS, code_string amcVer); i64 Amalgame_Compiler_AddCommand_RunSuggest(i64 argc, i64 startIdx); Amalgame_Compiler_TomlValue* Amalgame_Compiler_AddCommand_FindPackageByName(Amalgame_Compiler_TomlValue* pkgArr, code_string target); code_string Amalgame_Compiler_AddCommand_LatestCompatibleTag(Amalgame_Compiler_TomlValue* verArr, code_string pkgName, code_string amcVer); code_string Amalgame_Compiler_AddCommand_JsonEscape(code_string s); i64 Amalgame_Compiler_AddCommand_RunInfo(i64 argc, i64 startIdx); i64 Amalgame_Compiler_AddCommand_RunOutdated(i64 argc, i64 startIdx); i64 Amalgame_Compiler_AddCommand_RunCheck(i64 argc, i64 startIdx); i64 Amalgame_Compiler_AddCommand_RunNotice(i64 argc, i64 startIdx); code_string Amalgame_Compiler_AddCommand_LastUrlSegment(code_string url); code_string Amalgame_Compiler_AddCommand_ResolveLatestCompatible(code_string shortname); code_string Amalgame_Compiler_AddCommand_ResolveShortname(code_string spec); AmalgameList* Amalgame_Compiler_AddCommand_AllCachedRuntimeDirs(); code_string Amalgame_Compiler_AddCommand_LatestCacheRuntimeDir(code_string depKey); code_string Amalgame_Compiler_AddCommand_ShortnameFromDepKey(code_string depKey); code_string Amalgame_Compiler_AddCommand_FindExistingForTag(code_string baseDir, code_string tag); code_string Amalgame_Compiler_AddCommand_ExtractRevFromDirName(code_string dir); code_bool Amalgame_Compiler_AddCommand_UpdateProjectManifest(code_string depName, code_string url, code_string tag); code_bool Amalgame_Compiler_AddCommand_UpdateLockFile(code_string depName, code_string url, code_string tag, code_string rev); Amalgame_Compiler_MonoTimer* Amalgame_Compiler_MonoTimer_new(); Amalgame_Compiler_AmalgameCompiler* Amalgame_Compiler_AmalgameCompiler_new(); Amalgame_Compiler_Telemetry* Amalgame_Compiler_Telemetry_new(); Amalgame_Compiler_Program* Amalgame_Compiler_Program_new(); code_string Amalgame_Compiler_MonoTimer_Reset(Amalgame_Compiler_MonoTimer* self); static i64 Amalgame_Compiler_MonoTimer_NowNs(); static code_string Amalgame_Compiler_MonoTimer_Format(i64 nanos); static code_string Amalgame_Compiler_MonoTimer_Pad3(i64 n); void Amalgame_Compiler_AmalgameCompiler_SetLib(Amalgame_Compiler_AmalgameCompiler* self, code_bool v); void Amalgame_Compiler_AmalgameCompiler_SetCheckOnly(Amalgame_Compiler_AmalgameCompiler* self, code_bool v); void Amalgame_Compiler_AmalgameCompiler_SetLintMode(Amalgame_Compiler_AmalgameCompiler* self, code_bool v); void Amalgame_Compiler_AmalgameCompiler_SetVerbose(Amalgame_Compiler_AmalgameCompiler* self, code_bool v); void Amalgame_Compiler_AmalgameCompiler_SetColor(Amalgame_Compiler_AmalgameCompiler* self, code_bool v); void Amalgame_Compiler_AmalgameCompiler_SetExternalFiles(Amalgame_Compiler_AmalgameCompiler* self, AmalgameList* files); void Amalgame_Compiler_AmalgameCompiler_SetTarget(Amalgame_Compiler_AmalgameCompiler* self, code_string t); code_bool Amalgame_Compiler_AmalgameCompiler_IsEmbedded(Amalgame_Compiler_AmalgameCompiler* self); i64 Amalgame_Compiler_AmalgameCompiler_GetExitCode(Amalgame_Compiler_AmalgameCompiler* self); void Amalgame_Compiler_AmalgameCompiler_Run(Amalgame_Compiler_AmalgameCompiler* self, AmalgameList* inputFiles, code_string outputName); void Amalgame_Compiler_AmalgameCompiler_ScanImportsInto(AmalgameList* files, AmalgameList* out); code_bool Amalgame_Compiler_AmalgameCompiler_NamespaceCoveredBy(AmalgameList* nsList, code_string target); static code_bool Amalgame_Compiler_Telemetry_optedOut(); static code_bool Amalgame_Compiler_Telemetry_commandExists(code_string tool); static code_string Amalgame_Compiler_Telemetry_throttlePath(); static code_bool Amalgame_Compiler_Telemetry_throttled(i64 now); void Amalgame_Compiler_Telemetry_Ping(); code_bool Amalgame_Compiler_Program_IsWindows(); code_bool Amalgame_Compiler_Program_IsKnownTarget(code_string name); code_string Amalgame_Compiler_Program_KnownTargets(); code_bool Amalgame_Compiler_Program_TargetIsXtensa(code_string name); code_string Amalgame_Compiler_Program_TargetCC(code_string name); code_string Amalgame_Compiler_Program_TargetObjcopy(code_string name); code_string Amalgame_Compiler_Program_TargetSize(code_string name); code_string Amalgame_Compiler_Program_TargetCpuFlags(code_string name); code_string Amalgame_Compiler_Program_ResolveSelfPath(); code_string Amalgame_Compiler_Program_ResolveRuntimeDir(code_string amcPath); code_string Amalgame_Compiler_Program_ResolveLibAmalgameA(code_string amcPath); code_string Amalgame_Compiler_Program_ResolveStdlibSrcDir(code_string amcPath); void Amalgame_Compiler_Program_PrintUsage(); i64 Amalgame_Compiler_Program_RunTest(i64 argc); AmalgameList* Amalgame_Compiler_Program_PreCompilePackageSources(Amalgame_Compiler_PackageRegistry* reg, code_string amcRuntime); void Amalgame_Compiler_Program_PrintPackageSuggestionsForOutput(code_string output, code_string amcPath); static code_string Amalgame_Compiler_Program_TomlRawValue(AmalgameList* lines, code_string key); static code_string Amalgame_Compiler_Program_TomlScalar(AmalgameList* lines, code_string key); static AmalgameList* Amalgame_Compiler_Program_TomlArray(AmalgameList* lines, code_string key); static code_string Amalgame_Compiler_Program_EnvDirFlags(code_string envName, code_string flag); i64 Amalgame_Compiler_Program_LinkEmbedded(code_string target, code_string outC, code_string outBin, code_string amcRuntime, code_string boardPath, code_bool verbose, code_bool debug); code_bool Amalgame_Compiler_Program_RequireTool(code_string tool, code_string hint); i64 Amalgame_Compiler_Program_FlashEmbedded(code_string boardPath, code_string outBin); i64 Amalgame_Compiler_Program_RunMonitor(i64 argc); i64 Amalgame_Compiler_Program_BuildOneBinary(code_string amcPath, code_string entryAm, code_string outBin, code_string amcRuntime, code_string libamalgameA, AmalgameList* pkgObjs, AmalgameList* facadeArs, AmalgameList* pkgLibs, code_bool hasCxx, code_bool verbose, code_bool debug, code_string target, code_string board); i64 Amalgame_Compiler_Program_BuildEntry(code_string entryAm, code_string outBin, code_bool verbose, code_bool debug, code_string target, code_string board); i64 Amalgame_Compiler_Program_RunBuild(i64 argc); i64 Amalgame_Compiler_Program_RunRun(i64 argc); i64 Amalgame_Compiler_Program_RunWatch(i64 argc); static i64 Amalgame_Compiler_Program_BuildAndMaybeRun(code_string entryAm, code_string outBin, code_bool verbose, code_bool runAfter); static i64 Amalgame_Compiler_Program_FileMtimeNs(code_string path); static void Amalgame_Compiler_Program_SleepMs(i64 ms); i64 Amalgame_Compiler_Program_RunFmt(i64 argc); void Amalgame_Compiler_Program_Main(code_string* args); enum _Amalgame_Compiler_TokenType { Amalgame_Compiler_TokenType_INTEGER, Amalgame_Compiler_TokenType_FLOAT, Amalgame_Compiler_TokenType_STRING, Amalgame_Compiler_TokenType_BOOL, Amalgame_Compiler_TokenType_NULL, Amalgame_Compiler_TokenType_IDENTIFIER, Amalgame_Compiler_TokenType_KW_LET, Amalgame_Compiler_TokenType_KW_VAR, Amalgame_Compiler_TokenType_KW_IF, Amalgame_Compiler_TokenType_KW_ELSE, Amalgame_Compiler_TokenType_KW_FOR, Amalgame_Compiler_TokenType_KW_WHILE, Amalgame_Compiler_TokenType_KW_RETURN, Amalgame_Compiler_TokenType_KW_CLASS, Amalgame_Compiler_TokenType_KW_PUBLIC, Amalgame_Compiler_TokenType_KW_PRIVATE, Amalgame_Compiler_TokenType_KW_STATIC, Amalgame_Compiler_TokenType_KW_NEW, Amalgame_Compiler_TokenType_KW_THIS, Amalgame_Compiler_TokenType_KW_NULL, Amalgame_Compiler_TokenType_KW_TRUE, Amalgame_Compiler_TokenType_KW_FALSE, Amalgame_Compiler_TokenType_KW_IMPORT, Amalgame_Compiler_TokenType_KW_NAMESPACE, Amalgame_Compiler_TokenType_KW_ENUM, Amalgame_Compiler_TokenType_KW_MATCH, Amalgame_Compiler_TokenType_KW_IN, Amalgame_Compiler_TokenType_KW_IS, Amalgame_Compiler_TokenType_KW_AS, Amalgame_Compiler_TokenType_KW_VOID, Amalgame_Compiler_TokenType_KW_INT, Amalgame_Compiler_TokenType_KW_STRING_TYPE, Amalgame_Compiler_TokenType_KW_BOOL_TYPE, Amalgame_Compiler_TokenType_KW_FLOAT_TYPE, Amalgame_Compiler_TokenType_KW_TRY, Amalgame_Compiler_TokenType_KW_CATCH, Amalgame_Compiler_TokenType_KW_THROW, Amalgame_Compiler_TokenType_KW_FINALLY, Amalgame_Compiler_TokenType_KW_INTERFACE, Amalgame_Compiler_TokenType_KW_RECORD, Amalgame_Compiler_TokenType_KW_FUNC, Amalgame_Compiler_TokenType_KW_GUARD, Amalgame_Compiler_TokenType_OP_PLUS, Amalgame_Compiler_TokenType_OP_MINUS, Amalgame_Compiler_TokenType_OP_STAR, Amalgame_Compiler_TokenType_OP_SLASH, Amalgame_Compiler_TokenType_OP_PERCENT, Amalgame_Compiler_TokenType_OP_EQ, Amalgame_Compiler_TokenType_OP_EQEQ, Amalgame_Compiler_TokenType_OP_NEQ, Amalgame_Compiler_TokenType_OP_LT, Amalgame_Compiler_TokenType_OP_GT, Amalgame_Compiler_TokenType_OP_LTE, Amalgame_Compiler_TokenType_OP_GTE, Amalgame_Compiler_TokenType_OP_AND, Amalgame_Compiler_TokenType_OP_OR, Amalgame_Compiler_TokenType_OP_NOT, Amalgame_Compiler_TokenType_OP_ARROW, Amalgame_Compiler_TokenType_OP_THIN_ARROW, Amalgame_Compiler_TokenType_OP_DOT, Amalgame_Compiler_TokenType_OP_QDOT, Amalgame_Compiler_TokenType_OP_QMARK, Amalgame_Compiler_TokenType_OP_DOTDOT, Amalgame_Compiler_TokenType_OP_SPREAD, Amalgame_Compiler_TokenType_OP_COALESCE, Amalgame_Compiler_TokenType_OP_AMP, Amalgame_Compiler_TokenType_OP_PIPE, Amalgame_Compiler_TokenType_OP_CARET, Amalgame_Compiler_TokenType_OP_TILDE, Amalgame_Compiler_TokenType_OP_SHL, Amalgame_Compiler_TokenType_OP_SHR, Amalgame_Compiler_TokenType_OP_PLUS_EQ, Amalgame_Compiler_TokenType_OP_MINUS_EQ, Amalgame_Compiler_TokenType_OP_STAR_EQ, Amalgame_Compiler_TokenType_OP_SLASH_EQ, Amalgame_Compiler_TokenType_OP_PERCENT_EQ, Amalgame_Compiler_TokenType_OP_AMP_EQ, Amalgame_Compiler_TokenType_OP_PIPE_EQ, Amalgame_Compiler_TokenType_OP_CARET_EQ, Amalgame_Compiler_TokenType_OP_SHL_EQ, Amalgame_Compiler_TokenType_OP_SHR_EQ, Amalgame_Compiler_TokenType_LPAREN, Amalgame_Compiler_TokenType_RPAREN, Amalgame_Compiler_TokenType_LBRACE, Amalgame_Compiler_TokenType_RBRACE, Amalgame_Compiler_TokenType_LBRACKET, Amalgame_Compiler_TokenType_RBRACKET, Amalgame_Compiler_TokenType_COMMA, Amalgame_Compiler_TokenType_COLON, Amalgame_Compiler_TokenType_SEMICOLON, Amalgame_Compiler_TokenType_AT, Amalgame_Compiler_TokenType_INLINE_C, Amalgame_Compiler_TokenType_NEWLINE, Amalgame_Compiler_TokenType_COMMENT, Amalgame_Compiler_TokenType_EOF, Amalgame_Compiler_TokenType_UNKNOWN }; struct _Amalgame_Compiler_Token { Amalgame_Compiler_TokenType Type; code_string Value; i64 Line; i64 Column; code_string Filename; }; code_string Amalgame_Compiler_Token_ToString(Amalgame_Compiler_Token* self); code_bool Amalgame_Compiler_Token_IsKeyword(Amalgame_Compiler_Token* self); Amalgame_Compiler_Token* Amalgame_Compiler_Token_new(Amalgame_Compiler_TokenType t, code_string value, i64 line, i64 col, code_string file) { Amalgame_Compiler_Token* self = (Amalgame_Compiler_Token*) GC_MALLOC(sizeof(Amalgame_Compiler_Token)); #line 129 "./src/lexer/token.am" self->Type = t; #line 130 "./src/lexer/token.am" self->Value = value; #line 131 "./src/lexer/token.am" self->Line = line; #line 132 "./src/lexer/token.am" self->Column = col; #line 133 "./src/lexer/token.am" self->Filename = file; return self; } code_string Amalgame_Compiler_Token_ToString(Amalgame_Compiler_Token* self) { #line 137 "./src/lexer/token.am" return code_string_concat(code_string_concat(code_string_concat(code_string_concat(code_string_concat(code_string_concat(code_string_concat(code_string_concat(code_string_concat("", "Token("), String_FromInt((i64)self->Type)), ", '"), (self->Value ? self->Value : "")), "', "), String_FromInt(self->Line)), ":"), String_FromInt(self->Column)), ")"); } code_bool Amalgame_Compiler_Token_IsKeyword(Amalgame_Compiler_Token* self) { #line 141 "./src/lexer/token.am" Amalgame_Compiler_TokenType v = self->Type; #line 142 "./src/lexer/token.am" return (((((((((((((v == Amalgame_Compiler_TokenType_KW_LET) || (v == Amalgame_Compiler_TokenType_KW_VAR)) || (v == Amalgame_Compiler_TokenType_KW_IF)) || (v == Amalgame_Compiler_TokenType_KW_ELSE)) || (v == Amalgame_Compiler_TokenType_KW_FOR)) || (v == Amalgame_Compiler_TokenType_KW_WHILE)) || (v == Amalgame_Compiler_TokenType_KW_RETURN)) || (v == Amalgame_Compiler_TokenType_KW_CLASS)) || (v == Amalgame_Compiler_TokenType_KW_PUBLIC)) || (v == Amalgame_Compiler_TokenType_KW_STATIC)) || (v == Amalgame_Compiler_TokenType_KW_NEW)) || (v == Amalgame_Compiler_TokenType_KW_ENUM)) || (v == Amalgame_Compiler_TokenType_KW_MATCH)) || (v == Amalgame_Compiler_TokenType_KW_IN); } enum _Amalgame_Compiler_NodeKind { Amalgame_Compiler_NodeKind_PROGRAM, Amalgame_Compiler_NodeKind_CLASS_DECL, Amalgame_Compiler_NodeKind_METHOD_DECL, Amalgame_Compiler_NodeKind_FIELD_DECL, Amalgame_Compiler_NodeKind_PARAM, Amalgame_Compiler_NodeKind_ENUM_DECL, Amalgame_Compiler_NodeKind_BLOCK, Amalgame_Compiler_NodeKind_VAR_DECL, Amalgame_Compiler_NodeKind_ASSIGN, Amalgame_Compiler_NodeKind_RETURN_STMT, Amalgame_Compiler_NodeKind_IF_STMT, Amalgame_Compiler_NodeKind_WHILE_STMT, Amalgame_Compiler_NodeKind_FOR_IN_STMT, Amalgame_Compiler_NodeKind_BREAK_STMT, Amalgame_Compiler_NodeKind_CONTINUE_STMT, Amalgame_Compiler_NodeKind_TRY_STMT, Amalgame_Compiler_NodeKind_THROW_STMT, Amalgame_Compiler_NodeKind_BINARY, Amalgame_Compiler_NodeKind_UNARY, Amalgame_Compiler_NodeKind_CALL, Amalgame_Compiler_NodeKind_MEMBER, Amalgame_Compiler_NodeKind_IDENTIFIER, Amalgame_Compiler_NodeKind_LITERAL_INT, Amalgame_Compiler_NodeKind_LITERAL_FLOAT, Amalgame_Compiler_NodeKind_LITERAL_STRING, Amalgame_Compiler_NodeKind_LITERAL_BOOL, Amalgame_Compiler_NodeKind_LITERAL_NULL, Amalgame_Compiler_NodeKind_NEW_EXPR, Amalgame_Compiler_NodeKind_THIS_EXPR, Amalgame_Compiler_NodeKind_INDEX_EXPR, Amalgame_Compiler_NodeKind_LIST_COMP, Amalgame_Compiler_NodeKind_LIST_LITERAL, Amalgame_Compiler_NodeKind_INLINE_C, Amalgame_Compiler_NodeKind_INLINE_C_INCLUDE, Amalgame_Compiler_NodeKind_INLINE_C_LINK }; struct _Amalgame_Compiler_AstNode { Amalgame_Compiler_NodeKind Kind; i64 Line; i64 Column; code_string Name; code_string Str; code_string Str2; code_string Str3; code_string Str4; code_bool Flag; code_bool Flag2; code_bool Flag3; Amalgame_Compiler_AstNode* Left; Amalgame_Compiler_AstNode* Right; Amalgame_Compiler_AstNode* Cond; Amalgame_Compiler_AstNode* Body; Amalgame_Compiler_AstNode* Else; AmalgameList* Children; AmalgameList* Params; AmalgameList* Args; }; Amalgame_Compiler_AstNode* Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind kind, i64 line, i64 col) { Amalgame_Compiler_AstNode* self = (Amalgame_Compiler_AstNode*) GC_MALLOC(sizeof(Amalgame_Compiler_AstNode)); #line 99 "./src/parser/ast.am" self->Kind = kind; #line 100 "./src/parser/ast.am" self->Line = line; #line 101 "./src/parser/ast.am" self->Column = col; #line 102 "./src/parser/ast.am" self->Name = ""; #line 103 "./src/parser/ast.am" self->Str = ""; #line 104 "./src/parser/ast.am" self->Str2 = ""; #line 105 "./src/parser/ast.am" self->Str3 = ""; #line 106 "./src/parser/ast.am" self->Str4 = ""; #line 107 "./src/parser/ast.am" self->Flag = 0; #line 108 "./src/parser/ast.am" self->Flag2 = 0; #line 109 "./src/parser/ast.am" self->Flag3 = 0; #line 110 "./src/parser/ast.am" self->Left = NULL; #line 111 "./src/parser/ast.am" self->Right = NULL; #line 112 "./src/parser/ast.am" self->Cond = NULL; #line 113 "./src/parser/ast.am" self->Body = NULL; #line 114 "./src/parser/ast.am" self->Else = NULL; #line 115 "./src/parser/ast.am" self->Children = AmalgameList_new(); #line 116 "./src/parser/ast.am" self->Params = AmalgameList_new(); #line 117 "./src/parser/ast.am" self->Args = AmalgameList_new(); return self; } struct _Amalgame_Compiler_Ast { }; Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Program(i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Class(code_string name, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Method(code_string name, code_string retType, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Param(code_string name, code_string typeName, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Block(i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_VarDecl(code_string name, code_bool isMut, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Return(Amalgame_Compiler_AstNode* value, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_If(Amalgame_Compiler_AstNode* cond, Amalgame_Compiler_AstNode* then, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Binary(Amalgame_Compiler_AstNode* left, code_string op, Amalgame_Compiler_AstNode* right, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Call(Amalgame_Compiler_AstNode* callee, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Member(Amalgame_Compiler_AstNode* target, code_string member, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Ident(code_string name, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_IntLit(code_string raw, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_StrLit(code_string raw, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_BoolLit(code_bool val, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_FloatLit(code_string raw, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_NewExpr(code_string typeName, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_This(i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_InlineC(code_string body, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_InlineCInclude(code_string arg, i64 line, i64 col); Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_InlineCLink(code_string lib, i64 line, i64 col); Amalgame_Compiler_Ast* Amalgame_Compiler_Ast_new() { Amalgame_Compiler_Ast* self = (Amalgame_Compiler_Ast*) GC_MALLOC(sizeof(Amalgame_Compiler_Ast)); return self; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Program(i64 line, i64 col) { #line 125 "./src/parser/ast.am" return Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_PROGRAM, line, col); } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Class(code_string name, i64 line, i64 col) { #line 129 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_CLASS_DECL, line, col); #line 130 "./src/parser/ast.am" n->Name = name; #line 131 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Method(code_string name, code_string retType, i64 line, i64 col) { #line 135 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_METHOD_DECL, line, col); #line 136 "./src/parser/ast.am" n->Name = name; #line 137 "./src/parser/ast.am" n->Str = retType; #line 138 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Param(code_string name, code_string typeName, i64 line, i64 col) { #line 142 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_PARAM, line, col); #line 143 "./src/parser/ast.am" n->Name = name; #line 144 "./src/parser/ast.am" n->Str = typeName; #line 145 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Block(i64 line, i64 col) { #line 149 "./src/parser/ast.am" return Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_BLOCK, line, col); } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_VarDecl(code_string name, code_bool isMut, i64 line, i64 col) { #line 153 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_VAR_DECL, line, col); #line 154 "./src/parser/ast.am" n->Name = name; #line 155 "./src/parser/ast.am" n->Flag = isMut; #line 156 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Return(Amalgame_Compiler_AstNode* value, i64 line, i64 col) { #line 160 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_RETURN_STMT, line, col); #line 161 "./src/parser/ast.am" n->Left = value; #line 162 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_If(Amalgame_Compiler_AstNode* cond, Amalgame_Compiler_AstNode* then, i64 line, i64 col) { #line 166 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_IF_STMT, line, col); #line 167 "./src/parser/ast.am" n->Cond = cond; #line 168 "./src/parser/ast.am" n->Body = then; #line 169 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Binary(Amalgame_Compiler_AstNode* left, code_string op, Amalgame_Compiler_AstNode* right, i64 line, i64 col) { #line 173 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_BINARY, line, col); #line 174 "./src/parser/ast.am" n->Left = left; #line 175 "./src/parser/ast.am" n->Str = op; #line 176 "./src/parser/ast.am" n->Right = right; #line 177 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Call(Amalgame_Compiler_AstNode* callee, i64 line, i64 col) { #line 181 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_CALL, line, col); #line 182 "./src/parser/ast.am" n->Left = callee; #line 183 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Member(Amalgame_Compiler_AstNode* target, code_string member, i64 line, i64 col) { #line 187 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_MEMBER, line, col); #line 188 "./src/parser/ast.am" n->Left = target; #line 189 "./src/parser/ast.am" n->Name = member; #line 190 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_Ident(code_string name, i64 line, i64 col) { #line 194 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_IDENTIFIER, line, col); #line 195 "./src/parser/ast.am" n->Name = name; #line 196 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_IntLit(code_string raw, i64 line, i64 col) { #line 200 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_LITERAL_INT, line, col); #line 201 "./src/parser/ast.am" n->Str = raw; #line 202 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_StrLit(code_string raw, i64 line, i64 col) { #line 206 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_LITERAL_STRING, line, col); #line 207 "./src/parser/ast.am" n->Str = raw; #line 208 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_BoolLit(code_bool val, i64 line, i64 col) { #line 212 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_LITERAL_BOOL, line, col); #line 213 "./src/parser/ast.am" n->Flag = val; #line 214 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_FloatLit(code_string raw, i64 line, i64 col) { #line 218 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_LITERAL_FLOAT, line, col); #line 219 "./src/parser/ast.am" n->Str = raw; #line 220 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_NewExpr(code_string typeName, i64 line, i64 col) { #line 224 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_NEW_EXPR, line, col); #line 225 "./src/parser/ast.am" n->Name = typeName; #line 226 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_This(i64 line, i64 col) { #line 230 "./src/parser/ast.am" return Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_THIS_EXPR, line, col); } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_InlineC(code_string body, i64 line, i64 col) { #line 234 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_INLINE_C, line, col); #line 235 "./src/parser/ast.am" n->Str = body; #line 236 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_InlineCInclude(code_string arg, i64 line, i64 col) { #line 240 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_INLINE_C_INCLUDE, line, col); #line 241 "./src/parser/ast.am" n->Str = arg; #line 242 "./src/parser/ast.am" return n; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Ast_InlineCLink(code_string lib, i64 line, i64 col) { #line 246 "./src/parser/ast.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_INLINE_C_LINK, line, col); #line 247 "./src/parser/ast.am" n->Str = lib; #line 248 "./src/parser/ast.am" return n; } struct _Amalgame_Compiler_Lexer { code_string Source; i64 SourceLen; i64 Pos; i64 Line; i64 Column; code_string Filename; AmalgameList* Tokens; }; static code_bool Amalgame_Compiler_Lexer_IsSpace(Amalgame_Compiler_Lexer* self, code_string c); static code_bool Amalgame_Compiler_Lexer_IsDigit(Amalgame_Compiler_Lexer* self, code_string c); static code_bool Amalgame_Compiler_Lexer_IsHexDigit(Amalgame_Compiler_Lexer* self, code_string c); static code_bool Amalgame_Compiler_Lexer_IsBinDigit(Amalgame_Compiler_Lexer* self, code_string c); static code_bool Amalgame_Compiler_Lexer_IsAlpha(Amalgame_Compiler_Lexer* self, code_string c); static code_bool Amalgame_Compiler_Lexer_IsAlphaNum(Amalgame_Compiler_Lexer* self, code_string c); static code_string Amalgame_Compiler_Lexer_CharAt(Amalgame_Compiler_Lexer* self, i64 i); static void Amalgame_Compiler_Lexer_AddToken(Amalgame_Compiler_Lexer* self, Amalgame_Compiler_TokenType t, code_string value); static code_string Amalgame_Compiler_Lexer_Advance(Amalgame_Compiler_Lexer* self); static void Amalgame_Compiler_Lexer_SkipWhitespace(Amalgame_Compiler_Lexer* self); static void Amalgame_Compiler_Lexer_ReadLineComment(Amalgame_Compiler_Lexer* self); AmalgameList* Amalgame_Compiler_Lexer_Tokenize(Amalgame_Compiler_Lexer* self); static void Amalgame_Compiler_Lexer_ReadString(Amalgame_Compiler_Lexer* self); static void Amalgame_Compiler_Lexer_ReadTripleQuoted(Amalgame_Compiler_Lexer* self); static void Amalgame_Compiler_Lexer_TryReadInlineCOrAt(Amalgame_Compiler_Lexer* self, i64 startCol); static void Amalgame_Compiler_Lexer_ReadInlineCBody(Amalgame_Compiler_Lexer* self, i64 startCol); static i64 Amalgame_Compiler_Lexer_HexNibble(Amalgame_Compiler_Lexer* self, code_string ch); static void Amalgame_Compiler_Lexer_ReadNumber(Amalgame_Compiler_Lexer* self); static void Amalgame_Compiler_Lexer_ReadIdentifier(Amalgame_Compiler_Lexer* self); static Amalgame_Compiler_TokenType Amalgame_Compiler_Lexer_LookupKeyword(Amalgame_Compiler_Lexer* self, code_string word); static void Amalgame_Compiler_Lexer_ReadSymbol(Amalgame_Compiler_Lexer* self); Amalgame_Compiler_Lexer* Amalgame_Compiler_Lexer_new(code_string source, code_string filename) { Amalgame_Compiler_Lexer* self = (Amalgame_Compiler_Lexer*) GC_MALLOC(sizeof(Amalgame_Compiler_Lexer)); #line 22 "./src/lexer/lexer.am" self->Source = source; #line 23 "./src/lexer/lexer.am" self->SourceLen = String_Length(source); #line 24 "./src/lexer/lexer.am" self->Filename = filename; #line 25 "./src/lexer/lexer.am" self->Pos = 0LL; #line 26 "./src/lexer/lexer.am" self->Line = 1LL; #line 27 "./src/lexer/lexer.am" self->Column = 1LL; #line 28 "./src/lexer/lexer.am" self->Tokens = AmalgameList_new(); return self; } static code_bool Amalgame_Compiler_Lexer_IsSpace(Amalgame_Compiler_Lexer* self, code_string c) { #line 32 "./src/lexer/lexer.am" if (String_Length(c) == 0LL) { return 0; } #line 33 "./src/lexer/lexer.am" return ((code_string_equals(c, " ")) || (code_string_equals(c, "\t"))) || (code_string_equals(c, "\r")); } static code_bool Amalgame_Compiler_Lexer_IsDigit(Amalgame_Compiler_Lexer* self, code_string c) { #line 37 "./src/lexer/lexer.am" return String_Contains("0123456789", c); } static code_bool Amalgame_Compiler_Lexer_IsHexDigit(Amalgame_Compiler_Lexer* self, code_string c) { #line 41 "./src/lexer/lexer.am" return String_Contains("0123456789abcdefABCDEF", c); } static code_bool Amalgame_Compiler_Lexer_IsBinDigit(Amalgame_Compiler_Lexer* self, code_string c) { #line 45 "./src/lexer/lexer.am" return (code_string_equals(c, "0")) || (code_string_equals(c, "1")); } static code_bool Amalgame_Compiler_Lexer_IsAlpha(Amalgame_Compiler_Lexer* self, code_string c) { #line 49 "./src/lexer/lexer.am" return String_Contains("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_", c); } static code_bool Amalgame_Compiler_Lexer_IsAlphaNum(Amalgame_Compiler_Lexer* self, code_string c) { #line 53 "./src/lexer/lexer.am" return Amalgame_Compiler_Lexer_IsAlpha(self, c) || Amalgame_Compiler_Lexer_IsDigit(self, c); } static code_string Amalgame_Compiler_Lexer_CharAt(Amalgame_Compiler_Lexer* self, i64 i) { #line 57 "./src/lexer/lexer.am" if ((i < 0LL) || (i >= self->SourceLen)) { return ""; } #line 61 "./src/lexer/lexer.am" return String_CharAtUnchecked(self->Source, i); } static void Amalgame_Compiler_Lexer_AddToken(Amalgame_Compiler_Lexer* self, Amalgame_Compiler_TokenType t, code_string value) { #line 65 "./src/lexer/lexer.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Token_new(t, value, self->Line, self->Column, self->Filename); #line 66 "./src/lexer/lexer.am" AmalgameList_add(self->Tokens, (void*)(intptr_t)(tok)); } static code_string Amalgame_Compiler_Lexer_Advance(Amalgame_Compiler_Lexer* self) { #line 70 "./src/lexer/lexer.am" code_string ch = Amalgame_Compiler_Lexer_CharAt(self, self->Pos); #line 71 "./src/lexer/lexer.am" self->Pos = (self->Pos + 1LL); #line 72 "./src/lexer/lexer.am" self->Column = (self->Column + 1LL); #line 73 "./src/lexer/lexer.am" return ch; } static void Amalgame_Compiler_Lexer_SkipWhitespace(Amalgame_Compiler_Lexer* self) { #line 77 "./src/lexer/lexer.am" while (self->Pos < self->SourceLen) { #line 78 "./src/lexer/lexer.am" code_string c = Amalgame_Compiler_Lexer_CharAt(self, self->Pos); #line 79 "./src/lexer/lexer.am" if (Amalgame_Compiler_Lexer_IsSpace(self, c)) { #line 80 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); } else { #line 82 "./src/lexer/lexer.am" break; } } } static void Amalgame_Compiler_Lexer_ReadLineComment(Amalgame_Compiler_Lexer* self) { #line 88 "./src/lexer/lexer.am" i64 startLine = self->Line; #line 89 "./src/lexer/lexer.am" i64 startCol = self->Column; #line 90 "./src/lexer/lexer.am" i64 start = self->Pos; #line 91 "./src/lexer/lexer.am" while ((self->Pos < self->SourceLen) && (!code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos), "\n"))) { #line 92 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); } #line 94 "./src/lexer/lexer.am" code_string raw = String_Substring(self->Source, start, self->Pos - start); #line 95 "./src/lexer/lexer.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Token_new(Amalgame_Compiler_TokenType_COMMENT, raw, startLine, startCol, self->Filename); #line 96 "./src/lexer/lexer.am" AmalgameList_add(self->Tokens, (void*)(intptr_t)(tok)); } AmalgameList* Amalgame_Compiler_Lexer_Tokenize(Amalgame_Compiler_Lexer* self) { #line 100 "./src/lexer/lexer.am" while (self->Pos < self->SourceLen) { #line 101 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_SkipWhitespace(self); #line 102 "./src/lexer/lexer.am" if (self->Pos >= self->SourceLen) { break; } #line 103 "./src/lexer/lexer.am" code_string ch = Amalgame_Compiler_Lexer_CharAt(self, self->Pos); #line 104 "./src/lexer/lexer.am" if ((code_string_equals(ch, "/")) && (code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos + 1LL), "/"))) { #line 105 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_ReadLineComment(self); } else if (code_string_equals(ch, "\n")) { #line 107 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_NEWLINE, "\\n"); #line 108 "./src/lexer/lexer.am" self->Pos = (self->Pos + 1LL); #line 109 "./src/lexer/lexer.am" self->Line = (self->Line + 1LL); #line 110 "./src/lexer/lexer.am" self->Column = 1LL; } else if (code_string_equals(ch, "\"")) { #line 112 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_ReadString(self); } else if (Amalgame_Compiler_Lexer_IsDigit(self, ch)) { #line 114 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_ReadNumber(self); } else if (Amalgame_Compiler_Lexer_IsAlpha(self, ch)) { #line 116 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_ReadIdentifier(self); } else if (Amalgame_Compiler_Lexer_IsSpace(self, ch)) { #line 118 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); } else { #line 120 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_ReadSymbol(self); } } #line 123 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_EOF, ""); #line 124 "./src/lexer/lexer.am" return self->Tokens; } static void Amalgame_Compiler_Lexer_ReadString(Amalgame_Compiler_Lexer* self) { #line 128 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 131 "./src/lexer/lexer.am" if ((code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos), "\"")) && (code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos + 1LL), "\""))) { #line 132 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 133 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 134 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_ReadTripleQuoted(self); #line 135 "./src/lexer/lexer.am" return; } #line 137 "./src/lexer/lexer.am" code_string value = ""; #line 138 "./src/lexer/lexer.am" while ((self->Pos < self->SourceLen) && (!code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos), "\""))) { #line 139 "./src/lexer/lexer.am" code_string c = Amalgame_Compiler_Lexer_Advance(self); #line 140 "./src/lexer/lexer.am" if (code_string_equals(c, "\\")) { #line 141 "./src/lexer/lexer.am" code_string esc = Amalgame_Compiler_Lexer_Advance(self); #line 142 "./src/lexer/lexer.am" if (code_string_equals(esc, "n")) { value = (code_string_concat(value, "\n")); } #line 143 "./src/lexer/lexer.am" if (code_string_equals(esc, "t")) { value = (code_string_concat(value, "\t")); } #line 150 "./src/lexer/lexer.am" if (code_string_equals(esc, "r")) { value = (code_string_concat(value, String_FromByte(13LL))); } #line 151 "./src/lexer/lexer.am" if (code_string_equals(esc, "\"")) { value = (code_string_concat(value, "\"")); } #line 152 "./src/lexer/lexer.am" if (code_string_equals(esc, "\\")) { value = (code_string_concat(value, "\\")); } #line 154 "./src/lexer/lexer.am" if (code_string_equals(esc, "x")) { #line 155 "./src/lexer/lexer.am" code_string h1 = Amalgame_Compiler_Lexer_Advance(self); #line 156 "./src/lexer/lexer.am" code_string h2 = Amalgame_Compiler_Lexer_Advance(self); #line 157 "./src/lexer/lexer.am" i64 byte = (Amalgame_Compiler_Lexer_HexNibble(self, h1) * 16LL) + Amalgame_Compiler_Lexer_HexNibble(self, h2); #line 158 "./src/lexer/lexer.am" value = (code_string_concat(value, String_FromByte(byte))); } #line 161 "./src/lexer/lexer.am" if (code_string_equals(esc, "u")) { #line 162 "./src/lexer/lexer.am" code_string u1 = Amalgame_Compiler_Lexer_Advance(self); #line 163 "./src/lexer/lexer.am" code_string u2 = Amalgame_Compiler_Lexer_Advance(self); #line 164 "./src/lexer/lexer.am" code_string u3 = Amalgame_Compiler_Lexer_Advance(self); #line 165 "./src/lexer/lexer.am" code_string u4 = Amalgame_Compiler_Lexer_Advance(self); #line 166 "./src/lexer/lexer.am" i64 cp = (((Amalgame_Compiler_Lexer_HexNibble(self, u1) * 4096LL) + (Amalgame_Compiler_Lexer_HexNibble(self, u2) * 256LL)) + (Amalgame_Compiler_Lexer_HexNibble(self, u3) * 16LL)) + Amalgame_Compiler_Lexer_HexNibble(self, u4); #line 167 "./src/lexer/lexer.am" value = (code_string_concat(value, String_FromCodepoint(cp))); } } else { #line 170 "./src/lexer/lexer.am" value = (code_string_concat(value, c)); } } #line 173 "./src/lexer/lexer.am" if (self->Pos < self->SourceLen) { Amalgame_Compiler_Lexer_Advance(self); } #line 174 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_STRING, value); } static void Amalgame_Compiler_Lexer_ReadTripleQuoted(Amalgame_Compiler_Lexer* self) { #line 181 "./src/lexer/lexer.am" code_string value = ""; #line 182 "./src/lexer/lexer.am" i64 len = self->SourceLen; #line 183 "./src/lexer/lexer.am" while (self->Pos < len) { #line 185 "./src/lexer/lexer.am" if (((code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos), "\"")) && (code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos + 1LL), "\""))) && (code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos + 2LL), "\""))) { #line 186 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 187 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 188 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 189 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_STRING, value); #line 190 "./src/lexer/lexer.am" return; } #line 192 "./src/lexer/lexer.am" code_string c = Amalgame_Compiler_Lexer_Advance(self); #line 194 "./src/lexer/lexer.am" if (code_string_equals(c, "\n")) { #line 195 "./src/lexer/lexer.am" self->Line = (self->Line + 1LL); #line 196 "./src/lexer/lexer.am" self->Column = 1LL; } #line 198 "./src/lexer/lexer.am" value = (code_string_concat(value, c)); } #line 201 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_STRING, value); } static void Amalgame_Compiler_Lexer_TryReadInlineCOrAt(Amalgame_Compiler_Lexer* self, i64 startCol) { #line 209 "./src/lexer/lexer.am" i64 len = self->SourceLen; #line 210 "./src/lexer/lexer.am" if (code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos), "c")) { #line 211 "./src/lexer/lexer.am" i64 look = self->Pos + 1LL; #line 212 "./src/lexer/lexer.am" while (look < len) { #line 213 "./src/lexer/lexer.am" code_string lc = String_Substring(self->Source, look, 1LL); #line 214 "./src/lexer/lexer.am" if ((code_string_equals(lc, " ")) || (code_string_equals(lc, "\t"))) { look = (look + 1LL); } else { #line 215 "./src/lexer/lexer.am" break; } } #line 217 "./src/lexer/lexer.am" if ((look < len) && (code_string_equals(String_Substring(self->Source, look, 1LL), "{"))) { #line 218 "./src/lexer/lexer.am" i64 consumed = look - self->Pos; #line 219 "./src/lexer/lexer.am" for (i64 k = 0LL; k < consumed; k++) { Amalgame_Compiler_Lexer_Advance(self); } #line 220 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 221 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_ReadInlineCBody(self, startCol); #line 222 "./src/lexer/lexer.am" return; } } #line 225 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_AT, "@"); } static void Amalgame_Compiler_Lexer_ReadInlineCBody(Amalgame_Compiler_Lexer* self, i64 startCol) { #line 235 "./src/lexer/lexer.am" i64 startLine = self->Line; #line 236 "./src/lexer/lexer.am" code_string body = ""; #line 237 "./src/lexer/lexer.am" i64 depth = 1LL; #line 238 "./src/lexer/lexer.am" i64 len = self->SourceLen; #line 239 "./src/lexer/lexer.am" while ((self->Pos < len) && (depth > 0LL)) { #line 240 "./src/lexer/lexer.am" code_string c = Amalgame_Compiler_Lexer_CharAt(self, self->Pos); #line 241 "./src/lexer/lexer.am" if (code_string_equals(c, "\"")) { #line 242 "./src/lexer/lexer.am" body = (code_string_concat(body, c)); #line 243 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 244 "./src/lexer/lexer.am" while (self->Pos < len) { #line 245 "./src/lexer/lexer.am" code_string sc = Amalgame_Compiler_Lexer_CharAt(self, self->Pos); #line 246 "./src/lexer/lexer.am" body = (code_string_concat(body, sc)); #line 247 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 248 "./src/lexer/lexer.am" if ((code_string_equals(sc, "\\")) && (self->Pos < len)) { #line 249 "./src/lexer/lexer.am" body = (code_string_concat(body, Amalgame_Compiler_Lexer_CharAt(self, self->Pos))); #line 250 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); } else if (code_string_equals(sc, "\"")) { #line 252 "./src/lexer/lexer.am" break; } else if (code_string_equals(sc, "\n")) { #line 254 "./src/lexer/lexer.am" self->Line = (self->Line + 1LL); #line 255 "./src/lexer/lexer.am" self->Column = 1LL; } } #line 258 "./src/lexer/lexer.am" continue; } #line 260 "./src/lexer/lexer.am" if (code_string_equals(c, "'")) { #line 261 "./src/lexer/lexer.am" body = (code_string_concat(body, c)); #line 262 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 263 "./src/lexer/lexer.am" while (self->Pos < len) { #line 264 "./src/lexer/lexer.am" code_string sc = Amalgame_Compiler_Lexer_CharAt(self, self->Pos); #line 265 "./src/lexer/lexer.am" body = (code_string_concat(body, sc)); #line 266 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 267 "./src/lexer/lexer.am" if ((code_string_equals(sc, "\\")) && (self->Pos < len)) { #line 268 "./src/lexer/lexer.am" body = (code_string_concat(body, Amalgame_Compiler_Lexer_CharAt(self, self->Pos))); #line 269 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); } else if (code_string_equals(sc, "'")) { #line 271 "./src/lexer/lexer.am" break; } } #line 274 "./src/lexer/lexer.am" continue; } #line 276 "./src/lexer/lexer.am" if ((code_string_equals(c, "/")) && (code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos + 1LL), "/"))) { #line 277 "./src/lexer/lexer.am" body = (code_string_concat(body, c)); #line 278 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 279 "./src/lexer/lexer.am" while ((self->Pos < len) && (!code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos), "\n"))) { #line 280 "./src/lexer/lexer.am" body = (code_string_concat(body, Amalgame_Compiler_Lexer_CharAt(self, self->Pos))); #line 281 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); } #line 283 "./src/lexer/lexer.am" continue; } #line 285 "./src/lexer/lexer.am" if ((code_string_equals(c, "/")) && (code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos + 1LL), "*"))) { #line 286 "./src/lexer/lexer.am" body = (code_string_concat(body, c)); #line 287 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 288 "./src/lexer/lexer.am" body = (code_string_concat(body, Amalgame_Compiler_Lexer_CharAt(self, self->Pos))); #line 289 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 290 "./src/lexer/lexer.am" while (self->Pos < len) { #line 291 "./src/lexer/lexer.am" code_string cc = Amalgame_Compiler_Lexer_CharAt(self, self->Pos); #line 292 "./src/lexer/lexer.am" body = (code_string_concat(body, cc)); #line 293 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 294 "./src/lexer/lexer.am" if (code_string_equals(cc, "\n")) { #line 295 "./src/lexer/lexer.am" self->Line = (self->Line + 1LL); #line 296 "./src/lexer/lexer.am" self->Column = 1LL; } #line 298 "./src/lexer/lexer.am" if (((code_string_equals(cc, "*")) && (self->Pos < len)) && (code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos), "/"))) { #line 299 "./src/lexer/lexer.am" body = (code_string_concat(body, Amalgame_Compiler_Lexer_CharAt(self, self->Pos))); #line 300 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 301 "./src/lexer/lexer.am" break; } } #line 304 "./src/lexer/lexer.am" continue; } #line 306 "./src/lexer/lexer.am" if (code_string_equals(c, "{")) { #line 307 "./src/lexer/lexer.am" depth = (depth + 1LL); #line 308 "./src/lexer/lexer.am" body = (code_string_concat(body, c)); #line 309 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 310 "./src/lexer/lexer.am" continue; } #line 312 "./src/lexer/lexer.am" if (code_string_equals(c, "}")) { #line 313 "./src/lexer/lexer.am" depth = (depth - 1LL); #line 314 "./src/lexer/lexer.am" if (depth == 0LL) { #line 315 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 316 "./src/lexer/lexer.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Token_new(Amalgame_Compiler_TokenType_INLINE_C, body, startLine, startCol, self->Filename); #line 317 "./src/lexer/lexer.am" AmalgameList_add(self->Tokens, (void*)(intptr_t)(tok)); #line 318 "./src/lexer/lexer.am" return; } #line 320 "./src/lexer/lexer.am" body = (code_string_concat(body, c)); #line 321 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 322 "./src/lexer/lexer.am" continue; } #line 324 "./src/lexer/lexer.am" if (code_string_equals(c, "\n")) { #line 325 "./src/lexer/lexer.am" self->Line = (self->Line + 1LL); #line 326 "./src/lexer/lexer.am" self->Column = 1LL; } #line 328 "./src/lexer/lexer.am" body = (code_string_concat(body, c)); #line 329 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); } #line 333 "./src/lexer/lexer.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Token_new(Amalgame_Compiler_TokenType_INLINE_C, body, startLine, startCol, self->Filename); #line 334 "./src/lexer/lexer.am" AmalgameList_add(self->Tokens, (void*)(intptr_t)(tok)); } static i64 Amalgame_Compiler_Lexer_HexNibble(Amalgame_Compiler_Lexer* self, code_string ch) { #line 338 "./src/lexer/lexer.am" if (code_string_equals(ch, "0")) { return 0LL; } #line 339 "./src/lexer/lexer.am" if (code_string_equals(ch, "1")) { return 1LL; } #line 340 "./src/lexer/lexer.am" if (code_string_equals(ch, "2")) { return 2LL; } #line 341 "./src/lexer/lexer.am" if (code_string_equals(ch, "3")) { return 3LL; } #line 342 "./src/lexer/lexer.am" if (code_string_equals(ch, "4")) { return 4LL; } #line 343 "./src/lexer/lexer.am" if (code_string_equals(ch, "5")) { return 5LL; } #line 344 "./src/lexer/lexer.am" if (code_string_equals(ch, "6")) { return 6LL; } #line 345 "./src/lexer/lexer.am" if (code_string_equals(ch, "7")) { return 7LL; } #line 346 "./src/lexer/lexer.am" if (code_string_equals(ch, "8")) { return 8LL; } #line 347 "./src/lexer/lexer.am" if (code_string_equals(ch, "9")) { return 9LL; } #line 348 "./src/lexer/lexer.am" if ((code_string_equals(ch, "a")) || (code_string_equals(ch, "A"))) { return 10LL; } #line 349 "./src/lexer/lexer.am" if ((code_string_equals(ch, "b")) || (code_string_equals(ch, "B"))) { return 11LL; } #line 350 "./src/lexer/lexer.am" if ((code_string_equals(ch, "c")) || (code_string_equals(ch, "C"))) { return 12LL; } #line 351 "./src/lexer/lexer.am" if ((code_string_equals(ch, "d")) || (code_string_equals(ch, "D"))) { return 13LL; } #line 352 "./src/lexer/lexer.am" if ((code_string_equals(ch, "e")) || (code_string_equals(ch, "E"))) { return 14LL; } #line 353 "./src/lexer/lexer.am" if ((code_string_equals(ch, "f")) || (code_string_equals(ch, "F"))) { return 15LL; } #line 354 "./src/lexer/lexer.am" return 0LL; } static void Amalgame_Compiler_Lexer_ReadNumber(Amalgame_Compiler_Lexer* self) { #line 358 "./src/lexer/lexer.am" i64 startCol = self->Column; #line 362 "./src/lexer/lexer.am" if ((code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos), "0")) && ((code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos + 1LL), "x")) || (code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos + 1LL), "X")))) { #line 363 "./src/lexer/lexer.am" code_string hex = Amalgame_Compiler_Lexer_Advance(self); #line 364 "./src/lexer/lexer.am" hex = (code_string_concat(hex, Amalgame_Compiler_Lexer_Advance(self))); #line 365 "./src/lexer/lexer.am" while ((self->Pos < self->SourceLen) && Amalgame_Compiler_Lexer_IsHexDigit(self, Amalgame_Compiler_Lexer_CharAt(self, self->Pos))) { #line 366 "./src/lexer/lexer.am" hex = (code_string_concat(hex, Amalgame_Compiler_Lexer_Advance(self))); } #line 368 "./src/lexer/lexer.am" Amalgame_Compiler_Token* htok = Amalgame_Compiler_Token_new(Amalgame_Compiler_TokenType_INTEGER, hex, self->Line, startCol, self->Filename); #line 369 "./src/lexer/lexer.am" AmalgameList_add(self->Tokens, (void*)(intptr_t)(htok)); #line 370 "./src/lexer/lexer.am" return; } #line 375 "./src/lexer/lexer.am" if ((code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos), "0")) && ((code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos + 1LL), "b")) || (code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos + 1LL), "B")))) { #line 376 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 377 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 378 "./src/lexer/lexer.am" i64 dec = 0LL; #line 379 "./src/lexer/lexer.am" while ((self->Pos < self->SourceLen) && Amalgame_Compiler_Lexer_IsBinDigit(self, Amalgame_Compiler_Lexer_CharAt(self, self->Pos))) { #line 380 "./src/lexer/lexer.am" code_string bch = Amalgame_Compiler_Lexer_Advance(self); #line 381 "./src/lexer/lexer.am" dec = (dec * 2LL); #line 382 "./src/lexer/lexer.am" if (code_string_equals(bch, "1")) { dec = (dec + 1LL); } } #line 384 "./src/lexer/lexer.am" Amalgame_Compiler_Token* btok = Amalgame_Compiler_Token_new(Amalgame_Compiler_TokenType_INTEGER, String_FromInt(dec), self->Line, startCol, self->Filename); #line 385 "./src/lexer/lexer.am" AmalgameList_add(self->Tokens, (void*)(intptr_t)(btok)); #line 386 "./src/lexer/lexer.am" return; } #line 389 "./src/lexer/lexer.am" code_string value = ""; #line 390 "./src/lexer/lexer.am" code_bool isFloat = 0; #line 391 "./src/lexer/lexer.am" while ((self->Pos < self->SourceLen) && Amalgame_Compiler_Lexer_IsDigit(self, Amalgame_Compiler_Lexer_CharAt(self, self->Pos))) { #line 392 "./src/lexer/lexer.am" value = (code_string_concat(value, Amalgame_Compiler_Lexer_Advance(self))); } #line 394 "./src/lexer/lexer.am" if (((self->Pos < self->SourceLen) && (code_string_equals(Amalgame_Compiler_Lexer_CharAt(self, self->Pos), "."))) && Amalgame_Compiler_Lexer_IsDigit(self, Amalgame_Compiler_Lexer_CharAt(self, self->Pos + 1LL))) { #line 395 "./src/lexer/lexer.am" isFloat = 1; #line 396 "./src/lexer/lexer.am" value = (code_string_concat(value, Amalgame_Compiler_Lexer_Advance(self))); #line 397 "./src/lexer/lexer.am" while ((self->Pos < self->SourceLen) && Amalgame_Compiler_Lexer_IsDigit(self, Amalgame_Compiler_Lexer_CharAt(self, self->Pos))) { #line 398 "./src/lexer/lexer.am" value = (code_string_concat(value, Amalgame_Compiler_Lexer_Advance(self))); } } #line 401 "./src/lexer/lexer.am" if (isFloat) { #line 402 "./src/lexer/lexer.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Token_new(Amalgame_Compiler_TokenType_FLOAT, value, self->Line, startCol, self->Filename); #line 403 "./src/lexer/lexer.am" AmalgameList_add(self->Tokens, (void*)(intptr_t)(tok)); } else { #line 405 "./src/lexer/lexer.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Token_new(Amalgame_Compiler_TokenType_INTEGER, value, self->Line, startCol, self->Filename); #line 406 "./src/lexer/lexer.am" AmalgameList_add(self->Tokens, (void*)(intptr_t)(tok)); } } static void Amalgame_Compiler_Lexer_ReadIdentifier(Amalgame_Compiler_Lexer* self) { #line 411 "./src/lexer/lexer.am" i64 startCol = self->Column; #line 412 "./src/lexer/lexer.am" code_string value = ""; #line 413 "./src/lexer/lexer.am" while ((self->Pos < self->SourceLen) && Amalgame_Compiler_Lexer_IsAlphaNum(self, Amalgame_Compiler_Lexer_CharAt(self, self->Pos))) { #line 414 "./src/lexer/lexer.am" value = (code_string_concat(value, Amalgame_Compiler_Lexer_Advance(self))); } #line 416 "./src/lexer/lexer.am" Amalgame_Compiler_TokenType tt = Amalgame_Compiler_Lexer_LookupKeyword(self, value); #line 417 "./src/lexer/lexer.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Token_new(tt, value, self->Line, startCol, self->Filename); #line 418 "./src/lexer/lexer.am" AmalgameList_add(self->Tokens, (void*)(intptr_t)(tok)); } static Amalgame_Compiler_TokenType Amalgame_Compiler_Lexer_LookupKeyword(Amalgame_Compiler_Lexer* self, code_string word) { #line 422 "./src/lexer/lexer.am" if (code_string_equals(word, "let")) { return Amalgame_Compiler_TokenType_KW_LET; } #line 423 "./src/lexer/lexer.am" if (code_string_equals(word, "var")) { return Amalgame_Compiler_TokenType_KW_VAR; } #line 424 "./src/lexer/lexer.am" if (code_string_equals(word, "if")) { return Amalgame_Compiler_TokenType_KW_IF; } #line 425 "./src/lexer/lexer.am" if (code_string_equals(word, "else")) { return Amalgame_Compiler_TokenType_KW_ELSE; } #line 426 "./src/lexer/lexer.am" if (code_string_equals(word, "for")) { return Amalgame_Compiler_TokenType_KW_FOR; } #line 427 "./src/lexer/lexer.am" if (code_string_equals(word, "while")) { return Amalgame_Compiler_TokenType_KW_WHILE; } #line 428 "./src/lexer/lexer.am" if (code_string_equals(word, "return")) { return Amalgame_Compiler_TokenType_KW_RETURN; } #line 429 "./src/lexer/lexer.am" if (code_string_equals(word, "class")) { return Amalgame_Compiler_TokenType_KW_CLASS; } #line 430 "./src/lexer/lexer.am" if (code_string_equals(word, "public")) { return Amalgame_Compiler_TokenType_KW_PUBLIC; } #line 431 "./src/lexer/lexer.am" if (code_string_equals(word, "private")) { return Amalgame_Compiler_TokenType_KW_PRIVATE; } #line 432 "./src/lexer/lexer.am" if (code_string_equals(word, "static")) { return Amalgame_Compiler_TokenType_KW_STATIC; } #line 433 "./src/lexer/lexer.am" if (code_string_equals(word, "new")) { return Amalgame_Compiler_TokenType_KW_NEW; } #line 434 "./src/lexer/lexer.am" if (code_string_equals(word, "this")) { return Amalgame_Compiler_TokenType_KW_THIS; } #line 435 "./src/lexer/lexer.am" if (code_string_equals(word, "null")) { return Amalgame_Compiler_TokenType_KW_NULL; } #line 436 "./src/lexer/lexer.am" if (code_string_equals(word, "true")) { return Amalgame_Compiler_TokenType_KW_TRUE; } #line 437 "./src/lexer/lexer.am" if (code_string_equals(word, "false")) { return Amalgame_Compiler_TokenType_KW_FALSE; } #line 438 "./src/lexer/lexer.am" if (code_string_equals(word, "import")) { return Amalgame_Compiler_TokenType_KW_IMPORT; } #line 439 "./src/lexer/lexer.am" if (code_string_equals(word, "namespace")) { return Amalgame_Compiler_TokenType_KW_NAMESPACE; } #line 440 "./src/lexer/lexer.am" if (code_string_equals(word, "enum")) { return Amalgame_Compiler_TokenType_KW_ENUM; } #line 441 "./src/lexer/lexer.am" if (code_string_equals(word, "match")) { return Amalgame_Compiler_TokenType_KW_MATCH; } #line 442 "./src/lexer/lexer.am" if (code_string_equals(word, "in")) { return Amalgame_Compiler_TokenType_KW_IN; } #line 443 "./src/lexer/lexer.am" if (code_string_equals(word, "is")) { return Amalgame_Compiler_TokenType_KW_IS; } #line 444 "./src/lexer/lexer.am" if (code_string_equals(word, "as")) { return Amalgame_Compiler_TokenType_KW_AS; } #line 445 "./src/lexer/lexer.am" if (code_string_equals(word, "void")) { return Amalgame_Compiler_TokenType_KW_VOID; } #line 446 "./src/lexer/lexer.am" if (code_string_equals(word, "int")) { return Amalgame_Compiler_TokenType_KW_INT; } #line 447 "./src/lexer/lexer.am" if (code_string_equals(word, "string")) { return Amalgame_Compiler_TokenType_KW_STRING_TYPE; } #line 448 "./src/lexer/lexer.am" if (code_string_equals(word, "bool")) { return Amalgame_Compiler_TokenType_KW_BOOL_TYPE; } #line 449 "./src/lexer/lexer.am" if (code_string_equals(word, "float")) { return Amalgame_Compiler_TokenType_KW_FLOAT_TYPE; } #line 450 "./src/lexer/lexer.am" if (code_string_equals(word, "try")) { return Amalgame_Compiler_TokenType_KW_TRY; } #line 451 "./src/lexer/lexer.am" if (code_string_equals(word, "catch")) { return Amalgame_Compiler_TokenType_KW_CATCH; } #line 452 "./src/lexer/lexer.am" if (code_string_equals(word, "throw")) { return Amalgame_Compiler_TokenType_KW_THROW; } #line 453 "./src/lexer/lexer.am" if (code_string_equals(word, "finally")) { return Amalgame_Compiler_TokenType_KW_FINALLY; } #line 454 "./src/lexer/lexer.am" if (code_string_equals(word, "interface")) { return Amalgame_Compiler_TokenType_KW_INTERFACE; } #line 455 "./src/lexer/lexer.am" if (code_string_equals(word, "record")) { return Amalgame_Compiler_TokenType_KW_RECORD; } #line 456 "./src/lexer/lexer.am" if (code_string_equals(word, "func")) { return Amalgame_Compiler_TokenType_KW_FUNC; } #line 457 "./src/lexer/lexer.am" if (code_string_equals(word, "guard")) { return Amalgame_Compiler_TokenType_KW_GUARD; } #line 458 "./src/lexer/lexer.am" return Amalgame_Compiler_TokenType_IDENTIFIER; } static void Amalgame_Compiler_Lexer_ReadSymbol(Amalgame_Compiler_Lexer* self) { #line 462 "./src/lexer/lexer.am" i64 startCol = self->Column; #line 463 "./src/lexer/lexer.am" code_string c = Amalgame_Compiler_Lexer_Advance(self); #line 464 "./src/lexer/lexer.am" code_string c2 = Amalgame_Compiler_Lexer_CharAt(self, self->Pos); #line 466 "./src/lexer/lexer.am" if (code_string_equals(c, "+")) { #line 467 "./src/lexer/lexer.am" if (code_string_equals(c2, "=")) { Amalgame_Compiler_Lexer_Advance(self); #line 468 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_PLUS_EQ, "+="); } else { #line 469 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_PLUS, "+"); } } else if (code_string_equals(c, "%")) { #line 471 "./src/lexer/lexer.am" if (code_string_equals(c2, "=")) { Amalgame_Compiler_Lexer_Advance(self); #line 472 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_PERCENT_EQ, "%="); } else { #line 473 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_PERCENT, "%"); } } else if (code_string_equals(c, "@")) { #line 475 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_TryReadInlineCOrAt(self, startCol); } else if (code_string_equals(c, "(")) { #line 476 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_LPAREN, "("); } else if (code_string_equals(c, ")")) { #line 477 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_RPAREN, ")"); } else if (code_string_equals(c, "{")) { #line 478 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_LBRACE, "{"); } else if (code_string_equals(c, "}")) { #line 479 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_RBRACE, "}"); } else if (code_string_equals(c, "[")) { #line 480 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_LBRACKET, "["); } else if (code_string_equals(c, "]")) { #line 481 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_RBRACKET, "]"); } else if (code_string_equals(c, ",")) { #line 482 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_COMMA, ","); } else if (code_string_equals(c, ";")) { #line 483 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_SEMICOLON, ";"); } else if (code_string_equals(c, "/")) { #line 485 "./src/lexer/lexer.am" if (code_string_equals(c2, "=")) { Amalgame_Compiler_Lexer_Advance(self); #line 486 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_SLASH_EQ, "/="); } else { #line 487 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_SLASH, "/"); } } else if (code_string_equals(c, "-")) { #line 490 "./src/lexer/lexer.am" if (code_string_equals(c2, ">")) { Amalgame_Compiler_Lexer_Advance(self); #line 491 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_THIN_ARROW, "->"); } else if (code_string_equals(c2, "=")) { #line 492 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 493 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_MINUS_EQ, "-="); } else { #line 494 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_MINUS, "-"); } } else if (code_string_equals(c, "*")) { #line 496 "./src/lexer/lexer.am" if (code_string_equals(c2, "=")) { Amalgame_Compiler_Lexer_Advance(self); #line 497 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_STAR_EQ, "*="); } else { #line 498 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_STAR, "*"); } } else if (code_string_equals(c, "=")) { #line 500 "./src/lexer/lexer.am" if (code_string_equals(c2, "=")) { Amalgame_Compiler_Lexer_Advance(self); #line 501 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_EQEQ, "=="); } else if (code_string_equals(c2, ">")) { #line 502 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 503 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_ARROW, "=>"); } else { #line 504 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_EQ, "="); } } else if (code_string_equals(c, "!")) { #line 506 "./src/lexer/lexer.am" if (code_string_equals(c2, "=")) { Amalgame_Compiler_Lexer_Advance(self); #line 507 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_NEQ, "!="); } else { #line 508 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_NOT, "!"); } } else if (code_string_equals(c, "<")) { #line 510 "./src/lexer/lexer.am" if (code_string_equals(c2, "=")) { Amalgame_Compiler_Lexer_Advance(self); #line 511 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_LTE, "<="); } else if (code_string_equals(c2, "<")) { #line 512 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 513 "./src/lexer/lexer.am" code_string c3 = Amalgame_Compiler_Lexer_CharAt(self, self->Pos); #line 514 "./src/lexer/lexer.am" if (code_string_equals(c3, "=")) { Amalgame_Compiler_Lexer_Advance(self); #line 515 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_SHL_EQ, "<<="); } else { #line 516 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_SHL, "<<"); } } else { #line 517 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_LT, "<"); } } else if (code_string_equals(c, ">")) { #line 519 "./src/lexer/lexer.am" if (code_string_equals(c2, "=")) { Amalgame_Compiler_Lexer_Advance(self); #line 520 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_GTE, ">="); } else if (code_string_equals(c2, ">")) { #line 521 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 522 "./src/lexer/lexer.am" code_string c3 = Amalgame_Compiler_Lexer_CharAt(self, self->Pos); #line 523 "./src/lexer/lexer.am" if (code_string_equals(c3, "=")) { Amalgame_Compiler_Lexer_Advance(self); #line 524 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_SHR_EQ, ">>="); } else { #line 525 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_SHR, ">>"); } } else { #line 526 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_GT, ">"); } } else if (code_string_equals(c, "&")) { #line 528 "./src/lexer/lexer.am" if (code_string_equals(c2, "&")) { Amalgame_Compiler_Lexer_Advance(self); #line 529 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_AND, "&&"); } else if (code_string_equals(c2, "=")) { #line 530 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 531 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_AMP_EQ, "&="); } else { #line 532 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_AMP, "&"); } } else if (code_string_equals(c, "|")) { #line 534 "./src/lexer/lexer.am" if (code_string_equals(c2, "|")) { Amalgame_Compiler_Lexer_Advance(self); #line 535 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_OR, "||"); } else if (code_string_equals(c2, "=")) { #line 536 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 537 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_PIPE_EQ, "|="); } else { #line 538 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_PIPE, "|"); } } else if (code_string_equals(c, ".")) { #line 540 "./src/lexer/lexer.am" if (code_string_equals(c2, ".")) { #line 541 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 548 "./src/lexer/lexer.am" code_string c3 = Amalgame_Compiler_Lexer_CharAt(self, self->Pos); #line 549 "./src/lexer/lexer.am" if (code_string_equals(c3, ".")) { #line 550 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 551 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_SPREAD, "..."); } else { #line 553 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_DOTDOT, ".."); } } else { #line 556 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_DOT, "."); } } else if (code_string_equals(c, ":")) { #line 558 "./src/lexer/lexer.am" if (code_string_equals(c2, ":")) { Amalgame_Compiler_Lexer_Advance(self); #line 559 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_COLON, "::"); } else { #line 560 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_COLON, ":"); } } else if (code_string_equals(c, "?")) { #line 562 "./src/lexer/lexer.am" if (code_string_equals(c2, "?")) { Amalgame_Compiler_Lexer_Advance(self); #line 563 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_COALESCE, "??"); } else if (code_string_equals(c2, ".")) { #line 564 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_Advance(self); #line 565 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_QDOT, "?."); } else { #line 566 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_QMARK, "?"); } } else if (code_string_equals(c, "~")) { #line 568 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_TILDE, "~"); } else if (code_string_equals(c, "^")) { #line 570 "./src/lexer/lexer.am" if (code_string_equals(c2, "=")) { Amalgame_Compiler_Lexer_Advance(self); #line 571 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_CARET_EQ, "^="); } else { #line 572 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_OP_CARET, "^"); } } else { #line 574 "./src/lexer/lexer.am" Amalgame_Compiler_Lexer_AddToken(self, Amalgame_Compiler_TokenType_UNKNOWN, c); } } struct _Amalgame_Compiler_Parser { AmalgameList* Tokens; i64 TokenCount; i64 Pos; AmalgameList* Errors; i64 ParenDepth; code_string PendingDecorators; AmalgameList* Comments; }; static void Amalgame_Compiler_Parser_ParseDecoratorList(Amalgame_Compiler_Parser* self); static code_string Amalgame_Compiler_Parser_TakeDecorators(Amalgame_Compiler_Parser* self); Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_Parse(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseInlineCDirective(Amalgame_Compiler_Parser* self); code_bool Amalgame_Compiler_Parser_HasErrors(Amalgame_Compiler_Parser* self); code_string Amalgame_Compiler_Parser_GetErrors(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_Current(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_Peek(Amalgame_Compiler_Parser* self, i64 offset); static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_Advance(Amalgame_Compiler_Parser* self); static code_bool Amalgame_Compiler_Parser_IsEnd(Amalgame_Compiler_Parser* self); static code_bool Amalgame_Compiler_Parser_CheckType(Amalgame_Compiler_Parser* self, Amalgame_Compiler_TokenType t); static code_bool Amalgame_Compiler_Parser_CheckKw(Amalgame_Compiler_Parser* self, code_string word); static code_bool Amalgame_Compiler_Parser_CheckValue(Amalgame_Compiler_Parser* self, code_string v); static void Amalgame_Compiler_Parser_SkipNewlines(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_Expect(Amalgame_Compiler_Parser* self, code_string value); static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_ExpectIdent(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_Unknown(Amalgame_Compiler_Parser* self); static code_string Amalgame_Compiler_Parser_ParseQualifiedName(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseDecl(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseClass(Amalgame_Compiler_Parser* self, code_bool isPublic); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseDataClass(Amalgame_Compiler_Parser* self, code_bool isPublic); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMember(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseField(Amalgame_Compiler_Parser* self, code_bool isPublic); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMethod(Amalgame_Compiler_Parser* self, code_string retType, code_bool isPublic, code_bool isStatic, code_bool isAsync, i64 line, i64 col); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseParam(Amalgame_Compiler_Parser* self); static code_string Amalgame_Compiler_Parser_ParseTypeName(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseBlock(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseStmt(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseLoop(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseRegion(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseSetup(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseTry(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseThrow(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseInlineC(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseVarDecl(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseReturn(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseIf(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseGuard(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseWhile(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseForIn(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseEnum(Amalgame_Compiler_Parser* self, code_bool isPublic); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseInterface(Amalgame_Compiler_Parser* self, code_bool isPublic); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseExpr(Amalgame_Compiler_Parser* self); static code_bool Amalgame_Compiler_Parser_IsLambdaParenStart(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseLambdaSingle(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseLambdaMulti(Amalgame_Compiler_Parser* self); static void Amalgame_Compiler_Parser_ParseLambdaBody(Amalgame_Compiler_Parser* self, Amalgame_Compiler_AstNode* lam); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseAssign(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseTernary(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseRange(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseOr(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseBitwiseOr(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseBitwiseXor(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseBitwiseAnd(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseAnd(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseEquality(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseRelational(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseShift(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseAdd(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMul(Amalgame_Compiler_Parser* self); static code_bool Amalgame_Compiler_Parser_LookaheadAfterNewlinesIs(Amalgame_Compiler_Parser* self, code_string s1, code_string s2, code_string s3); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseUnary(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParsePostfix(Amalgame_Compiler_Parser* self); static code_bool Amalgame_Compiler_Parser_LookaheadStartsWithDot(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseCallArgs(Amalgame_Compiler_Parser* self, Amalgame_Compiler_AstNode* callee); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParsePrimary(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseListItem(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseListComp(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMatch(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMatchPattern(Amalgame_Compiler_Parser* self); static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseNew(Amalgame_Compiler_Parser* self); Amalgame_Compiler_Parser* Amalgame_Compiler_Parser_new(AmalgameList* tokens) { Amalgame_Compiler_Parser* self = (Amalgame_Compiler_Parser*) GC_MALLOC(sizeof(Amalgame_Compiler_Parser)); #line 21 "./src/parser/parser.am" AmalgameList* filtered = AmalgameList_new(); #line 22 "./src/parser/parser.am" AmalgameList* comments = AmalgameList_new(); #line 23 "./src/parser/parser.am" i64 total = AmalgameList_count(tokens); #line 24 "./src/parser/parser.am" i64 i = 0LL; #line 25 "./src/parser/parser.am" while (i < total) { #line 26 "./src/parser/parser.am" Amalgame_Compiler_Token* t = (void*)AmalgameList_get(tokens, i); #line 27 "./src/parser/parser.am" if (t->Type == Amalgame_Compiler_TokenType_COMMENT) { #line 28 "./src/parser/parser.am" AmalgameList_add(comments, (void*)(intptr_t)(t)); } else { #line 30 "./src/parser/parser.am" AmalgameList_add(filtered, (void*)(intptr_t)(t)); } #line 32 "./src/parser/parser.am" i = (i + 1LL); } #line 34 "./src/parser/parser.am" self->Tokens = filtered; #line 35 "./src/parser/parser.am" self->TokenCount = AmalgameList_count(filtered); #line 36 "./src/parser/parser.am" self->Pos = 0LL; #line 37 "./src/parser/parser.am" self->Errors = AmalgameList_new(); #line 38 "./src/parser/parser.am" self->ParenDepth = 0LL; #line 39 "./src/parser/parser.am" self->PendingDecorators = ""; #line 40 "./src/parser/parser.am" self->Comments = comments; return self; } static void Amalgame_Compiler_Parser_ParseDecoratorList(Amalgame_Compiler_Parser* self) { #line 46 "./src/parser/parser.am" while (Amalgame_Compiler_Parser_CheckValue(self, "@")) { #line 47 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 48 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 49 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_Advance(self); #line 50 "./src/parser/parser.am" if (String_Length(self->PendingDecorators) > 0LL) { #line 51 "./src/parser/parser.am" self->PendingDecorators = (code_string_concat(self->PendingDecorators, ",")); } #line 53 "./src/parser/parser.am" self->PendingDecorators = (code_string_concat(self->PendingDecorators, nameTok->Value)); } #line 55 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } } static code_string Amalgame_Compiler_Parser_TakeDecorators(Amalgame_Compiler_Parser* self) { #line 60 "./src/parser/parser.am" code_string d = self->PendingDecorators; #line 61 "./src/parser/parser.am" self->PendingDecorators = ""; #line 62 "./src/parser/parser.am" return d; } Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_Parse(Amalgame_Compiler_Parser* self) { #line 68 "./src/parser/parser.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Ast_Program(1LL, 1LL); #line 70 "./src/parser/parser.am" if (AmalgameList_count(self->Tokens) > 0LL) { #line 71 "./src/parser/parser.am" Amalgame_Compiler_Token* firstTok = (Amalgame_Compiler_Token*)AmalgameList_get(self->Tokens, 0LL); #line 72 "./src/parser/parser.am" prog->Str2 = firstTok->Filename; } #line 74 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 76 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "namespace")) { #line 77 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 78 "./src/parser/parser.am" prog->Str = Amalgame_Compiler_Parser_ParseQualifiedName(self); #line 79 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 82 "./src/parser/parser.am" while (Amalgame_Compiler_Parser_CheckKw(self, "import")) { #line 83 "./src/parser/parser.am" Amalgame_Compiler_Token* importTok = Amalgame_Compiler_Parser_Advance(self); #line 84 "./src/parser/parser.am" code_string qname = Amalgame_Compiler_Parser_ParseQualifiedName(self); #line 88 "./src/parser/parser.am" Amalgame_Compiler_AstNode* imp = Amalgame_Compiler_Ast_Ident(qname, importTok->Line, importTok->Column); #line 89 "./src/parser/parser.am" AmalgameList_add(prog->Args, (void*)(intptr_t)(imp)); #line 90 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 93 "./src/parser/parser.am" i64 parseLastPos = 0LL; #line 94 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self)) { #line 95 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 96 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_IsEnd(self)) { break; } #line 97 "./src/parser/parser.am" i64 parsePos = self->Pos; #line 98 "./src/parser/parser.am" if ((parsePos == parseLastPos) && (parseLastPos > 0LL)) { #line 99 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 100 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_IsEnd(self)) { break; } } #line 102 "./src/parser/parser.am" parseLastPos = self->Pos; #line 110 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_INLINE_C)) { #line 111 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 112 "./src/parser/parser.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_Ast_InlineC(tok->Value, tok->Line, tok->Column); #line 113 "./src/parser/parser.am" AmalgameList_add(prog->Children, (void*)(intptr_t)(node)); #line 114 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 115 "./src/parser/parser.am" continue; } #line 120 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_AT)) { #line 121 "./src/parser/parser.am" Amalgame_Compiler_Token* nextTok = Amalgame_Compiler_Parser_Peek(self, 1LL); #line 122 "./src/parser/parser.am" if ((nextTok->Type == Amalgame_Compiler_TokenType_IDENTIFIER) && ((code_string_equals(nextTok->Value, "c_include")) || (code_string_equals(nextTok->Value, "c_link")))) { #line 123 "./src/parser/parser.am" Amalgame_Compiler_AstNode* directive = Amalgame_Compiler_Parser_ParseInlineCDirective(self); #line 124 "./src/parser/parser.am" AmalgameList_add(prog->Children, (void*)(intptr_t)(directive)); #line 125 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 126 "./src/parser/parser.am" continue; } } #line 129 "./src/parser/parser.am" code_string curVal = Amalgame_Compiler_Parser_Current(self)->Value; #line 130 "./src/parser/parser.am" Amalgame_Compiler_AstNode* decl = Amalgame_Compiler_Parser_ParseDecl(self); #line 131 "./src/parser/parser.am" Amalgame_Compiler_NodeKind dk = decl->Kind; #line 132 "./src/parser/parser.am" if (dk != Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 133 "./src/parser/parser.am" AmalgameList_add(prog->Children, (void*)(intptr_t)(decl)); } #line 135 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 137 "./src/parser/parser.am" return prog; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseInlineCDirective(Amalgame_Compiler_Parser* self) { #line 144 "./src/parser/parser.am" Amalgame_Compiler_Token* atTok = Amalgame_Compiler_Parser_Advance(self); #line 145 "./src/parser/parser.am" Amalgame_Compiler_Token* kwTok = Amalgame_Compiler_Parser_Advance(self); #line 146 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_STRING)) { #line 147 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Unknown(self); } #line 149 "./src/parser/parser.am" Amalgame_Compiler_Token* strTok = Amalgame_Compiler_Parser_Advance(self); #line 150 "./src/parser/parser.am" if (code_string_equals(kwTok->Value, "c_include")) { #line 151 "./src/parser/parser.am" return Amalgame_Compiler_Ast_InlineCInclude(strTok->Value, atTok->Line, atTok->Column); } #line 153 "./src/parser/parser.am" return Amalgame_Compiler_Ast_InlineCLink(strTok->Value, atTok->Line, atTok->Column); } code_bool Amalgame_Compiler_Parser_HasErrors(Amalgame_Compiler_Parser* self) { #line 157 "./src/parser/parser.am" return AmalgameList_count(self->Errors) > 0LL; } code_string Amalgame_Compiler_Parser_GetErrors(Amalgame_Compiler_Parser* self) { #line 161 "./src/parser/parser.am" code_string result = ""; #line 162 "./src/parser/parser.am" i64 count = AmalgameList_count(self->Errors); #line 163 "./src/parser/parser.am" for (i64 i = 0LL; i < count; i++) { #line 164 "./src/parser/parser.am" code_string e = (code_string)AmalgameList_get(self->Errors, i); #line 165 "./src/parser/parser.am" result = (code_string_concat((code_string_concat(result, e)), "\n")); } #line 167 "./src/parser/parser.am" return result; } static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_Current(Amalgame_Compiler_Parser* self) { #line 173 "./src/parser/parser.am" i64 count = self->TokenCount; #line 174 "./src/parser/parser.am" if (self->Pos >= count) { #line 175 "./src/parser/parser.am" return (Amalgame_Compiler_Token*)AmalgameList_get(self->Tokens, count - 1LL); } #line 177 "./src/parser/parser.am" return (Amalgame_Compiler_Token*)AmalgameList_get(self->Tokens, self->Pos); } static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_Peek(Amalgame_Compiler_Parser* self, i64 offset) { #line 181 "./src/parser/parser.am" i64 i = self->Pos + offset; #line 182 "./src/parser/parser.am" i64 count = self->TokenCount; #line 183 "./src/parser/parser.am" if (i >= count) { return (Amalgame_Compiler_Token*)AmalgameList_get(self->Tokens, count - 1LL); } #line 184 "./src/parser/parser.am" return (Amalgame_Compiler_Token*)AmalgameList_get(self->Tokens, i); } static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_Advance(Amalgame_Compiler_Parser* self) { #line 188 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Current(self); #line 189 "./src/parser/parser.am" self->Pos = (self->Pos + 1LL); #line 190 "./src/parser/parser.am" return tok; } static code_bool Amalgame_Compiler_Parser_IsEnd(Amalgame_Compiler_Parser* self) { #line 194 "./src/parser/parser.am" if (self->Pos >= self->TokenCount) { return 1; } #line 195 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = (Amalgame_Compiler_Token*)AmalgameList_get(self->Tokens, self->Pos); #line 196 "./src/parser/parser.am" return tok->Type == Amalgame_Compiler_TokenType_EOF; } static code_bool Amalgame_Compiler_Parser_CheckType(Amalgame_Compiler_Parser* self, Amalgame_Compiler_TokenType t) { #line 200 "./src/parser/parser.am" if (self->Pos >= self->TokenCount) { return 0; } #line 201 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = (Amalgame_Compiler_Token*)AmalgameList_get(self->Tokens, self->Pos); #line 202 "./src/parser/parser.am" return tok->Type == t; } static code_bool Amalgame_Compiler_Parser_CheckKw(Amalgame_Compiler_Parser* self, code_string word) { #line 206 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Current(self); #line 207 "./src/parser/parser.am" return code_string_equals(tok->Value, word); } static code_bool Amalgame_Compiler_Parser_CheckValue(Amalgame_Compiler_Parser* self, code_string v) { #line 211 "./src/parser/parser.am" if (self->Pos >= self->TokenCount) { return 0; } #line 212 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = (Amalgame_Compiler_Token*)AmalgameList_get(self->Tokens, self->Pos); #line 213 "./src/parser/parser.am" return code_string_equals(tok->Value, v); } static void Amalgame_Compiler_Parser_SkipNewlines(Amalgame_Compiler_Parser* self) { #line 225 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_NEWLINE) || Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_SEMICOLON))) { #line 226 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } } static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_Expect(Amalgame_Compiler_Parser* self, code_string value) { #line 231 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Current(self); #line 232 "./src/parser/parser.am" if (code_string_equals(tok->Value, value)) { #line 233 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Advance(self); } #line 235 "./src/parser/parser.am" i64 line = tok->Line; #line 236 "./src/parser/parser.am" i64 col = tok->Column; #line 237 "./src/parser/parser.am" code_string got = tok->Value; #line 238 "./src/parser/parser.am" AmalgameList_add(self->Errors, (void*)(intptr_t)(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("Expected '", value)), "' at ")), String_FromInt(line))), ":")), String_FromInt(col))), " got '")), got)), "'"))); #line 239 "./src/parser/parser.am" return tok; } static Amalgame_Compiler_Token* Amalgame_Compiler_Parser_ExpectIdent(Amalgame_Compiler_Parser* self) { #line 243 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Current(self); #line 244 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 245 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Advance(self); } #line 247 "./src/parser/parser.am" i64 line = tok->Line; #line 248 "./src/parser/parser.am" code_string got = tok->Value; #line 249 "./src/parser/parser.am" AmalgameList_add(self->Errors, (void*)(intptr_t)(code_string_concat((code_string_concat((code_string_concat((code_string_concat("Expected identifier at line ", String_FromInt(line))), " got '")), got)), "'"))); #line 251 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 252 "./src/parser/parser.am" return tok; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_Unknown(Amalgame_Compiler_Parser* self) { #line 256 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Current(self); #line 257 "./src/parser/parser.am" return Amalgame_Compiler_Ast_Ident("_unknown_", tok->Line, tok->Column); } static code_string Amalgame_Compiler_Parser_ParseQualifiedName(Amalgame_Compiler_Parser* self) { #line 263 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 264 "./src/parser/parser.am" code_string name = tok->Value; #line 265 "./src/parser/parser.am" while (Amalgame_Compiler_Parser_CheckValue(self, ".")) { #line 266 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 267 "./src/parser/parser.am" Amalgame_Compiler_Token* next = Amalgame_Compiler_Parser_ExpectIdent(self); #line 268 "./src/parser/parser.am" name = (code_string_concat((code_string_concat(name, ".")), next->Value)); } #line 270 "./src/parser/parser.am" return name; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseDecl(Amalgame_Compiler_Parser* self) { #line 276 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 277 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_IsEnd(self)) { return Amalgame_Compiler_Parser_Unknown(self); } #line 278 "./src/parser/parser.am" code_bool isPublic = 0; #line 279 "./src/parser/parser.am" code_bool isStatic = 0; #line 281 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "public")) { #line 282 "./src/parser/parser.am" isPublic = 1; #line 283 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } #line 285 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "private")) { #line 286 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } #line 288 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "static")) { #line 289 "./src/parser/parser.am" isStatic = 1; #line 290 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } #line 296 "./src/parser/parser.am" code_string v = Amalgame_Compiler_Parser_Current(self)->Value; #line 297 "./src/parser/parser.am" { /* match v */ if (strcmp(v, "class") == 0) { #line 298 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseClass(self, isPublic); } else if (strcmp(v, "data") == 0) { #line 301 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 302 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "class")) { #line 303 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseDataClass(self, isPublic); } } else if (strcmp(v, "record") == 0) { #line 308 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 309 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseDataClass(self, isPublic); } else if (strcmp(v, "enum") == 0) { #line 311 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseEnum(self, isPublic); } else if (strcmp(v, "interface") == 0) { #line 312 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseInterface(self, isPublic); } else if (strcmp(v, "fn") == 0) { #line 320 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Current(self); #line 321 "./src/parser/parser.am" code_string name = ""; #line 322 "./src/parser/parser.am" Amalgame_Compiler_Token* nextTok = Amalgame_Compiler_Parser_Peek(self, 1LL); #line 323 "./src/parser/parser.am" if (nextTok->Type == Amalgame_Compiler_TokenType_IDENTIFIER) { #line 324 "./src/parser/parser.am" name = nextTok->Value; } #line 326 "./src/parser/parser.am" AmalgameList_add(self->Errors, (void*)(intptr_t)(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("Top-level functions aren't supported (got 'fn ", name)), "' at ")), String_FromInt(tok->Line))), ":")), String_FromInt(tok->Column))), "). Wrap it inside a class as `public static`."))); #line 328 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, "{")) { Amalgame_Compiler_Parser_Advance(self); } #line 329 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "{")) { #line 330 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 331 "./src/parser/parser.am" i64 depth = 1LL; #line 332 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && (depth > 0LL)) { #line 333 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "{")) { depth = (depth + 1LL); } else if (Amalgame_Compiler_Parser_CheckValue(self, "}")) { #line 334 "./src/parser/parser.am" depth = (depth - 1LL); } #line 335 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } } #line 338 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Unknown(self); } else { } } #line 356 "./src/parser/parser.am" Amalgame_Compiler_Token* startTok = Amalgame_Compiler_Parser_Current(self); #line 357 "./src/parser/parser.am" code_bool foundFreeFn = 0; #line 358 "./src/parser/parser.am" code_string freeFnName = ""; #line 359 "./src/parser/parser.am" i64 lookI = 0LL; #line 360 "./src/parser/parser.am" while ((lookI < 16LL) && !Amalgame_Compiler_Parser_IsEnd(self)) { #line 361 "./src/parser/parser.am" Amalgame_Compiler_Token* t = Amalgame_Compiler_Parser_Peek(self, lookI); #line 362 "./src/parser/parser.am" Amalgame_Compiler_Token* t1 = Amalgame_Compiler_Parser_Peek(self, lookI + 1LL); #line 363 "./src/parser/parser.am" code_string tv = t->Value; #line 364 "./src/parser/parser.am" if ((t->Type == Amalgame_Compiler_TokenType_IDENTIFIER) && (code_string_equals(t1->Value, "("))) { #line 365 "./src/parser/parser.am" freeFnName = t->Value; #line 366 "./src/parser/parser.am" foundFreeFn = 1; #line 367 "./src/parser/parser.am" break; } #line 369 "./src/parser/parser.am" if (((code_string_equals(tv, "{")) || (code_string_equals(tv, ";"))) || (code_string_equals(tv, "}"))) { break; } #line 370 "./src/parser/parser.am" lookI = (lookI + 1LL); } #line 372 "./src/parser/parser.am" if (foundFreeFn) { #line 373 "./src/parser/parser.am" AmalgameList_add(self->Errors, (void*)(intptr_t)(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("Top-level functions aren't supported (got '", freeFnName)), "' at ")), String_FromInt(startTok->Line))), ":")), String_FromInt(startTok->Column))), "). Wrap it inside a class as `public static`."))); #line 374 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, "{")) { Amalgame_Compiler_Parser_Advance(self); } #line 375 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "{")) { #line 376 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 377 "./src/parser/parser.am" i64 depth = 1LL; #line 378 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && (depth > 0LL)) { #line 379 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "{")) { depth = (depth + 1LL); } else if (Amalgame_Compiler_Parser_CheckValue(self, "}")) { #line 380 "./src/parser/parser.am" depth = (depth - 1LL); } #line 381 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } } #line 384 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Unknown(self); } #line 387 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 388 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Unknown(self); } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseClass(Amalgame_Compiler_Parser* self, code_bool isPublic) { #line 394 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 395 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 396 "./src/parser/parser.am" Amalgame_Compiler_AstNode* cls = Amalgame_Compiler_Ast_Class(nameTok->Value, tok->Line, tok->Column); #line 397 "./src/parser/parser.am" cls->Flag = isPublic; #line 399 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "<")) { #line 400 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 401 "./src/parser/parser.am" code_string gparams = ""; #line 402 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, ">")) { #line 403 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); continue; } #line 404 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 405 "./src/parser/parser.am" Amalgame_Compiler_Token* pTok = Amalgame_Compiler_Parser_Advance(self); #line 406 "./src/parser/parser.am" if (String_Length(gparams) > 0LL) { gparams = (code_string_concat(gparams, ",")); } #line 407 "./src/parser/parser.am" gparams = (code_string_concat(gparams, pTok->Value)); } else { #line 409 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } } #line 412 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ">")) { Amalgame_Compiler_Parser_Advance(self); } #line 413 "./src/parser/parser.am" cls->Str3 = gparams; } #line 416 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "extends")) { #line 417 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 418 "./src/parser/parser.am" cls->Str = Amalgame_Compiler_Parser_ParseQualifiedName(self); } #line 422 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "implements")) { #line 423 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 424 "./src/parser/parser.am" code_string impl = ""; #line 425 "./src/parser/parser.am" while ((!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, "{")) && !Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_NEWLINE)) { #line 426 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); continue; } #line 427 "./src/parser/parser.am" code_string iname = Amalgame_Compiler_Parser_ParseTypeName(self); #line 428 "./src/parser/parser.am" if (String_Length(iname) > 0LL) { #line 429 "./src/parser/parser.am" if (String_Length(impl) > 0LL) { impl = (code_string_concat(impl, ",")); } #line 430 "./src/parser/parser.am" impl = (code_string_concat(impl, iname)); } } #line 433 "./src/parser/parser.am" cls->Str4 = impl; } #line 435 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 437 "./src/parser/parser.am" i64 classLastPos = 0LL; #line 438 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, "}")) { #line 439 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 440 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "}")) { break; } #line 441 "./src/parser/parser.am" i64 classPos = self->Pos; #line 442 "./src/parser/parser.am" if ((classPos == classLastPos) && (classLastPos > 0LL)) { #line 443 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 444 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "}")) { break; } } #line 446 "./src/parser/parser.am" classLastPos = self->Pos; #line 447 "./src/parser/parser.am" Amalgame_Compiler_AstNode* member = Amalgame_Compiler_Parser_ParseMember(self); #line 448 "./src/parser/parser.am" Amalgame_Compiler_NodeKind mk = member->Kind; #line 449 "./src/parser/parser.am" if (mk != Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 450 "./src/parser/parser.am" AmalgameList_add(cls->Children, (void*)(intptr_t)(member)); } #line 452 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 455 "./src/parser/parser.am" Amalgame_Compiler_Token* clsClose = Amalgame_Compiler_Parser_Current(self); #line 456 "./src/parser/parser.am" cls->Str2 = String_FromInt(clsClose->Line); #line 457 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "}"); #line 458 "./src/parser/parser.am" return cls; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseDataClass(Amalgame_Compiler_Parser* self, code_bool isPublic) { #line 464 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "class")) { #line 465 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } #line 467 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 468 "./src/parser/parser.am" Amalgame_Compiler_AstNode* cls = Amalgame_Compiler_Ast_Class(nameTok->Value, nameTok->Line, nameTok->Column); #line 469 "./src/parser/parser.am" cls->Flag = isPublic; #line 471 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "(")) { #line 472 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 473 "./src/parser/parser.am" Amalgame_Compiler_AstNode* ctor = Amalgame_Compiler_Ast_Method(nameTok->Value, "void", nameTok->Line, nameTok->Column); #line 474 "./src/parser/parser.am" ctor->Flag = 1; #line 475 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, ")")) { #line 476 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 477 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ")")) { break; } #line 478 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); } #line 479 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 480 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ")")) { break; } #line 481 "./src/parser/parser.am" code_string ftype = Amalgame_Compiler_Parser_ParseTypeName(self); #line 482 "./src/parser/parser.am" Amalgame_Compiler_Token* fname = Amalgame_Compiler_Parser_ExpectIdent(self); #line 484 "./src/parser/parser.am" Amalgame_Compiler_AstNode* field = Amalgame_Compiler_Ast_VarDecl(fname->Value, 1, fname->Line, fname->Column); #line 485 "./src/parser/parser.am" field->Str = ftype; #line 486 "./src/parser/parser.am" field->Flag = 1; #line 487 "./src/parser/parser.am" AmalgameList_add(cls->Children, (void*)(intptr_t)(field)); #line 489 "./src/parser/parser.am" Amalgame_Compiler_AstNode* param = Amalgame_Compiler_Ast_Param(fname->Value, ftype, fname->Line, fname->Column); #line 490 "./src/parser/parser.am" AmalgameList_add(ctor->Params, (void*)(intptr_t)(param)); #line 491 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); } } #line 493 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ")")) { Amalgame_Compiler_Parser_Advance(self); } #line 494 "./src/parser/parser.am" AmalgameList_add(cls->Children, (void*)(intptr_t)(ctor)); } #line 497 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "{")) { #line 498 "./src/parser/parser.am" i64 depth2 = 0LL; #line 499 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self)) { #line 500 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "{")) { depth2 = (depth2 + 1LL); } #line 501 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "}")) { #line 502 "./src/parser/parser.am" depth2 = (depth2 - 1LL); #line 503 "./src/parser/parser.am" if (depth2 == 0LL) { #line 504 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 505 "./src/parser/parser.am" break; } } #line 508 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } } #line 511 "./src/parser/parser.am" return cls; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMember(Amalgame_Compiler_Parser* self) { #line 515 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 516 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_IsEnd(self) || Amalgame_Compiler_Parser_CheckValue(self, "}")) { #line 517 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Unknown(self); } #line 522 "./src/parser/parser.am" Amalgame_Compiler_Parser_ParseDecoratorList(self); #line 523 "./src/parser/parser.am" code_bool isPublic = 0; #line 524 "./src/parser/parser.am" code_bool isStatic = 0; #line 526 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "public")) { #line 527 "./src/parser/parser.am" isPublic = 1; #line 528 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } #line 530 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "private")) { #line 531 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } #line 533 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "static")) { #line 534 "./src/parser/parser.am" isStatic = 1; #line 535 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } #line 541 "./src/parser/parser.am" code_bool isAsync = 0; #line 542 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "async")) { #line 543 "./src/parser/parser.am" Amalgame_Compiler_Token* pkA = Amalgame_Compiler_Parser_Peek(self, 1LL); #line 544 "./src/parser/parser.am" if ((!code_string_equals(pkA->Value, "(")) && (!code_string_equals(pkA->Value, ":"))) { #line 545 "./src/parser/parser.am" isAsync = 1; #line 546 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 552 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "fn")) { #line 553 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } } } #line 558 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Current(self); #line 560 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 561 "./src/parser/parser.am" Amalgame_Compiler_Token* peek = Amalgame_Compiler_Parser_Peek(self, 1LL); #line 562 "./src/parser/parser.am" if (code_string_equals(peek->Value, ":")) { #line 563 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseField(self, isPublic); } #line 565 "./src/parser/parser.am" if (code_string_equals(peek->Value, "(")) { #line 566 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseMethod(self, "void", isPublic, isStatic, isAsync, tok->Line, tok->Column); } #line 568 "./src/parser/parser.am" code_string typeName = Amalgame_Compiler_Parser_ParseTypeName(self); #line 569 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_Current(self); #line 570 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 571 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseMethod(self, typeName, isPublic, isStatic, isAsync, tok->Line, tok->Column); } } else if (((((code_string_equals(tok->Value, "int")) || (code_string_equals(tok->Value, "string"))) || (code_string_equals(tok->Value, "bool"))) || (code_string_equals(tok->Value, "void"))) || (code_string_equals(tok->Value, "float"))) { #line 575 "./src/parser/parser.am" code_string typeName = Amalgame_Compiler_Parser_ParseTypeName(self); #line 576 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 577 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseMethod(self, typeName, isPublic, isStatic, isAsync, tok->Line, tok->Column); } } else if (code_string_equals(tok->Value, "(")) { #line 582 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 583 "./src/parser/parser.am" code_string tupleTypes = ""; #line 584 "./src/parser/parser.am" i64 tupleCount = 0LL; #line 585 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, ")")) { #line 586 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 587 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); continue; } #line 588 "./src/parser/parser.am" code_string tname = Amalgame_Compiler_Parser_ParseTypeName(self); #line 589 "./src/parser/parser.am" if (tupleCount > 0LL) { tupleTypes = (code_string_concat(tupleTypes, ",")); } #line 590 "./src/parser/parser.am" tupleTypes = (code_string_concat(tupleTypes, tname)); #line 591 "./src/parser/parser.am" tupleCount = (tupleCount + 1LL); } #line 593 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ")")) { Amalgame_Compiler_Parser_Advance(self); } #line 594 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 596 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 597 "./src/parser/parser.am" code_string retType = code_string_concat((code_string_concat("(", tupleTypes)), ")"); #line 598 "./src/parser/parser.am" Amalgame_Compiler_AstNode* method = Amalgame_Compiler_Parser_ParseMethod(self, retType, isPublic, isStatic, isAsync, tok->Line, tok->Column); #line 599 "./src/parser/parser.am" return method; } #line 601 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Unknown(self); } #line 604 "./src/parser/parser.am" while ((!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_NEWLINE)) && !Amalgame_Compiler_Parser_CheckValue(self, "}")) { #line 605 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } #line 607 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Unknown(self); } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseField(Amalgame_Compiler_Parser* self, code_bool isPublic) { #line 613 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 614 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ":"); #line 615 "./src/parser/parser.am" code_string typeName = Amalgame_Compiler_Parser_ParseTypeName(self); #line 616 "./src/parser/parser.am" Amalgame_Compiler_AstNode* field = Amalgame_Compiler_Ast_VarDecl(nameTok->Value, 0, nameTok->Line, nameTok->Column); #line 617 "./src/parser/parser.am" field->Str = typeName; #line 618 "./src/parser/parser.am" field->Flag = isPublic; #line 619 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "=")) { #line 620 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 621 "./src/parser/parser.am" field->Left = Amalgame_Compiler_Parser_ParseExpr(self); } #line 623 "./src/parser/parser.am" return field; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMethod(Amalgame_Compiler_Parser* self, code_string retType, code_bool isPublic, code_bool isStatic, code_bool isAsync, i64 line, i64 col) { #line 629 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 634 "./src/parser/parser.am" Amalgame_Compiler_AstNode* method = Amalgame_Compiler_Ast_Method(nameTok->Value, retType, nameTok->Line, nameTok->Column); #line 635 "./src/parser/parser.am" method->Flag = isPublic; #line 636 "./src/parser/parser.am" method->Flag2 = isStatic; #line 637 "./src/parser/parser.am" method->Flag3 = isAsync; #line 639 "./src/parser/parser.am" method->Str2 = Amalgame_Compiler_Parser_TakeDecorators(self); #line 640 "./src/parser/parser.am" code_string mname = nameTok->Value; #line 642 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "<")) { #line 643 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 644 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, ">")) { Amalgame_Compiler_Parser_Advance(self); } #line 645 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ">")) { Amalgame_Compiler_Parser_Advance(self); } } #line 648 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "("); #line 649 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 650 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, ")")) { #line 651 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { #line 652 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 653 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 654 "./src/parser/parser.am" continue; } #line 660 "./src/parser/parser.am" i64 beforePos = self->Pos; #line 661 "./src/parser/parser.am" Amalgame_Compiler_AstNode* p = Amalgame_Compiler_Parser_ParseParam(self); #line 662 "./src/parser/parser.am" if (self->Pos == beforePos) { #line 663 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } #line 665 "./src/parser/parser.am" Amalgame_Compiler_NodeKind pk = p->Kind; #line 666 "./src/parser/parser.am" if (pk != Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 667 "./src/parser/parser.am" AmalgameList_add(method->Params, (void*)(intptr_t)(p)); } #line 669 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 671 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ")"); #line 680 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ":")) { #line 681 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 682 "./src/parser/parser.am" method->Str = Amalgame_Compiler_Parser_ParseTypeName(self); } #line 685 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "=>")) { #line 686 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 687 "./src/parser/parser.am" Amalgame_Compiler_AstNode* body = Amalgame_Compiler_Ast_Block(line, col); #line 688 "./src/parser/parser.am" Amalgame_Compiler_AstNode* ret = Amalgame_Compiler_Ast_Return(Amalgame_Compiler_Parser_ParseExpr(self), line, col); #line 689 "./src/parser/parser.am" AmalgameList_add(body->Children, (void*)(intptr_t)(ret)); #line 690 "./src/parser/parser.am" method->Body = body; #line 691 "./src/parser/parser.am" return method; } #line 694 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 695 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "{")) { #line 696 "./src/parser/parser.am" method->Body = Amalgame_Compiler_Parser_ParseBlock(self); } #line 698 "./src/parser/parser.am" return method; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseParam(Amalgame_Compiler_Parser* self) { #line 723 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_OP_SPREAD)) { #line 724 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 725 "./src/parser/parser.am" Amalgame_Compiler_AstNode* inner = Amalgame_Compiler_Parser_ParseParam(self); #line 726 "./src/parser/parser.am" inner->Flag = 1; #line 727 "./src/parser/parser.am" return inner; } #line 729 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Current(self); #line 730 "./src/parser/parser.am" code_string v = tok->Value; #line 731 "./src/parser/parser.am" code_bool isKeywordType = ((((code_string_equals(v, "int")) || (code_string_equals(v, "string"))) || (code_string_equals(v, "bool"))) || (code_string_equals(v, "void"))) || (code_string_equals(v, "float")); #line 732 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER) && !isKeywordType) { #line 735 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 736 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Unknown(self); } #line 738 "./src/parser/parser.am" code_string typeName = Amalgame_Compiler_Parser_ParseTypeName(self); #line 744 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ":")) { #line 745 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 746 "./src/parser/parser.am" Amalgame_Compiler_Token* realTypeTok = Amalgame_Compiler_Parser_Current(self); #line 747 "./src/parser/parser.am" code_string rv = realTypeTok->Value; #line 748 "./src/parser/parser.am" code_bool rIsKeywordType = ((((code_string_equals(rv, "int")) || (code_string_equals(rv, "string"))) || (code_string_equals(rv, "bool"))) || (code_string_equals(rv, "void"))) || (code_string_equals(rv, "float")); #line 749 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER) || rIsKeywordType) { #line 750 "./src/parser/parser.am" code_string realType = Amalgame_Compiler_Parser_ParseTypeName(self); #line 751 "./src/parser/parser.am" return Amalgame_Compiler_Ast_Param(typeName, realType, tok->Line, tok->Column); } #line 755 "./src/parser/parser.am" return Amalgame_Compiler_Ast_Param(typeName, "?", tok->Line, tok->Column); } #line 757 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 758 "./src/parser/parser.am" return Amalgame_Compiler_Ast_Param("_", typeName, 0LL, 0LL); } #line 760 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 761 "./src/parser/parser.am" return Amalgame_Compiler_Ast_Param(nameTok->Value, typeName, nameTok->Line, nameTok->Column); } static code_string Amalgame_Compiler_Parser_ParseTypeName(Amalgame_Compiler_Parser* self) { #line 767 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Current(self); #line 768 "./src/parser/parser.am" code_string v = tok->Value; #line 769 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 770 "./src/parser/parser.am" if (((((code_string_equals(v, "void")) || (code_string_equals(v, "int"))) || (code_string_equals(v, "string"))) || (code_string_equals(v, "bool"))) || (code_string_equals(v, "float"))) { #line 771 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 772 "./src/parser/parser.am" code_string kwName = v; #line 773 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "[")) { #line 774 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 775 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "]"); #line 776 "./src/parser/parser.am" kwName = (code_string_concat(kwName, "[]")); } #line 778 "./src/parser/parser.am" return kwName; } #line 780 "./src/parser/parser.am" return "void"; } #line 782 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 783 "./src/parser/parser.am" code_string name = nameTok->Value; #line 784 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "<")) { #line 785 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 786 "./src/parser/parser.am" name = (code_string_concat(name, "<")); #line 787 "./src/parser/parser.am" i64 depth = 1LL; #line 788 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && (depth > 0LL)) { #line 789 "./src/parser/parser.am" Amalgame_Compiler_Token* inner = Amalgame_Compiler_Parser_Current(self); #line 790 "./src/parser/parser.am" code_string iv = inner->Value; #line 791 "./src/parser/parser.am" if (code_string_equals(iv, ">>")) { #line 797 "./src/parser/parser.am" if (depth >= 3LL) { #line 798 "./src/parser/parser.am" name = (code_string_concat(name, ">>")); #line 799 "./src/parser/parser.am" depth = (depth - 2LL); } else if (depth == 2LL) { #line 801 "./src/parser/parser.am" name = (code_string_concat(name, ">")); #line 802 "./src/parser/parser.am" depth = 0LL; } else { #line 806 "./src/parser/parser.am" depth = 0LL; } #line 808 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } else { #line 810 "./src/parser/parser.am" if (code_string_equals(iv, "<")) { depth = (depth + 1LL); } #line 811 "./src/parser/parser.am" if (code_string_equals(iv, ">")) { depth = (depth - 1LL); } #line 812 "./src/parser/parser.am" if (depth > 0LL) { name = (code_string_concat(name, iv)); } #line 813 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } } #line 816 "./src/parser/parser.am" name = (code_string_concat(name, ">")); } #line 818 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "[")) { #line 819 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 820 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "]"); #line 821 "./src/parser/parser.am" name = (code_string_concat(name, "[]")); } #line 823 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "?")) { #line 824 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 825 "./src/parser/parser.am" name = (code_string_concat(name, "?")); } #line 827 "./src/parser/parser.am" return name; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseBlock(Amalgame_Compiler_Parser* self) { #line 833 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Expect(self, "{"); #line 834 "./src/parser/parser.am" Amalgame_Compiler_AstNode* block = Amalgame_Compiler_Ast_Block(tok->Line, tok->Column); #line 835 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 836 "./src/parser/parser.am" i64 lastPos = 0LL; #line 837 "./src/parser/parser.am" code_bool hadProgress = 1; #line 838 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, "}")) { #line 839 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 840 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "}")) { break; } #line 841 "./src/parser/parser.am" i64 curPos = self->Pos; #line 842 "./src/parser/parser.am" if (!hadProgress) { #line 843 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 844 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 845 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "}")) { break; } #line 846 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_IsEnd(self)) { break; } } #line 848 "./src/parser/parser.am" lastPos = self->Pos; #line 849 "./src/parser/parser.am" hadProgress = 0; #line 850 "./src/parser/parser.am" Amalgame_Compiler_AstNode* stmt = Amalgame_Compiler_Parser_ParseStmt(self); #line 851 "./src/parser/parser.am" AmalgameList_add(block->Children, (void*)(intptr_t)(stmt)); #line 852 "./src/parser/parser.am" hadProgress = 1; #line 853 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 858 "./src/parser/parser.am" Amalgame_Compiler_Token* closeTok = Amalgame_Compiler_Parser_Current(self); #line 859 "./src/parser/parser.am" block->Str2 = String_FromInt(closeTok->Line); #line 860 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "}"); #line 861 "./src/parser/parser.am" return block; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseStmt(Amalgame_Compiler_Parser* self) { #line 867 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 868 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_IsEnd(self) || Amalgame_Compiler_Parser_CheckValue(self, "}")) { #line 869 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Unknown(self); } #line 871 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Current(self); #line 872 "./src/parser/parser.am" code_string v = tok->Value; #line 876 "./src/parser/parser.am" if (tok->Type == Amalgame_Compiler_TokenType_INLINE_C) { return Amalgame_Compiler_Parser_ParseInlineC(self); } #line 878 "./src/parser/parser.am" { /* match v */ if (strcmp(v, "let") == 0) { #line 879 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseVarDecl(self); } else if (strcmp(v, "var") == 0) { #line 880 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseVarDecl(self); } else if (strcmp(v, "return") == 0) { #line 881 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseReturn(self); } else if (strcmp(v, "if") == 0) { #line 882 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseIf(self); } else if (strcmp(v, "while") == 0) { #line 883 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseWhile(self); } else if (strcmp(v, "for") == 0) { #line 884 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseForIn(self); } else if (strcmp(v, "break") == 0) { #line 886 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 887 "./src/parser/parser.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_BREAK_STMT, tok->Line, tok->Column); #line 888 "./src/parser/parser.am" return n; } else if (strcmp(v, "continue") == 0) { #line 891 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 892 "./src/parser/parser.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_CONTINUE_STMT, tok->Line, tok->Column); #line 893 "./src/parser/parser.am" return n; } else if (strcmp(v, "match") == 0) { #line 895 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseMatch(self); } else if (strcmp(v, "guard") == 0) { #line 896 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseGuard(self); } else if (strcmp(v, "try") == 0) { #line 897 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseTry(self); } else if (strcmp(v, "throw") == 0) { #line 898 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseThrow(self); } else if (strcmp(v, "{") == 0) { #line 899 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseBlock(self); } else if (strcmp(v, "loop") == 0) { #line 904 "./src/parser/parser.am" if (code_string_equals(Amalgame_Compiler_Parser_Peek(self, 1LL)->Value, "{")) { return Amalgame_Compiler_Parser_ParseLoop(self); } } else if (strcmp(v, "setup") == 0) { #line 905 "./src/parser/parser.am" if (code_string_equals(Amalgame_Compiler_Parser_Peek(self, 1LL)->Value, "{")) { return Amalgame_Compiler_Parser_ParseSetup(self); } } else if (strcmp(v, "region") == 0) { #line 906 "./src/parser/parser.am" if (code_string_equals(Amalgame_Compiler_Parser_Peek(self, 1LL)->Value, "{")) { return Amalgame_Compiler_Parser_ParseRegion(self); } } else { } } #line 909 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseExpr(self); } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseLoop(Amalgame_Compiler_Parser* self) { #line 921 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 922 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 923 "./src/parser/parser.am" Amalgame_Compiler_AstNode* body = Amalgame_Compiler_Parser_ParseBlock(self); #line 924 "./src/parser/parser.am" Amalgame_Compiler_AstNode* nb = Amalgame_Compiler_Ast_Block(body->Line, body->Column); #line 925 "./src/parser/parser.am" AmalgameList_add(nb->Children, (void*)(intptr_t)(Amalgame_Compiler_Ast_InlineC("amc_arena_reset();", tok->Line, tok->Column))); #line 926 "./src/parser/parser.am" i64 n = AmalgameList_count(body->Children); #line 927 "./src/parser/parser.am" for (i64 ci = 0LL; ci < n; ci++) { AmalgameList_add(nb->Children, (void*)(intptr_t)((Amalgame_Compiler_AstNode*)AmalgameList_get(body->Children, ci))); } #line 928 "./src/parser/parser.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_WHILE_STMT, tok->Line, tok->Column); #line 929 "./src/parser/parser.am" node->Cond = Amalgame_Compiler_Ast_BoolLit(1, tok->Line, tok->Column); #line 930 "./src/parser/parser.am" node->Body = nb; #line 931 "./src/parser/parser.am" return node; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseRegion(Amalgame_Compiler_Parser* self) { #line 939 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 940 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 941 "./src/parser/parser.am" Amalgame_Compiler_AstNode* body = Amalgame_Compiler_Parser_ParseBlock(self); #line 942 "./src/parser/parser.am" Amalgame_Compiler_AstNode* nb = Amalgame_Compiler_Ast_Block(body->Line, body->Column); #line 943 "./src/parser/parser.am" AmalgameList_add(nb->Children, (void*)(intptr_t)(Amalgame_Compiler_Ast_InlineC("amc_arena_push_mark();", tok->Line, tok->Column))); #line 944 "./src/parser/parser.am" i64 n = AmalgameList_count(body->Children); #line 945 "./src/parser/parser.am" for (i64 ci = 0LL; ci < n; ci++) { AmalgameList_add(nb->Children, (void*)(intptr_t)((Amalgame_Compiler_AstNode*)AmalgameList_get(body->Children, ci))); } #line 946 "./src/parser/parser.am" AmalgameList_add(nb->Children, (void*)(intptr_t)(Amalgame_Compiler_Ast_InlineC("amc_arena_pop_mark();", tok->Line, tok->Column))); #line 947 "./src/parser/parser.am" return nb; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseSetup(Amalgame_Compiler_Parser* self) { #line 952 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 953 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 954 "./src/parser/parser.am" Amalgame_Compiler_AstNode* body = Amalgame_Compiler_Parser_ParseBlock(self); #line 955 "./src/parser/parser.am" Amalgame_Compiler_AstNode* nb = Amalgame_Compiler_Ast_Block(body->Line, body->Column); #line 956 "./src/parser/parser.am" AmalgameList_add(nb->Children, (void*)(intptr_t)(Amalgame_Compiler_Ast_InlineC("amc_persist_begin();", tok->Line, tok->Column))); #line 957 "./src/parser/parser.am" i64 n = AmalgameList_count(body->Children); #line 958 "./src/parser/parser.am" for (i64 ci = 0LL; ci < n; ci++) { AmalgameList_add(nb->Children, (void*)(intptr_t)((Amalgame_Compiler_AstNode*)AmalgameList_get(body->Children, ci))); } #line 959 "./src/parser/parser.am" AmalgameList_add(nb->Children, (void*)(intptr_t)(Amalgame_Compiler_Ast_InlineC("amc_persist_end();", tok->Line, tok->Column))); #line 960 "./src/parser/parser.am" return nb; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseTry(Amalgame_Compiler_Parser* self) { #line 969 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 970 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 971 "./src/parser/parser.am" Amalgame_Compiler_AstNode* tryBlock = Amalgame_Compiler_Parser_ParseBlock(self); #line 972 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 973 "./src/parser/parser.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_TRY_STMT, tok->Line, tok->Column); #line 974 "./src/parser/parser.am" node->Body = tryBlock; #line 975 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "catch")) { #line 976 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 978 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 979 "./src/parser/parser.am" Amalgame_Compiler_Token* bind = Amalgame_Compiler_Parser_Advance(self); #line 980 "./src/parser/parser.am" node->Name = bind->Value; } #line 982 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 983 "./src/parser/parser.am" node->Else = Amalgame_Compiler_Parser_ParseBlock(self); #line 984 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 986 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "finally")) { #line 987 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 988 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 989 "./src/parser/parser.am" node->Cond = Amalgame_Compiler_Parser_ParseBlock(self); } #line 991 "./src/parser/parser.am" return node; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseThrow(Amalgame_Compiler_Parser* self) { #line 996 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 997 "./src/parser/parser.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_THROW_STMT, tok->Line, tok->Column); #line 998 "./src/parser/parser.am" if ((!Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_NEWLINE) && !Amalgame_Compiler_Parser_CheckValue(self, "}")) && !Amalgame_Compiler_Parser_IsEnd(self)) { #line 999 "./src/parser/parser.am" n->Left = Amalgame_Compiler_Parser_ParseExpr(self); } #line 1001 "./src/parser/parser.am" return n; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseInlineC(Amalgame_Compiler_Parser* self) { #line 1007 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1008 "./src/parser/parser.am" return Amalgame_Compiler_Ast_InlineC(tok->Value, tok->Line, tok->Column); } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseVarDecl(Amalgame_Compiler_Parser* self) { #line 1014 "./src/parser/parser.am" Amalgame_Compiler_Token* kwTok = Amalgame_Compiler_Parser_Advance(self); #line 1015 "./src/parser/parser.am" code_bool isMut = code_string_equals(kwTok->Value, "var"); #line 1018 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "(")) { #line 1019 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1020 "./src/parser/parser.am" AmalgameList* names = AmalgameList_new(); #line 1021 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, ")")) { #line 1022 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1023 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); continue; } #line 1024 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 1025 "./src/parser/parser.am" Amalgame_Compiler_Token* n = Amalgame_Compiler_Parser_Advance(self); #line 1026 "./src/parser/parser.am" AmalgameList_add(names, (void*)(intptr_t)(n->Value)); } } #line 1029 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ")")) { Amalgame_Compiler_Parser_Advance(self); } #line 1031 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "=")) { Amalgame_Compiler_Parser_Advance(self); } #line 1032 "./src/parser/parser.am" Amalgame_Compiler_AstNode* rhs = Amalgame_Compiler_Parser_ParseExpr(self); #line 1034 "./src/parser/parser.am" Amalgame_Compiler_AstNode* td = Amalgame_Compiler_Ast_VarDecl("__tuple__", isMut, kwTok->Line, kwTok->Column); #line 1035 "./src/parser/parser.am" td->Left = rhs; #line 1036 "./src/parser/parser.am" i64 nc = AmalgameList_count(names); #line 1037 "./src/parser/parser.am" for (i64 i = 0LL; i < nc; i++) { #line 1038 "./src/parser/parser.am" code_string vname = (code_string)AmalgameList_get(names, i); #line 1039 "./src/parser/parser.am" Amalgame_Compiler_AstNode* vnode = Amalgame_Compiler_Ast_Ident(vname, kwTok->Line, kwTok->Column); #line 1040 "./src/parser/parser.am" AmalgameList_add(td->Children, (void*)(intptr_t)(vnode)); } #line 1042 "./src/parser/parser.am" td->Str = "__tuple_destructure__"; #line 1043 "./src/parser/parser.am" return td; } #line 1046 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 1047 "./src/parser/parser.am" Amalgame_Compiler_AstNode* decl = Amalgame_Compiler_Ast_VarDecl(nameTok->Value, isMut, nameTok->Line, nameTok->Column); #line 1048 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ":")) { #line 1049 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1050 "./src/parser/parser.am" decl->Str = Amalgame_Compiler_Parser_ParseTypeName(self); } #line 1052 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "=")) { #line 1053 "./src/parser/parser.am" Amalgame_Compiler_Token* eqTok = Amalgame_Compiler_Parser_Advance(self); #line 1064 "./src/parser/parser.am" if ((Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_NEWLINE) || Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_RBRACE)) || Amalgame_Compiler_Parser_IsEnd(self)) { #line 1065 "./src/parser/parser.am" AmalgameList_add(self->Errors, (void*)(intptr_t)(code_string_concat((code_string_concat((code_string_concat("Expected expression after '=' at ", String_FromInt(eqTok->Line))), ":")), String_FromInt(eqTok->Column)))); #line 1066 "./src/parser/parser.am" decl->Left = Amalgame_Compiler_Parser_Unknown(self); } else { #line 1068 "./src/parser/parser.am" decl->Left = Amalgame_Compiler_Parser_ParseExpr(self); } } #line 1071 "./src/parser/parser.am" return decl; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseReturn(Amalgame_Compiler_Parser* self) { #line 1077 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1078 "./src/parser/parser.am" if ((Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_NEWLINE) || Amalgame_Compiler_Parser_CheckValue(self, "}")) || Amalgame_Compiler_Parser_IsEnd(self)) { #line 1079 "./src/parser/parser.am" return Amalgame_Compiler_Ast_Return(Amalgame_Compiler_Parser_Unknown(self), tok->Line, tok->Column); } #line 1081 "./src/parser/parser.am" return Amalgame_Compiler_Ast_Return(Amalgame_Compiler_Parser_ParseExpr(self), tok->Line, tok->Column); } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseIf(Amalgame_Compiler_Parser* self) { #line 1087 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1088 "./src/parser/parser.am" code_bool hasParen = Amalgame_Compiler_Parser_CheckValue(self, "("); #line 1089 "./src/parser/parser.am" if (hasParen) { #line 1090 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1091 "./src/parser/parser.am" self->ParenDepth = (self->ParenDepth + 1LL); } #line 1093 "./src/parser/parser.am" Amalgame_Compiler_AstNode* cond = Amalgame_Compiler_Parser_ParseExpr(self); #line 1094 "./src/parser/parser.am" if (hasParen) { #line 1095 "./src/parser/parser.am" self->ParenDepth = (self->ParenDepth - 1LL); #line 1096 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ")"); } #line 1098 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1099 "./src/parser/parser.am" Amalgame_Compiler_AstNode* then = Amalgame_Compiler_Parser_ParseBlock(self); #line 1100 "./src/parser/parser.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_Ast_If(cond, then, tok->Line, tok->Column); #line 1101 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1102 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "else")) { #line 1103 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1104 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1105 "./src/parser/parser.am" node->Flag = 1; #line 1106 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "if")) { #line 1107 "./src/parser/parser.am" node->Else = Amalgame_Compiler_Parser_ParseIf(self); } else { #line 1109 "./src/parser/parser.am" node->Else = Amalgame_Compiler_Parser_ParseBlock(self); } } #line 1112 "./src/parser/parser.am" return node; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseGuard(Amalgame_Compiler_Parser* self) { #line 1122 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1123 "./src/parser/parser.am" code_bool hasParen = Amalgame_Compiler_Parser_CheckValue(self, "("); #line 1124 "./src/parser/parser.am" if (hasParen) { #line 1125 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1126 "./src/parser/parser.am" self->ParenDepth = (self->ParenDepth + 1LL); } #line 1128 "./src/parser/parser.am" Amalgame_Compiler_AstNode* cond = Amalgame_Compiler_Parser_ParseExpr(self); #line 1129 "./src/parser/parser.am" if (hasParen) { #line 1130 "./src/parser/parser.am" self->ParenDepth = (self->ParenDepth - 1LL); #line 1131 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ")"); } #line 1133 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1135 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "else")) { #line 1136 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } #line 1138 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1139 "./src/parser/parser.am" Amalgame_Compiler_AstNode* body = Amalgame_Compiler_Parser_ParseBlock(self); #line 1141 "./src/parser/parser.am" Amalgame_Compiler_AstNode* neg = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_UNARY, tok->Line, tok->Column); #line 1142 "./src/parser/parser.am" neg->Str = "!"; #line 1143 "./src/parser/parser.am" neg->Left = cond; #line 1145 "./src/parser/parser.am" return Amalgame_Compiler_Ast_If(neg, body, tok->Line, tok->Column); } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseWhile(Amalgame_Compiler_Parser* self) { #line 1151 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1152 "./src/parser/parser.am" code_bool hasParen = Amalgame_Compiler_Parser_CheckValue(self, "("); #line 1153 "./src/parser/parser.am" if (hasParen) { #line 1154 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1155 "./src/parser/parser.am" self->ParenDepth = (self->ParenDepth + 1LL); } #line 1157 "./src/parser/parser.am" Amalgame_Compiler_AstNode* cond = Amalgame_Compiler_Parser_ParseExpr(self); #line 1158 "./src/parser/parser.am" if (hasParen) { #line 1159 "./src/parser/parser.am" self->ParenDepth = (self->ParenDepth - 1LL); #line 1160 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ")"); } #line 1162 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1163 "./src/parser/parser.am" Amalgame_Compiler_AstNode* body = Amalgame_Compiler_Parser_ParseBlock(self); #line 1164 "./src/parser/parser.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_WHILE_STMT, tok->Line, tok->Column); #line 1165 "./src/parser/parser.am" node->Cond = cond; #line 1166 "./src/parser/parser.am" node->Body = body; #line 1167 "./src/parser/parser.am" return node; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseForIn(Amalgame_Compiler_Parser* self) { #line 1173 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1174 "./src/parser/parser.am" Amalgame_Compiler_Token* varTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 1175 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "in"); #line 1176 "./src/parser/parser.am" Amalgame_Compiler_AstNode* iter = Amalgame_Compiler_Parser_ParseExpr(self); #line 1177 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1178 "./src/parser/parser.am" Amalgame_Compiler_AstNode* body = Amalgame_Compiler_Parser_ParseBlock(self); #line 1179 "./src/parser/parser.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_FOR_IN_STMT, tok->Line, tok->Column); #line 1180 "./src/parser/parser.am" node->Name = varTok->Value; #line 1181 "./src/parser/parser.am" node->Left = iter; #line 1182 "./src/parser/parser.am" node->Body = body; #line 1183 "./src/parser/parser.am" return node; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseEnum(Amalgame_Compiler_Parser* self, code_bool isPublic) { #line 1189 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1190 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 1191 "./src/parser/parser.am" Amalgame_Compiler_AstNode* en = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_ENUM_DECL, tok->Line, tok->Column); #line 1192 "./src/parser/parser.am" en->Name = nameTok->Value; #line 1193 "./src/parser/parser.am" en->Flag = isPublic; #line 1194 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1195 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "{"); #line 1196 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1197 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, "}")) { #line 1198 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_NEWLINE)) { Amalgame_Compiler_Parser_Advance(self); continue; } #line 1199 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); continue; } #line 1200 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { Amalgame_Compiler_Parser_Advance(self); continue; } #line 1201 "./src/parser/parser.am" Amalgame_Compiler_Token* memberTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 1202 "./src/parser/parser.am" Amalgame_Compiler_AstNode* member = Amalgame_Compiler_Ast_Ident(memberTok->Value, memberTok->Line, memberTok->Column); #line 1204 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "(")) { #line 1205 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1206 "./src/parser/parser.am" code_string typeList = ""; #line 1207 "./src/parser/parser.am" i64 typeCount = 0LL; #line 1208 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, ")")) { #line 1209 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); continue; } #line 1210 "./src/parser/parser.am" code_string tname = Amalgame_Compiler_Parser_ParseTypeName(self); #line 1211 "./src/parser/parser.am" if (typeCount > 0LL) { typeList = (code_string_concat(typeList, ",")); } #line 1212 "./src/parser/parser.am" typeList = (code_string_concat(typeList, tname)); #line 1213 "./src/parser/parser.am" typeCount = (typeCount + 1LL); } #line 1215 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ")"); #line 1216 "./src/parser/parser.am" member->Str = typeList; } #line 1218 "./src/parser/parser.am" AmalgameList_add(en->Children, (void*)(intptr_t)(member)); #line 1219 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 1221 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "}"); #line 1222 "./src/parser/parser.am" return en; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseInterface(Amalgame_Compiler_Parser* self, code_bool isPublic) { #line 1228 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1229 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 1230 "./src/parser/parser.am" Amalgame_Compiler_AstNode* iface = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_CLASS_DECL, tok->Line, tok->Column); #line 1231 "./src/parser/parser.am" iface->Name = nameTok->Value; #line 1232 "./src/parser/parser.am" iface->Flag = isPublic; #line 1233 "./src/parser/parser.am" iface->Flag2 = 1; #line 1235 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "<")) { #line 1236 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1237 "./src/parser/parser.am" code_string gparams = ""; #line 1238 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, ">")) { #line 1239 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); continue; } #line 1240 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 1241 "./src/parser/parser.am" Amalgame_Compiler_Token* pTok = Amalgame_Compiler_Parser_Advance(self); #line 1242 "./src/parser/parser.am" if (String_Length(gparams) > 0LL) { gparams = (code_string_concat(gparams, ",")); } #line 1243 "./src/parser/parser.am" gparams = (code_string_concat(gparams, pTok->Value)); } else { #line 1245 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } } #line 1248 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ">")) { Amalgame_Compiler_Parser_Advance(self); } #line 1249 "./src/parser/parser.am" iface->Str3 = gparams; } #line 1251 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1252 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "{"); #line 1253 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1254 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, "}")) { #line 1255 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1256 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "}")) { break; } #line 1260 "./src/parser/parser.am" code_string typeName = "void"; #line 1261 "./src/parser/parser.am" code_string methodName = "_unknown_"; #line 1262 "./src/parser/parser.am" i64 mline = Amalgame_Compiler_Parser_Current(self)->Line; #line 1263 "./src/parser/parser.am" i64 mcol = Amalgame_Compiler_Parser_Current(self)->Column; #line 1265 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 1266 "./src/parser/parser.am" Amalgame_Compiler_Token* peek1 = Amalgame_Compiler_Parser_Peek(self, 1LL); #line 1267 "./src/parser/parser.am" if (code_string_equals(peek1->Value, "(")) { #line 1269 "./src/parser/parser.am" Amalgame_Compiler_Token* mnameTok2 = Amalgame_Compiler_Parser_ExpectIdent(self); #line 1270 "./src/parser/parser.am" methodName = mnameTok2->Value; #line 1271 "./src/parser/parser.am" mline = mnameTok2->Line; #line 1272 "./src/parser/parser.am" mcol = mnameTok2->Column; } else { #line 1275 "./src/parser/parser.am" typeName = Amalgame_Compiler_Parser_ParseTypeName(self); #line 1276 "./src/parser/parser.am" Amalgame_Compiler_Token* mnameTok3 = Amalgame_Compiler_Parser_ExpectIdent(self); #line 1277 "./src/parser/parser.am" methodName = mnameTok3->Value; #line 1278 "./src/parser/parser.am" mline = mnameTok3->Line; #line 1279 "./src/parser/parser.am" mcol = mnameTok3->Column; } } #line 1282 "./src/parser/parser.am" Amalgame_Compiler_AstNode* m = Amalgame_Compiler_Ast_Method(methodName, typeName, mline, mcol); #line 1283 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "("); #line 1284 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, ")")) { #line 1285 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); } #line 1286 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ")")) { break; } #line 1289 "./src/parser/parser.am" i64 beforePos = self->Pos; #line 1290 "./src/parser/parser.am" Amalgame_Compiler_AstNode* p = Amalgame_Compiler_Parser_ParseParam(self); #line 1291 "./src/parser/parser.am" if (self->Pos == beforePos) { #line 1292 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } #line 1294 "./src/parser/parser.am" AmalgameList_add(m->Params, (void*)(intptr_t)(p)); } #line 1296 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ")"); #line 1298 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "->")) { #line 1299 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1300 "./src/parser/parser.am" code_string retType2 = Amalgame_Compiler_Parser_ParseTypeName(self); #line 1301 "./src/parser/parser.am" m->Str = retType2; } #line 1303 "./src/parser/parser.am" AmalgameList_add(iface->Children, (void*)(intptr_t)(m)); #line 1304 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 1306 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "}"); #line 1307 "./src/parser/parser.am" return iface; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseExpr(Amalgame_Compiler_Parser* self) { #line 1314 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER) && (code_string_equals(Amalgame_Compiler_Parser_Peek(self, 1LL)->Value, "=>"))) { #line 1315 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseLambdaSingle(self); } #line 1321 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "(") && Amalgame_Compiler_Parser_IsLambdaParenStart(self)) { #line 1322 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseLambdaMulti(self); } #line 1324 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseAssign(self); } static code_bool Amalgame_Compiler_Parser_IsLambdaParenStart(Amalgame_Compiler_Parser* self) { #line 1340 "./src/parser/parser.am" i64 i = 1LL; #line 1342 "./src/parser/parser.am" if (code_string_equals(Amalgame_Compiler_Parser_Peek(self, i)->Value, ")")) { #line 1343 "./src/parser/parser.am" return code_string_equals(Amalgame_Compiler_Parser_Peek(self, i + 1LL)->Value, "=>"); } #line 1346 "./src/parser/parser.am" while (1) { #line 1347 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_Peek(self, i)->Type != Amalgame_Compiler_TokenType_IDENTIFIER) { return 0; } #line 1348 "./src/parser/parser.am" i = (i + 1LL); #line 1354 "./src/parser/parser.am" if (code_string_equals(Amalgame_Compiler_Parser_Peek(self, i)->Value, ":")) { #line 1355 "./src/parser/parser.am" i = (i + 1LL); #line 1356 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_Peek(self, i)->Type != Amalgame_Compiler_TokenType_IDENTIFIER) { #line 1357 "./src/parser/parser.am" code_string v = Amalgame_Compiler_Parser_Peek(self, i)->Value; #line 1358 "./src/parser/parser.am" code_bool isKw = ((((code_string_equals(v, "int")) || (code_string_equals(v, "string"))) || (code_string_equals(v, "bool"))) || (code_string_equals(v, "void"))) || (code_string_equals(v, "float")); #line 1359 "./src/parser/parser.am" if (!isKw) { return 0; } } #line 1361 "./src/parser/parser.am" i = (i + 1LL); #line 1363 "./src/parser/parser.am" if (code_string_equals(Amalgame_Compiler_Parser_Peek(self, i)->Value, "<")) { #line 1364 "./src/parser/parser.am" i64 depth = 1LL; #line 1365 "./src/parser/parser.am" i = (i + 1LL); #line 1366 "./src/parser/parser.am" while ((depth > 0LL) && (Amalgame_Compiler_Parser_Peek(self, i)->Type != Amalgame_Compiler_TokenType_EOF)) { #line 1367 "./src/parser/parser.am" code_string v2 = Amalgame_Compiler_Parser_Peek(self, i)->Value; #line 1368 "./src/parser/parser.am" if (code_string_equals(v2, ">>")) { #line 1371 "./src/parser/parser.am" depth = (depth - 2LL); #line 1372 "./src/parser/parser.am" if (depth < 0LL) { depth = 0LL; } } else { #line 1374 "./src/parser/parser.am" if (code_string_equals(v2, "<")) { depth = (depth + 1LL); } #line 1375 "./src/parser/parser.am" if (code_string_equals(v2, ">")) { depth = (depth - 1LL); } } #line 1377 "./src/parser/parser.am" i = (i + 1LL); } } #line 1381 "./src/parser/parser.am" if (code_string_equals(Amalgame_Compiler_Parser_Peek(self, i)->Value, "[")) { #line 1382 "./src/parser/parser.am" if (code_string_equals(Amalgame_Compiler_Parser_Peek(self, i + 1LL)->Value, "]")) { i = (i + 2LL); } } #line 1385 "./src/parser/parser.am" if (code_string_equals(Amalgame_Compiler_Parser_Peek(self, i)->Value, "?")) { i = (i + 1LL); } } #line 1387 "./src/parser/parser.am" if (code_string_equals(Amalgame_Compiler_Parser_Peek(self, i)->Value, ")")) { #line 1388 "./src/parser/parser.am" return code_string_equals(Amalgame_Compiler_Parser_Peek(self, i + 1LL)->Value, "=>"); } #line 1390 "./src/parser/parser.am" if (!code_string_equals(Amalgame_Compiler_Parser_Peek(self, i)->Value, ",")) { return 0; } #line 1391 "./src/parser/parser.am" i = (i + 1LL); } #line 1393 "./src/parser/parser.am" return 0; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseLambdaSingle(Amalgame_Compiler_Parser* self) { #line 1397 "./src/parser/parser.am" Amalgame_Compiler_Token* paramTok = Amalgame_Compiler_Parser_Advance(self); #line 1398 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1399 "./src/parser/parser.am" Amalgame_Compiler_AstNode* lam = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_METHOD_DECL, paramTok->Line, paramTok->Column); #line 1400 "./src/parser/parser.am" lam->Name = "__lambda__"; #line 1401 "./src/parser/parser.am" Amalgame_Compiler_AstNode* p = Amalgame_Compiler_Ast_Param(paramTok->Value, "?", paramTok->Line, paramTok->Column); #line 1402 "./src/parser/parser.am" AmalgameList_add(lam->Params, (void*)(intptr_t)(p)); #line 1403 "./src/parser/parser.am" Amalgame_Compiler_Parser_ParseLambdaBody(self, lam); #line 1404 "./src/parser/parser.am" return lam; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseLambdaMulti(Amalgame_Compiler_Parser* self) { #line 1408 "./src/parser/parser.am" Amalgame_Compiler_Token* openTok = Amalgame_Compiler_Parser_Advance(self); #line 1409 "./src/parser/parser.am" Amalgame_Compiler_AstNode* lam = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_METHOD_DECL, openTok->Line, openTok->Column); #line 1410 "./src/parser/parser.am" lam->Name = "__lambda__"; #line 1411 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, ")")) { #line 1412 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); continue; } #line 1413 "./src/parser/parser.am" Amalgame_Compiler_Token* pTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 1419 "./src/parser/parser.am" code_string pType = "?"; #line 1420 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ":")) { #line 1421 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1422 "./src/parser/parser.am" pType = Amalgame_Compiler_Parser_ParseTypeName(self); } #line 1424 "./src/parser/parser.am" Amalgame_Compiler_AstNode* p = Amalgame_Compiler_Ast_Param(pTok->Value, pType, pTok->Line, pTok->Column); #line 1425 "./src/parser/parser.am" AmalgameList_add(lam->Params, (void*)(intptr_t)(p)); } #line 1427 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ")"); #line 1428 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1429 "./src/parser/parser.am" Amalgame_Compiler_Parser_ParseLambdaBody(self, lam); #line 1430 "./src/parser/parser.am" return lam; } static void Amalgame_Compiler_Parser_ParseLambdaBody(Amalgame_Compiler_Parser* self, Amalgame_Compiler_AstNode* lam) { #line 1437 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "{")) { #line 1438 "./src/parser/parser.am" lam->Body = Amalgame_Compiler_Parser_ParseBlock(self); } else { #line 1440 "./src/parser/parser.am" lam->Left = Amalgame_Compiler_Parser_ParseExpr(self); } } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseAssign(Amalgame_Compiler_Parser* self) { #line 1445 "./src/parser/parser.am" Amalgame_Compiler_AstNode* left = Amalgame_Compiler_Parser_ParseTernary(self); #line 1446 "./src/parser/parser.am" code_bool isAssign = ((((Amalgame_Compiler_Parser_CheckValue(self, "=") || Amalgame_Compiler_Parser_CheckValue(self, "+=")) || Amalgame_Compiler_Parser_CheckValue(self, "-=")) || Amalgame_Compiler_Parser_CheckValue(self, "*=")) || Amalgame_Compiler_Parser_CheckValue(self, "/=")) || Amalgame_Compiler_Parser_CheckValue(self, "%="); #line 1447 "./src/parser/parser.am" code_bool isBitAssign = (((Amalgame_Compiler_Parser_CheckValue(self, "&=") || Amalgame_Compiler_Parser_CheckValue(self, "|=")) || Amalgame_Compiler_Parser_CheckValue(self, "^=")) || Amalgame_Compiler_Parser_CheckValue(self, "<<=")) || Amalgame_Compiler_Parser_CheckValue(self, ">>="); #line 1448 "./src/parser/parser.am" if (isAssign || isBitAssign) { #line 1449 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1455 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1456 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParseAssign(self); #line 1457 "./src/parser/parser.am" return Amalgame_Compiler_Ast_Binary(left, tok->Value, right, tok->Line, tok->Column); } #line 1459 "./src/parser/parser.am" return left; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseTernary(Amalgame_Compiler_Parser* self) { #line 1479 "./src/parser/parser.am" Amalgame_Compiler_AstNode* cond = Amalgame_Compiler_Parser_ParseRange(self); #line 1480 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_CheckValue(self, "?")) { return cond; } #line 1481 "./src/parser/parser.am" Amalgame_Compiler_Token* q = Amalgame_Compiler_Parser_Advance(self); #line 1482 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1483 "./src/parser/parser.am" Amalgame_Compiler_AstNode* thenExpr = Amalgame_Compiler_Parser_ParseAssign(self); #line 1484 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1485 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ":"); #line 1486 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1487 "./src/parser/parser.am" Amalgame_Compiler_AstNode* elseExpr = Amalgame_Compiler_Parser_ParseAssign(self); #line 1488 "./src/parser/parser.am" Amalgame_Compiler_AstNode* thenBlk = Amalgame_Compiler_Ast_Block(thenExpr->Line, thenExpr->Column); #line 1489 "./src/parser/parser.am" AmalgameList_add(thenBlk->Children, (void*)(intptr_t)(thenExpr)); #line 1490 "./src/parser/parser.am" Amalgame_Compiler_AstNode* elseBlk = Amalgame_Compiler_Ast_Block(elseExpr->Line, elseExpr->Column); #line 1491 "./src/parser/parser.am" AmalgameList_add(elseBlk->Children, (void*)(intptr_t)(elseExpr)); #line 1492 "./src/parser/parser.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_Ast_If(cond, thenBlk, q->Line, q->Column); #line 1493 "./src/parser/parser.am" node->Flag = 1; #line 1494 "./src/parser/parser.am" node->Else = elseBlk; #line 1495 "./src/parser/parser.am" return node; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseRange(Amalgame_Compiler_Parser* self) { #line 1515 "./src/parser/parser.am" Amalgame_Compiler_AstNode* left = Amalgame_Compiler_Parser_ParseOr(self); #line 1516 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "..")) { #line 1517 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1518 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParseOr(self); #line 1519 "./src/parser/parser.am" return Amalgame_Compiler_Ast_Binary(left, "..", right, tok->Line, tok->Column); } #line 1521 "./src/parser/parser.am" return left; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseOr(Amalgame_Compiler_Parser* self) { #line 1525 "./src/parser/parser.am" Amalgame_Compiler_AstNode* left = Amalgame_Compiler_Parser_ParseBitwiseOr(self); #line 1526 "./src/parser/parser.am" while (1) { #line 1531 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_NEWLINE)) { #line 1532 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_LookaheadAfterNewlinesIs(self, "||", "", "")) { break; } #line 1533 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 1535 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_CheckValue(self, "||")) { break; } #line 1536 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1537 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1538 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParseBitwiseOr(self); #line 1539 "./src/parser/parser.am" left = Amalgame_Compiler_Ast_Binary(left, "||", right, tok->Line, tok->Column); } #line 1541 "./src/parser/parser.am" return left; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseBitwiseOr(Amalgame_Compiler_Parser* self) { #line 1545 "./src/parser/parser.am" Amalgame_Compiler_AstNode* left = Amalgame_Compiler_Parser_ParseBitwiseXor(self); #line 1546 "./src/parser/parser.am" while (Amalgame_Compiler_Parser_CheckValue(self, "|") && !Amalgame_Compiler_Parser_CheckValue(self, "||")) { #line 1547 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1548 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParseBitwiseXor(self); #line 1549 "./src/parser/parser.am" left = Amalgame_Compiler_Ast_Binary(left, "|", right, tok->Line, tok->Column); } #line 1551 "./src/parser/parser.am" return left; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseBitwiseXor(Amalgame_Compiler_Parser* self) { #line 1555 "./src/parser/parser.am" Amalgame_Compiler_AstNode* left = Amalgame_Compiler_Parser_ParseBitwiseAnd(self); #line 1556 "./src/parser/parser.am" while (Amalgame_Compiler_Parser_CheckValue(self, "^")) { #line 1557 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1558 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParseBitwiseAnd(self); #line 1559 "./src/parser/parser.am" left = Amalgame_Compiler_Ast_Binary(left, "^", right, tok->Line, tok->Column); } #line 1561 "./src/parser/parser.am" return left; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseBitwiseAnd(Amalgame_Compiler_Parser* self) { #line 1565 "./src/parser/parser.am" Amalgame_Compiler_AstNode* left = Amalgame_Compiler_Parser_ParseAnd(self); #line 1566 "./src/parser/parser.am" while (Amalgame_Compiler_Parser_CheckValue(self, "&") && !Amalgame_Compiler_Parser_CheckValue(self, "&&")) { #line 1567 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1568 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParseAnd(self); #line 1569 "./src/parser/parser.am" left = Amalgame_Compiler_Ast_Binary(left, "&", right, tok->Line, tok->Column); } #line 1571 "./src/parser/parser.am" return left; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseAnd(Amalgame_Compiler_Parser* self) { #line 1575 "./src/parser/parser.am" Amalgame_Compiler_AstNode* left = Amalgame_Compiler_Parser_ParseEquality(self); #line 1576 "./src/parser/parser.am" while (1) { #line 1582 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_NEWLINE)) { #line 1583 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_LookaheadAfterNewlinesIs(self, "&&", "", "")) { break; } #line 1584 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 1586 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_CheckValue(self, "&&")) { break; } #line 1587 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1588 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1589 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParseEquality(self); #line 1590 "./src/parser/parser.am" left = Amalgame_Compiler_Ast_Binary(left, "&&", right, tok->Line, tok->Column); } #line 1592 "./src/parser/parser.am" return left; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseEquality(Amalgame_Compiler_Parser* self) { #line 1596 "./src/parser/parser.am" Amalgame_Compiler_AstNode* left = Amalgame_Compiler_Parser_ParseRelational(self); #line 1597 "./src/parser/parser.am" while (Amalgame_Compiler_Parser_CheckValue(self, "==") || Amalgame_Compiler_Parser_CheckValue(self, "!=")) { #line 1598 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1599 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParseRelational(self); #line 1600 "./src/parser/parser.am" left = Amalgame_Compiler_Ast_Binary(left, tok->Value, right, tok->Line, tok->Column); } #line 1602 "./src/parser/parser.am" return left; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseRelational(Amalgame_Compiler_Parser* self) { #line 1611 "./src/parser/parser.am" Amalgame_Compiler_AstNode* left = Amalgame_Compiler_Parser_ParseShift(self); #line 1612 "./src/parser/parser.am" while (((Amalgame_Compiler_Parser_CheckValue(self, "<") || Amalgame_Compiler_Parser_CheckValue(self, ">")) || Amalgame_Compiler_Parser_CheckValue(self, "<=")) || Amalgame_Compiler_Parser_CheckValue(self, ">=")) { #line 1613 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1614 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParseShift(self); #line 1615 "./src/parser/parser.am" left = Amalgame_Compiler_Ast_Binary(left, tok->Value, right, tok->Line, tok->Column); } #line 1617 "./src/parser/parser.am" return left; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseShift(Amalgame_Compiler_Parser* self) { #line 1621 "./src/parser/parser.am" Amalgame_Compiler_AstNode* left = Amalgame_Compiler_Parser_ParseAdd(self); #line 1622 "./src/parser/parser.am" while (Amalgame_Compiler_Parser_CheckValue(self, "<<") || Amalgame_Compiler_Parser_CheckValue(self, ">>")) { #line 1623 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1624 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParseAdd(self); #line 1625 "./src/parser/parser.am" left = Amalgame_Compiler_Ast_Binary(left, tok->Value, right, tok->Line, tok->Column); } #line 1627 "./src/parser/parser.am" return left; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseAdd(Amalgame_Compiler_Parser* self) { #line 1631 "./src/parser/parser.am" Amalgame_Compiler_AstNode* left = Amalgame_Compiler_Parser_ParseMul(self); #line 1632 "./src/parser/parser.am" while (1) { #line 1637 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_NEWLINE)) { #line 1638 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_LookaheadAfterNewlinesIs(self, "+", "-", "")) { break; } #line 1639 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 1641 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_CheckValue(self, "+") && !Amalgame_Compiler_Parser_CheckValue(self, "-")) { break; } #line 1642 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1643 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1644 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParseMul(self); #line 1645 "./src/parser/parser.am" left = Amalgame_Compiler_Ast_Binary(left, tok->Value, right, tok->Line, tok->Column); } #line 1647 "./src/parser/parser.am" return left; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMul(Amalgame_Compiler_Parser* self) { #line 1651 "./src/parser/parser.am" Amalgame_Compiler_AstNode* left = Amalgame_Compiler_Parser_ParseUnary(self); #line 1652 "./src/parser/parser.am" while (1) { #line 1653 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_NEWLINE)) { #line 1654 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_LookaheadAfterNewlinesIs(self, "*", "/", "%")) { break; } #line 1655 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 1657 "./src/parser/parser.am" if ((!Amalgame_Compiler_Parser_CheckValue(self, "*") && !Amalgame_Compiler_Parser_CheckValue(self, "/")) && !Amalgame_Compiler_Parser_CheckValue(self, "%")) { break; } #line 1658 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1659 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1660 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParseUnary(self); #line 1661 "./src/parser/parser.am" left = Amalgame_Compiler_Ast_Binary(left, tok->Value, right, tok->Line, tok->Column); } #line 1663 "./src/parser/parser.am" return left; } static code_bool Amalgame_Compiler_Parser_LookaheadAfterNewlinesIs(Amalgame_Compiler_Parser* self, code_string s1, code_string s2, code_string s3) { #line 1670 "./src/parser/parser.am" i64 off = 0LL; #line 1671 "./src/parser/parser.am" i64 max = self->TokenCount; #line 1672 "./src/parser/parser.am" while ((self->Pos + off) < max) { #line 1673 "./src/parser/parser.am" Amalgame_Compiler_Token* t = (Amalgame_Compiler_Token*)AmalgameList_get(self->Tokens, self->Pos + off); #line 1674 "./src/parser/parser.am" if (t->Type == Amalgame_Compiler_TokenType_NEWLINE) { #line 1675 "./src/parser/parser.am" off = (off + 1LL); #line 1676 "./src/parser/parser.am" continue; } #line 1678 "./src/parser/parser.am" code_string v = t->Value; #line 1679 "./src/parser/parser.am" return ((code_string_equals(v, s1)) || (code_string_equals(v, s2))) || (code_string_equals(v, s3)); } #line 1681 "./src/parser/parser.am" return 0; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseUnary(Amalgame_Compiler_Parser* self) { #line 1686 "./src/parser/parser.am" code_bool isUnaryNot = Amalgame_Compiler_Parser_CheckValue(self, "!") && !Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_STRING); #line 1687 "./src/parser/parser.am" code_bool isUnaryMinus = Amalgame_Compiler_Parser_CheckValue(self, "-") && !Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_STRING); #line 1688 "./src/parser/parser.am" code_bool isUnaryTilde = Amalgame_Compiler_Parser_CheckValue(self, "~") && !Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_STRING); #line 1689 "./src/parser/parser.am" if ((isUnaryNot || isUnaryMinus) || isUnaryTilde) { #line 1690 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1691 "./src/parser/parser.am" Amalgame_Compiler_AstNode* operand = Amalgame_Compiler_Parser_ParseUnary(self); #line 1692 "./src/parser/parser.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_UNARY, tok->Line, tok->Column); #line 1693 "./src/parser/parser.am" node->Str = tok->Value; #line 1694 "./src/parser/parser.am" node->Left = operand; #line 1695 "./src/parser/parser.am" return node; } #line 1704 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "await") && !Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_STRING)) { #line 1705 "./src/parser/parser.am" Amalgame_Compiler_Token* nx = Amalgame_Compiler_Parser_Peek(self, 1LL); #line 1706 "./src/parser/parser.am" code_string nv = nx->Value; #line 1707 "./src/parser/parser.am" code_bool blocks = (((((((code_string_equals(nv, ")")) || (code_string_equals(nv, ","))) || (code_string_equals(nv, "]"))) || (code_string_equals(nv, "}"))) || (code_string_equals(nv, "="))) || (code_string_equals(nv, ";"))) || (code_string_equals(nv, ""))) || (nx->Type == Amalgame_Compiler_TokenType_NEWLINE); #line 1709 "./src/parser/parser.am" if (!blocks) { #line 1710 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1711 "./src/parser/parser.am" Amalgame_Compiler_AstNode* operand = Amalgame_Compiler_Parser_ParseUnary(self); #line 1712 "./src/parser/parser.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_UNARY, tok->Line, tok->Column); #line 1713 "./src/parser/parser.am" node->Str = "await"; #line 1714 "./src/parser/parser.am" node->Left = operand; #line 1715 "./src/parser/parser.am" return node; } } #line 1718 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParsePostfix(self); } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParsePostfix(Amalgame_Compiler_Parser* self) { #line 1722 "./src/parser/parser.am" Amalgame_Compiler_AstNode* expr = Amalgame_Compiler_Parser_ParsePrimary(self); #line 1723 "./src/parser/parser.am" code_bool running = 1; #line 1724 "./src/parser/parser.am" while (running) { #line 1734 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_NEWLINE) && Amalgame_Compiler_Parser_LookaheadStartsWithDot(self)) { #line 1735 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 1737 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ".")) { #line 1738 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1739 "./src/parser/parser.am" Amalgame_Compiler_Token* memberTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 1740 "./src/parser/parser.am" expr = Amalgame_Compiler_Ast_Member(expr, memberTok->Value, tok->Line, tok->Column); #line 1741 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "(")) { #line 1742 "./src/parser/parser.am" expr = Amalgame_Compiler_Parser_ParseCallArgs(self, expr); } } else if (Amalgame_Compiler_Parser_CheckValue(self, "?.")) { #line 1747 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1748 "./src/parser/parser.am" Amalgame_Compiler_Token* memberTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 1749 "./src/parser/parser.am" Amalgame_Compiler_AstNode* m = Amalgame_Compiler_Ast_Member(expr, memberTok->Value, tok->Line, tok->Column); #line 1750 "./src/parser/parser.am" m->Flag = 1; #line 1751 "./src/parser/parser.am" expr = m; #line 1752 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "(")) { #line 1753 "./src/parser/parser.am" expr = Amalgame_Compiler_Parser_ParseCallArgs(self, expr); } } else if (Amalgame_Compiler_Parser_CheckValue(self, "(")) { #line 1756 "./src/parser/parser.am" expr = Amalgame_Compiler_Parser_ParseCallArgs(self, expr); } else if (Amalgame_Compiler_Parser_CheckValue(self, "[")) { #line 1758 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1759 "./src/parser/parser.am" Amalgame_Compiler_AstNode* idx = Amalgame_Compiler_Parser_ParseExpr(self); #line 1760 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "]"); #line 1761 "./src/parser/parser.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_INDEX_EXPR, tok->Line, tok->Column); #line 1762 "./src/parser/parser.am" node->Left = expr; #line 1763 "./src/parser/parser.am" node->Right = idx; #line 1764 "./src/parser/parser.am" expr = node; } else { #line 1766 "./src/parser/parser.am" running = 0; } } #line 1769 "./src/parser/parser.am" return expr; } static code_bool Amalgame_Compiler_Parser_LookaheadStartsWithDot(Amalgame_Compiler_Parser* self) { #line 1776 "./src/parser/parser.am" i64 off = 0LL; #line 1777 "./src/parser/parser.am" i64 max = self->TokenCount; #line 1778 "./src/parser/parser.am" while ((self->Pos + off) < max) { #line 1779 "./src/parser/parser.am" Amalgame_Compiler_Token* t = (Amalgame_Compiler_Token*)AmalgameList_get(self->Tokens, self->Pos + off); #line 1780 "./src/parser/parser.am" if (t->Type == Amalgame_Compiler_TokenType_NEWLINE) { #line 1781 "./src/parser/parser.am" off = (off + 1LL); #line 1782 "./src/parser/parser.am" continue; } #line 1784 "./src/parser/parser.am" if ((code_string_equals(t->Value, ".")) || (code_string_equals(t->Value, "?."))) { return 1; } #line 1785 "./src/parser/parser.am" return 0; } #line 1787 "./src/parser/parser.am" return 0; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseCallArgs(Amalgame_Compiler_Parser* self, Amalgame_Compiler_AstNode* callee) { #line 1791 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Expect(self, "("); #line 1792 "./src/parser/parser.am" Amalgame_Compiler_AstNode* call = Amalgame_Compiler_Ast_Call(callee, tok->Line, tok->Column); #line 1793 "./src/parser/parser.am" self->ParenDepth = (self->ParenDepth + 1LL); #line 1794 "./src/parser/parser.am" i64 myDepth = self->ParenDepth; #line 1795 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1796 "./src/parser/parser.am" i64 callLastPos = 0LL; #line 1797 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self)) { #line 1798 "./src/parser/parser.am" i64 callPos = self->Pos; #line 1799 "./src/parser/parser.am" if ((callPos == callLastPos) && (callLastPos > 0LL)) { #line 1800 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1801 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_IsEnd(self)) { break; } } #line 1803 "./src/parser/parser.am" callLastPos = self->Pos; #line 1805 "./src/parser/parser.am" code_bool isRparen = Amalgame_Compiler_Parser_CheckValue(self, ")") && !Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_STRING); #line 1806 "./src/parser/parser.am" if (isRparen && (self->ParenDepth == myDepth)) { break; } #line 1808 "./src/parser/parser.am" code_bool isComma = Amalgame_Compiler_Parser_CheckValue(self, ",") && !Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_STRING); #line 1809 "./src/parser/parser.am" if (isComma) { #line 1810 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1811 "./src/parser/parser.am" continue; } #line 1813 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1814 "./src/parser/parser.am" code_bool isRparen2 = Amalgame_Compiler_Parser_CheckValue(self, ")") && !Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_STRING); #line 1815 "./src/parser/parser.am" if (isRparen2 && (self->ParenDepth == myDepth)) { break; } #line 1816 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_IsEnd(self)) { break; } #line 1821 "./src/parser/parser.am" code_string namedKey = ""; #line 1822 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 1823 "./src/parser/parser.am" Amalgame_Compiler_Token* peek = Amalgame_Compiler_Parser_Peek(self, 1LL); #line 1824 "./src/parser/parser.am" if (code_string_equals(peek->Value, ":")) { #line 1825 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_Advance(self); #line 1826 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1827 "./src/parser/parser.am" namedKey = nameTok->Value; } } #line 1834 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_OP_SPREAD)) { #line 1835 "./src/parser/parser.am" Amalgame_Compiler_Token* sptok = Amalgame_Compiler_Parser_Advance(self); #line 1836 "./src/parser/parser.am" Amalgame_Compiler_AstNode* inner = Amalgame_Compiler_Parser_ParseExpr(self); #line 1837 "./src/parser/parser.am" Amalgame_Compiler_AstNode* sn = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_UNARY, sptok->Line, sptok->Column); #line 1838 "./src/parser/parser.am" sn->Str = "..."; #line 1839 "./src/parser/parser.am" sn->Left = inner; #line 1840 "./src/parser/parser.am" if (String_Length(namedKey) > 0LL) { sn->Str2 = namedKey; } #line 1841 "./src/parser/parser.am" AmalgameList_add(call->Args, (void*)(intptr_t)(sn)); #line 1842 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1843 "./src/parser/parser.am" continue; } #line 1845 "./src/parser/parser.am" Amalgame_Compiler_AstNode* arg = Amalgame_Compiler_Parser_ParseExpr(self); #line 1846 "./src/parser/parser.am" if (String_Length(namedKey) > 0LL) { arg->Str2 = namedKey; } #line 1847 "./src/parser/parser.am" AmalgameList_add(call->Args, (void*)(intptr_t)(arg)); #line 1848 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 1850 "./src/parser/parser.am" self->ParenDepth = (self->ParenDepth - 1LL); #line 1851 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ")"); #line 1852 "./src/parser/parser.am" return call; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParsePrimary(Amalgame_Compiler_Parser* self) { #line 1856 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Current(self); #line 1857 "./src/parser/parser.am" code_string v = tok->Value; #line 1859 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_INTEGER)) { #line 1860 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1864 "./src/parser/parser.am" return Amalgame_Compiler_Ast_IntLit(v, tok->Line, tok->Column); } #line 1866 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_FLOAT)) { #line 1867 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1868 "./src/parser/parser.am" return Amalgame_Compiler_Ast_FloatLit(v, tok->Line, tok->Column); } #line 1870 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_STRING)) { #line 1871 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1872 "./src/parser/parser.am" return Amalgame_Compiler_Ast_StrLit(v, tok->Line, tok->Column); } #line 1874 "./src/parser/parser.am" if (code_string_equals(v, "true")) { #line 1875 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1876 "./src/parser/parser.am" return Amalgame_Compiler_Ast_BoolLit(1, tok->Line, tok->Column); } #line 1878 "./src/parser/parser.am" if (code_string_equals(v, "false")) { #line 1879 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1880 "./src/parser/parser.am" return Amalgame_Compiler_Ast_BoolLit(0, tok->Line, tok->Column); } #line 1882 "./src/parser/parser.am" if (code_string_equals(v, "null")) { #line 1883 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1884 "./src/parser/parser.am" return Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_LITERAL_NULL, tok->Line, tok->Column); } #line 1886 "./src/parser/parser.am" if (code_string_equals(v, "this")) { #line 1887 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1888 "./src/parser/parser.am" return Amalgame_Compiler_Ast_This(tok->Line, tok->Column); } #line 1890 "./src/parser/parser.am" if (code_string_equals(v, "new")) { #line 1891 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseNew(self); } #line 1894 "./src/parser/parser.am" if (code_string_equals(v, "if")) { #line 1895 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseIf(self); } #line 1898 "./src/parser/parser.am" if (code_string_equals(v, "match")) { #line 1899 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseMatch(self); } #line 1901 "./src/parser/parser.am" if (code_string_equals(v, "(")) { #line 1902 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1903 "./src/parser/parser.am" self->ParenDepth = (self->ParenDepth + 1LL); #line 1904 "./src/parser/parser.am" Amalgame_Compiler_AstNode* first2 = Amalgame_Compiler_Parser_ParseExpr(self); #line 1906 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { #line 1908 "./src/parser/parser.am" Amalgame_Compiler_AstNode* tupleNode = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_CALL, tok->Line, tok->Column); #line 1909 "./src/parser/parser.am" tupleNode->Name = "__tuple_literal__"; #line 1910 "./src/parser/parser.am" AmalgameList_add(tupleNode->Args, (void*)(intptr_t)(first2)); #line 1911 "./src/parser/parser.am" while (Amalgame_Compiler_Parser_CheckValue(self, ",")) { #line 1912 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1913 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ")")) { break; } #line 1914 "./src/parser/parser.am" Amalgame_Compiler_AstNode* elem = Amalgame_Compiler_Parser_ParseExpr(self); #line 1915 "./src/parser/parser.am" AmalgameList_add(tupleNode->Args, (void*)(intptr_t)(elem)); } #line 1917 "./src/parser/parser.am" self->ParenDepth = (self->ParenDepth - 1LL); #line 1918 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ")"); #line 1919 "./src/parser/parser.am" return tupleNode; } #line 1921 "./src/parser/parser.am" self->ParenDepth = (self->ParenDepth - 1LL); #line 1922 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ")"); #line 1923 "./src/parser/parser.am" return first2; } #line 1925 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 1926 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1928 "./src/parser/parser.am" return Amalgame_Compiler_Ast_Ident(v, tok->Line, tok->Column); } #line 1931 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "[")) { #line 1932 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseListComp(self); } #line 1935 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1936 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Unknown(self); } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseListItem(Amalgame_Compiler_Parser* self) { #line 1951 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_OP_SPREAD)) { #line 1952 "./src/parser/parser.am" Amalgame_Compiler_Token* sptok = Amalgame_Compiler_Parser_Advance(self); #line 1953 "./src/parser/parser.am" Amalgame_Compiler_AstNode* inner = Amalgame_Compiler_Parser_ParseExpr(self); #line 1954 "./src/parser/parser.am" Amalgame_Compiler_AstNode* n = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_UNARY, sptok->Line, sptok->Column); #line 1955 "./src/parser/parser.am" n->Str = "..."; #line 1956 "./src/parser/parser.am" n->Left = inner; #line 1957 "./src/parser/parser.am" return n; } #line 1959 "./src/parser/parser.am" return Amalgame_Compiler_Parser_ParseExpr(self); } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseListComp(Amalgame_Compiler_Parser* self) { #line 1963 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 1964 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1966 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "]")) { #line 1967 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1968 "./src/parser/parser.am" return Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_LIST_LITERAL, tok->Line, tok->Column); } #line 1970 "./src/parser/parser.am" Amalgame_Compiler_AstNode* firstExpr = Amalgame_Compiler_Parser_ParseListItem(self); #line 1971 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1973 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "for")) { #line 1974 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1975 "./src/parser/parser.am" Amalgame_Compiler_Token* varTok = Amalgame_Compiler_Parser_ExpectIdent(self); #line 1976 "./src/parser/parser.am" if (!Amalgame_Compiler_Parser_CheckKw(self, "in")) { #line 1977 "./src/parser/parser.am" AmalgameList_add(self->Errors, (void*)(intptr_t)(code_string_concat((code_string_concat((code_string_concat("Expected 'in' in list comprehension at ", String_FromInt(varTok->Line))), ":")), String_FromInt(varTok->Column)))); } else { #line 1979 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } #line 1981 "./src/parser/parser.am" Amalgame_Compiler_AstNode* iter = Amalgame_Compiler_Parser_ParseExpr(self); #line 1982 "./src/parser/parser.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_LIST_COMP, tok->Line, tok->Column); #line 1983 "./src/parser/parser.am" node->Left = firstExpr; #line 1984 "./src/parser/parser.am" node->Str = varTok->Value; #line 1985 "./src/parser/parser.am" node->Right = iter; #line 1986 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 1987 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckKw(self, "if")) { #line 1988 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 1989 "./src/parser/parser.am" node->Cond = Amalgame_Compiler_Parser_ParseExpr(self); #line 1990 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 1992 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "]"); #line 1993 "./src/parser/parser.am" return node; } #line 1996 "./src/parser/parser.am" Amalgame_Compiler_AstNode* lit = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_LIST_LITERAL, tok->Line, tok->Column); #line 1997 "./src/parser/parser.am" AmalgameList_add(lit->Children, (void*)(intptr_t)(firstExpr)); #line 1998 "./src/parser/parser.am" while (Amalgame_Compiler_Parser_CheckValue(self, ",")) { #line 1999 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 2000 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 2001 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "]")) { break; } #line 2002 "./src/parser/parser.am" AmalgameList_add(lit->Children, (void*)(intptr_t)(Amalgame_Compiler_Parser_ParseListItem(self))); #line 2003 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 2005 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "]"); #line 2006 "./src/parser/parser.am" return lit; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMatch(Amalgame_Compiler_Parser* self) { #line 2016 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Advance(self); #line 2017 "./src/parser/parser.am" Amalgame_Compiler_AstNode* subject = Amalgame_Compiler_Parser_ParseExpr(self); #line 2018 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 2019 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "{"); #line 2020 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 2021 "./src/parser/parser.am" Amalgame_Compiler_AstNode* matchNode = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_IF_STMT, tok->Line, tok->Column); #line 2022 "./src/parser/parser.am" matchNode->Left = subject; #line 2023 "./src/parser/parser.am" matchNode->Name = "__match__"; #line 2025 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, "}")) { #line 2026 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 2027 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "}")) { break; } #line 2028 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); continue; } #line 2030 "./src/parser/parser.am" Amalgame_Compiler_AstNode* patNode = Amalgame_Compiler_Parser_ParseMatchPattern(self); #line 2031 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 2033 "./src/parser/parser.am" code_bool hasGuard = Amalgame_Compiler_Parser_CheckKw(self, "if"); #line 2034 "./src/parser/parser.am" Amalgame_Compiler_AstNode* arm = Amalgame_Compiler_Ast_Binary(patNode, "=>", patNode, tok->Line, tok->Column); #line 2035 "./src/parser/parser.am" if (hasGuard) { #line 2036 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 2037 "./src/parser/parser.am" arm->Cond = Amalgame_Compiler_Parser_ParseExpr(self); #line 2038 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 2041 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "=>")) { Amalgame_Compiler_Parser_Advance(self); } #line 2042 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 2046 "./src/parser/parser.am" Amalgame_Compiler_AstNode* armBody = Amalgame_Compiler_Parser_ParseStmt(self); #line 2048 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); } #line 2049 "./src/parser/parser.am" arm->Right = armBody; #line 2050 "./src/parser/parser.am" AmalgameList_add(matchNode->Children, (void*)(intptr_t)(arm)); #line 2051 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 2053 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, "}"); #line 2054 "./src/parser/parser.am" return matchNode; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseMatchPattern(Amalgame_Compiler_Parser* self) { #line 2058 "./src/parser/parser.am" Amalgame_Compiler_Token* tok = Amalgame_Compiler_Parser_Current(self); #line 2060 "./src/parser/parser.am" if (code_string_equals(tok->Value, "_")) { #line 2061 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 2062 "./src/parser/parser.am" Amalgame_Compiler_AstNode* wc = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_IDENTIFIER, tok->Line, tok->Column); #line 2063 "./src/parser/parser.am" wc->Name = "_"; #line 2064 "./src/parser/parser.am" return wc; } #line 2071 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_STRING)) { #line 2072 "./src/parser/parser.am" Amalgame_Compiler_Token* s = Amalgame_Compiler_Parser_Advance(self); #line 2073 "./src/parser/parser.am" return Amalgame_Compiler_Ast_StrLit(s->Value, s->Line, s->Column); } #line 2076 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_INTEGER)) { #line 2077 "./src/parser/parser.am" Amalgame_Compiler_Token* num = Amalgame_Compiler_Parser_Advance(self); #line 2078 "./src/parser/parser.am" Amalgame_Compiler_AstNode* lit = Amalgame_Compiler_Ast_IntLit(num->Value, num->Line, num->Column); #line 2079 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "..")) { #line 2080 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 2081 "./src/parser/parser.am" Amalgame_Compiler_AstNode* right = Amalgame_Compiler_Parser_ParsePrimary(self); #line 2082 "./src/parser/parser.am" return Amalgame_Compiler_Ast_Binary(lit, "..", right, num->Line, num->Column); } #line 2084 "./src/parser/parser.am" return lit; } #line 2087 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 2088 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_Advance(self); #line 2089 "./src/parser/parser.am" Amalgame_Compiler_AstNode* patIdent = Amalgame_Compiler_Ast_Ident(nameTok->Value, nameTok->Line, nameTok->Column); #line 2091 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ".")) { #line 2092 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 2093 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 2094 "./src/parser/parser.am" Amalgame_Compiler_Token* memberTok = Amalgame_Compiler_Parser_Advance(self); #line 2095 "./src/parser/parser.am" patIdent = Amalgame_Compiler_Ast_Member(patIdent, memberTok->Value, nameTok->Line, nameTok->Column); } } #line 2099 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "(")) { #line 2100 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 2101 "./src/parser/parser.am" Amalgame_Compiler_AstNode* captures = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_CALL, nameTok->Line, nameTok->Column); #line 2102 "./src/parser/parser.am" captures->Name = nameTok->Value; #line 2103 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, ")")) { #line 2104 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { Amalgame_Compiler_Parser_Advance(self); continue; } #line 2105 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 2106 "./src/parser/parser.am" Amalgame_Compiler_Token* cap = Amalgame_Compiler_Parser_Advance(self); #line 2107 "./src/parser/parser.am" Amalgame_Compiler_AstNode* capNode = Amalgame_Compiler_Ast_Ident(cap->Value, cap->Line, cap->Column); #line 2108 "./src/parser/parser.am" AmalgameList_add(captures->Args, (void*)(intptr_t)(capNode)); } else { #line 2109 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } } #line 2111 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ")"); #line 2112 "./src/parser/parser.am" return captures; } #line 2114 "./src/parser/parser.am" return patIdent; } #line 2116 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 2117 "./src/parser/parser.am" return Amalgame_Compiler_Parser_Unknown(self); } static Amalgame_Compiler_AstNode* Amalgame_Compiler_Parser_ParseNew(Amalgame_Compiler_Parser* self) { #line 2121 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 2122 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_Current(self); #line 2123 "./src/parser/parser.am" code_string typeName = Amalgame_Compiler_Parser_ParseQualifiedName(self); #line 2127 "./src/parser/parser.am" code_string generic = ""; #line 2128 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "<")) { #line 2129 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 2130 "./src/parser/parser.am" i64 depth = 1LL; #line 2131 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && (depth > 0LL)) { #line 2132 "./src/parser/parser.am" Amalgame_Compiler_Token* inner = Amalgame_Compiler_Parser_Current(self); #line 2133 "./src/parser/parser.am" code_string iv = inner->Value; #line 2134 "./src/parser/parser.am" if (code_string_equals(iv, ">>")) { #line 2140 "./src/parser/parser.am" if (depth >= 3LL) { #line 2141 "./src/parser/parser.am" generic = (code_string_concat(generic, ">>")); #line 2142 "./src/parser/parser.am" depth = (depth - 2LL); } else if (depth == 2LL) { #line 2144 "./src/parser/parser.am" generic = (code_string_concat(generic, ">")); #line 2145 "./src/parser/parser.am" depth = 0LL; } else { #line 2147 "./src/parser/parser.am" depth = 0LL; } #line 2149 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } else { #line 2151 "./src/parser/parser.am" if (code_string_equals(iv, "<")) { depth = (depth + 1LL); } #line 2152 "./src/parser/parser.am" if (code_string_equals(iv, ">")) { depth = (depth - 1LL); } #line 2153 "./src/parser/parser.am" if (depth > 0LL) { generic = (code_string_concat(generic, iv)); } #line 2154 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); } } } #line 2158 "./src/parser/parser.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_Ast_NewExpr(typeName, nameTok->Line, nameTok->Column); #line 2159 "./src/parser/parser.am" if (String_Length(generic) > 0LL) { node->Str2 = generic; } #line 2160 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, "(")) { #line 2161 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 2162 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 2163 "./src/parser/parser.am" while (!Amalgame_Compiler_Parser_IsEnd(self) && !Amalgame_Compiler_Parser_CheckValue(self, ")")) { #line 2164 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckValue(self, ",")) { #line 2165 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 2166 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 2167 "./src/parser/parser.am" continue; } #line 2171 "./src/parser/parser.am" code_string namedKey = ""; #line 2172 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_IDENTIFIER)) { #line 2173 "./src/parser/parser.am" Amalgame_Compiler_Token* peek = Amalgame_Compiler_Parser_Peek(self, 1LL); #line 2174 "./src/parser/parser.am" if (code_string_equals(peek->Value, ":")) { #line 2175 "./src/parser/parser.am" Amalgame_Compiler_Token* nameTok = Amalgame_Compiler_Parser_Advance(self); #line 2176 "./src/parser/parser.am" Amalgame_Compiler_Parser_Advance(self); #line 2177 "./src/parser/parser.am" namedKey = nameTok->Value; } } #line 2183 "./src/parser/parser.am" if (Amalgame_Compiler_Parser_CheckType(self, Amalgame_Compiler_TokenType_OP_SPREAD)) { #line 2184 "./src/parser/parser.am" Amalgame_Compiler_Token* sptok = Amalgame_Compiler_Parser_Advance(self); #line 2185 "./src/parser/parser.am" Amalgame_Compiler_AstNode* inner = Amalgame_Compiler_Parser_ParseExpr(self); #line 2186 "./src/parser/parser.am" Amalgame_Compiler_AstNode* sn = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_UNARY, sptok->Line, sptok->Column); #line 2187 "./src/parser/parser.am" sn->Str = "..."; #line 2188 "./src/parser/parser.am" sn->Left = inner; #line 2189 "./src/parser/parser.am" if (String_Length(namedKey) > 0LL) { sn->Str2 = namedKey; } #line 2190 "./src/parser/parser.am" AmalgameList_add(node->Args, (void*)(intptr_t)(sn)); #line 2191 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); #line 2192 "./src/parser/parser.am" continue; } #line 2194 "./src/parser/parser.am" Amalgame_Compiler_AstNode* arg = Amalgame_Compiler_Parser_ParseExpr(self); #line 2195 "./src/parser/parser.am" if (String_Length(namedKey) > 0LL) { arg->Str2 = namedKey; } #line 2196 "./src/parser/parser.am" AmalgameList_add(node->Args, (void*)(intptr_t)(arg)); #line 2197 "./src/parser/parser.am" Amalgame_Compiler_Parser_SkipNewlines(self); } #line 2199 "./src/parser/parser.am" Amalgame_Compiler_Parser_Expect(self, ")"); } #line 2201 "./src/parser/parser.am" return node; } enum _Amalgame_Compiler_TomlKind { Amalgame_Compiler_TomlKind_Null, Amalgame_Compiler_TomlKind_Bool, Amalgame_Compiler_TomlKind_Int, Amalgame_Compiler_TomlKind_String, Amalgame_Compiler_TomlKind_Array, Amalgame_Compiler_TomlKind_Table }; struct _Amalgame_Compiler_TomlValue { Amalgame_Compiler_TomlKind Kind; code_bool B; i64 I; code_string S; AmalgameList* Items; AmalgameList* TableKeys; AmalgameList* TableVals; }; code_bool Amalgame_Compiler_TomlValue_IsNull(Amalgame_Compiler_TomlValue* self); code_bool Amalgame_Compiler_TomlValue_IsBool(Amalgame_Compiler_TomlValue* self); code_bool Amalgame_Compiler_TomlValue_IsInt(Amalgame_Compiler_TomlValue* self); code_bool Amalgame_Compiler_TomlValue_IsString(Amalgame_Compiler_TomlValue* self); code_bool Amalgame_Compiler_TomlValue_IsArray(Amalgame_Compiler_TomlValue* self); code_bool Amalgame_Compiler_TomlValue_IsTable(Amalgame_Compiler_TomlValue* self); code_bool Amalgame_Compiler_TomlValue_AsBool(Amalgame_Compiler_TomlValue* self); i64 Amalgame_Compiler_TomlValue_AsInt(Amalgame_Compiler_TomlValue* self); code_string Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue* self); AmalgameList* Amalgame_Compiler_TomlValue_AsArray(Amalgame_Compiler_TomlValue* self); i64 Amalgame_Compiler_TomlValue_Count(Amalgame_Compiler_TomlValue* self); Amalgame_Compiler_TomlValue* Amalgame_Compiler_TomlValue_At(Amalgame_Compiler_TomlValue* self, i64 idx); Amalgame_Compiler_TomlValue* Amalgame_Compiler_TomlValue_Get(Amalgame_Compiler_TomlValue* self, code_string key); code_bool Amalgame_Compiler_TomlValue_Has(Amalgame_Compiler_TomlValue* self, code_string key); AmalgameList* Amalgame_Compiler_TomlValue_Keys(Amalgame_Compiler_TomlValue* self); void Amalgame_Compiler_TomlValue_SetBool(Amalgame_Compiler_TomlValue* self, code_bool v); void Amalgame_Compiler_TomlValue_SetInt(Amalgame_Compiler_TomlValue* self, i64 v); void Amalgame_Compiler_TomlValue_SetString(Amalgame_Compiler_TomlValue* self, code_string v); void Amalgame_Compiler_TomlValue_BecomeArray(Amalgame_Compiler_TomlValue* self); void Amalgame_Compiler_TomlValue_BecomeTable(Amalgame_Compiler_TomlValue* self); void Amalgame_Compiler_TomlValue_AppendItem(Amalgame_Compiler_TomlValue* self, Amalgame_Compiler_TomlValue* v); void Amalgame_Compiler_TomlValue_SetEntry(Amalgame_Compiler_TomlValue* self, code_string key, Amalgame_Compiler_TomlValue* v); Amalgame_Compiler_TomlValue* Amalgame_Compiler_TomlValue_new() { Amalgame_Compiler_TomlValue* self = (Amalgame_Compiler_TomlValue*) GC_MALLOC(sizeof(Amalgame_Compiler_TomlValue)); #line 67 "./src/stdlib/toml.am" self->Kind = Amalgame_Compiler_TomlKind_Null; #line 68 "./src/stdlib/toml.am" self->B = 0; #line 69 "./src/stdlib/toml.am" self->I = 0LL; #line 70 "./src/stdlib/toml.am" self->S = ""; #line 71 "./src/stdlib/toml.am" self->Items = AmalgameList_new(); #line 72 "./src/stdlib/toml.am" self->TableKeys = AmalgameList_new(); #line 73 "./src/stdlib/toml.am" self->TableVals = AmalgameList_new(); return self; } code_bool Amalgame_Compiler_TomlValue_IsNull(Amalgame_Compiler_TomlValue* self) { #line 77 "./src/stdlib/toml.am" return self->Kind == Amalgame_Compiler_TomlKind_Null; } code_bool Amalgame_Compiler_TomlValue_IsBool(Amalgame_Compiler_TomlValue* self) { #line 78 "./src/stdlib/toml.am" return self->Kind == Amalgame_Compiler_TomlKind_Bool; } code_bool Amalgame_Compiler_TomlValue_IsInt(Amalgame_Compiler_TomlValue* self) { #line 79 "./src/stdlib/toml.am" return self->Kind == Amalgame_Compiler_TomlKind_Int; } code_bool Amalgame_Compiler_TomlValue_IsString(Amalgame_Compiler_TomlValue* self) { #line 80 "./src/stdlib/toml.am" return self->Kind == Amalgame_Compiler_TomlKind_String; } code_bool Amalgame_Compiler_TomlValue_IsArray(Amalgame_Compiler_TomlValue* self) { #line 81 "./src/stdlib/toml.am" return self->Kind == Amalgame_Compiler_TomlKind_Array; } code_bool Amalgame_Compiler_TomlValue_IsTable(Amalgame_Compiler_TomlValue* self) { #line 82 "./src/stdlib/toml.am" return self->Kind == Amalgame_Compiler_TomlKind_Table; } code_bool Amalgame_Compiler_TomlValue_AsBool(Amalgame_Compiler_TomlValue* self) { #line 86 "./src/stdlib/toml.am" if (self->Kind == Amalgame_Compiler_TomlKind_Bool) { return self->B; } #line 87 "./src/stdlib/toml.am" return 0; } i64 Amalgame_Compiler_TomlValue_AsInt(Amalgame_Compiler_TomlValue* self) { #line 91 "./src/stdlib/toml.am" if (self->Kind == Amalgame_Compiler_TomlKind_Int) { return self->I; } #line 92 "./src/stdlib/toml.am" return 0LL; } code_string Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue* self) { #line 96 "./src/stdlib/toml.am" if (self->Kind == Amalgame_Compiler_TomlKind_String) { return self->S; } #line 97 "./src/stdlib/toml.am" return ""; } AmalgameList* Amalgame_Compiler_TomlValue_AsArray(Amalgame_Compiler_TomlValue* self) { #line 101 "./src/stdlib/toml.am" return self->Items; } i64 Amalgame_Compiler_TomlValue_Count(Amalgame_Compiler_TomlValue* self) { #line 106 "./src/stdlib/toml.am" if (self->Kind == Amalgame_Compiler_TomlKind_Array) { return AmalgameList_count(self->Items); } #line 107 "./src/stdlib/toml.am" if (self->Kind == Amalgame_Compiler_TomlKind_Table) { return AmalgameList_count(self->TableKeys); } #line 108 "./src/stdlib/toml.am" return 0LL; } Amalgame_Compiler_TomlValue* Amalgame_Compiler_TomlValue_At(Amalgame_Compiler_TomlValue* self, i64 idx) { #line 112 "./src/stdlib/toml.am" if (self->Kind != Amalgame_Compiler_TomlKind_Array) { return Amalgame_Compiler_TomlValue_new(); } #line 113 "./src/stdlib/toml.am" if ((idx < 0LL) || (idx >= AmalgameList_count(self->Items))) { return Amalgame_Compiler_TomlValue_new(); } #line 114 "./src/stdlib/toml.am" return (Amalgame_Compiler_TomlValue*)AmalgameList_get(self->Items, idx); } Amalgame_Compiler_TomlValue* Amalgame_Compiler_TomlValue_Get(Amalgame_Compiler_TomlValue* self, code_string key) { #line 124 "./src/stdlib/toml.am" if (self->Kind != Amalgame_Compiler_TomlKind_Table) { return Amalgame_Compiler_TomlValue_new(); } #line 125 "./src/stdlib/toml.am" i64 n = AmalgameList_count(self->TableKeys); #line 126 "./src/stdlib/toml.am" for (i64 i = 0LL; i < n; i++) { #line 127 "./src/stdlib/toml.am" if (code_string_equals((code_string)AmalgameList_get(self->TableKeys, i), key)) { #line 128 "./src/stdlib/toml.am" return (Amalgame_Compiler_TomlValue*)AmalgameList_get(self->TableVals, i); } } #line 131 "./src/stdlib/toml.am" return Amalgame_Compiler_TomlValue_new(); } code_bool Amalgame_Compiler_TomlValue_Has(Amalgame_Compiler_TomlValue* self, code_string key) { #line 135 "./src/stdlib/toml.am" if (self->Kind != Amalgame_Compiler_TomlKind_Table) { return 0; } #line 136 "./src/stdlib/toml.am" i64 n = AmalgameList_count(self->TableKeys); #line 137 "./src/stdlib/toml.am" for (i64 i = 0LL; i < n; i++) { #line 138 "./src/stdlib/toml.am" if (code_string_equals((code_string)AmalgameList_get(self->TableKeys, i), key)) { return 1; } } #line 140 "./src/stdlib/toml.am" return 0; } AmalgameList* Amalgame_Compiler_TomlValue_Keys(Amalgame_Compiler_TomlValue* self) { #line 144 "./src/stdlib/toml.am" return self->TableKeys; } void Amalgame_Compiler_TomlValue_SetBool(Amalgame_Compiler_TomlValue* self, code_bool v) { #line 148 "./src/stdlib/toml.am" self->Kind = Amalgame_Compiler_TomlKind_Bool; self->B = v; } void Amalgame_Compiler_TomlValue_SetInt(Amalgame_Compiler_TomlValue* self, i64 v) { #line 149 "./src/stdlib/toml.am" self->Kind = Amalgame_Compiler_TomlKind_Int; self->I = v; } void Amalgame_Compiler_TomlValue_SetString(Amalgame_Compiler_TomlValue* self, code_string v) { #line 150 "./src/stdlib/toml.am" self->Kind = Amalgame_Compiler_TomlKind_String; self->S = v; } void Amalgame_Compiler_TomlValue_BecomeArray(Amalgame_Compiler_TomlValue* self) { #line 151 "./src/stdlib/toml.am" self->Kind = Amalgame_Compiler_TomlKind_Array; } void Amalgame_Compiler_TomlValue_BecomeTable(Amalgame_Compiler_TomlValue* self) { #line 152 "./src/stdlib/toml.am" self->Kind = Amalgame_Compiler_TomlKind_Table; } void Amalgame_Compiler_TomlValue_AppendItem(Amalgame_Compiler_TomlValue* self, Amalgame_Compiler_TomlValue* v) { #line 155 "./src/stdlib/toml.am" if (self->Kind != Amalgame_Compiler_TomlKind_Array) { Amalgame_Compiler_TomlValue_BecomeArray(self); } #line 156 "./src/stdlib/toml.am" AmalgameList_add(self->Items, (void*)(intptr_t)(v)); } void Amalgame_Compiler_TomlValue_SetEntry(Amalgame_Compiler_TomlValue* self, code_string key, Amalgame_Compiler_TomlValue* v) { #line 165 "./src/stdlib/toml.am" if (self->Kind != Amalgame_Compiler_TomlKind_Table) { Amalgame_Compiler_TomlValue_BecomeTable(self); } #line 166 "./src/stdlib/toml.am" i64 n = AmalgameList_count(self->TableKeys); #line 167 "./src/stdlib/toml.am" for (i64 i = 0LL; i < n; i++) { #line 168 "./src/stdlib/toml.am" if (code_string_equals((code_string)AmalgameList_get(self->TableKeys, i), key)) { #line 169 "./src/stdlib/toml.am" AmalgameList_set(self->TableVals, i, (void*)(intptr_t)(v)); #line 170 "./src/stdlib/toml.am" return; } } #line 173 "./src/stdlib/toml.am" AmalgameList_add(self->TableKeys, (void*)(intptr_t)(key)); #line 174 "./src/stdlib/toml.am" AmalgameList_add(self->TableVals, (void*)(intptr_t)(v)); } struct _Amalgame_Compiler_TomlParser { code_string Src; i64 Pos; i64 Len; code_bool HasError; code_string ErrMsg; }; void Amalgame_Compiler_TomlParser_Fail(Amalgame_Compiler_TomlParser* self, code_string msg); code_bool Amalgame_Compiler_TomlParser_AtEnd(Amalgame_Compiler_TomlParser* self); code_string Amalgame_Compiler_TomlParser_Peek(Amalgame_Compiler_TomlParser* self); code_string Amalgame_Compiler_TomlParser_PeekAt(Amalgame_Compiler_TomlParser* self, i64 offset); code_string Amalgame_Compiler_TomlParser_Advance(Amalgame_Compiler_TomlParser* self); void Amalgame_Compiler_TomlParser_SkipInlineSpace(Amalgame_Compiler_TomlParser* self); void Amalgame_Compiler_TomlParser_SkipBlankLines(Amalgame_Compiler_TomlParser* self); static code_bool Amalgame_Compiler_TomlParser_IsBareKeyChar(Amalgame_Compiler_TomlParser* self, code_string c); static code_bool Amalgame_Compiler_TomlParser_IsDigit(Amalgame_Compiler_TomlParser* self, code_string c); code_string Amalgame_Compiler_TomlParser_ReadKey(Amalgame_Compiler_TomlParser* self); code_string Amalgame_Compiler_TomlParser_ReadStringLiteral(Amalgame_Compiler_TomlParser* self); Amalgame_Compiler_TomlParser* Amalgame_Compiler_TomlParser_new(code_string src) { Amalgame_Compiler_TomlParser* self = (Amalgame_Compiler_TomlParser*) GC_MALLOC(sizeof(Amalgame_Compiler_TomlParser)); #line 190 "./src/stdlib/toml.am" self->Src = src; #line 191 "./src/stdlib/toml.am" self->Pos = 0LL; #line 192 "./src/stdlib/toml.am" self->Len = String_Length(src); #line 193 "./src/stdlib/toml.am" self->HasError = 0; #line 194 "./src/stdlib/toml.am" self->ErrMsg = ""; return self; } void Amalgame_Compiler_TomlParser_Fail(Amalgame_Compiler_TomlParser* self, code_string msg) { #line 200 "./src/stdlib/toml.am" if (!self->HasError) { #line 201 "./src/stdlib/toml.am" self->HasError = 1; #line 202 "./src/stdlib/toml.am" self->ErrMsg = msg; } } code_bool Amalgame_Compiler_TomlParser_AtEnd(Amalgame_Compiler_TomlParser* self) { #line 207 "./src/stdlib/toml.am" return self->Pos >= self->Len; } code_string Amalgame_Compiler_TomlParser_Peek(Amalgame_Compiler_TomlParser* self) { #line 211 "./src/stdlib/toml.am" if (Amalgame_Compiler_TomlParser_AtEnd(self)) { return ""; } #line 212 "./src/stdlib/toml.am" return String_CharAt1(self->Src, self->Pos); } code_string Amalgame_Compiler_TomlParser_PeekAt(Amalgame_Compiler_TomlParser* self, i64 offset) { #line 216 "./src/stdlib/toml.am" i64 p = self->Pos + offset; #line 217 "./src/stdlib/toml.am" if ((p < 0LL) || (p >= self->Len)) { return ""; } #line 218 "./src/stdlib/toml.am" return String_CharAt1(self->Src, p); } code_string Amalgame_Compiler_TomlParser_Advance(Amalgame_Compiler_TomlParser* self) { #line 222 "./src/stdlib/toml.am" code_string c = Amalgame_Compiler_TomlParser_Peek(self); #line 223 "./src/stdlib/toml.am" self->Pos = (self->Pos + 1LL); #line 224 "./src/stdlib/toml.am" return c; } void Amalgame_Compiler_TomlParser_SkipInlineSpace(Amalgame_Compiler_TomlParser* self) { #line 231 "./src/stdlib/toml.am" while (!Amalgame_Compiler_TomlParser_AtEnd(self)) { #line 232 "./src/stdlib/toml.am" code_string c = Amalgame_Compiler_TomlParser_Peek(self); #line 233 "./src/stdlib/toml.am" if ((code_string_equals(c, " ")) || (code_string_equals(c, "\t"))) { #line 234 "./src/stdlib/toml.am" self->Pos = (self->Pos + 1LL); } else if (code_string_equals(c, "#")) { #line 237 "./src/stdlib/toml.am" while (!Amalgame_Compiler_TomlParser_AtEnd(self) && (!code_string_equals(Amalgame_Compiler_TomlParser_Peek(self), "\n"))) { #line 238 "./src/stdlib/toml.am" self->Pos = (self->Pos + 1LL); } } else { #line 241 "./src/stdlib/toml.am" return; } } } void Amalgame_Compiler_TomlParser_SkipBlankLines(Amalgame_Compiler_TomlParser* self) { #line 249 "./src/stdlib/toml.am" while (!Amalgame_Compiler_TomlParser_AtEnd(self)) { #line 250 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(self); #line 251 "./src/stdlib/toml.am" if (Amalgame_Compiler_TomlParser_AtEnd(self)) { return; } #line 252 "./src/stdlib/toml.am" code_string c = Amalgame_Compiler_TomlParser_Peek(self); #line 253 "./src/stdlib/toml.am" if (code_string_equals(c, "\n")) { #line 254 "./src/stdlib/toml.am" self->Pos = (self->Pos + 1LL); } else if (code_string_equals(c, "\r")) { #line 256 "./src/stdlib/toml.am" self->Pos = (self->Pos + 1LL); #line 257 "./src/stdlib/toml.am" if (!Amalgame_Compiler_TomlParser_AtEnd(self) && (code_string_equals(Amalgame_Compiler_TomlParser_Peek(self), "\n"))) { self->Pos = (self->Pos + 1LL); } } else { #line 259 "./src/stdlib/toml.am" return; } } } static code_bool Amalgame_Compiler_TomlParser_IsBareKeyChar(Amalgame_Compiler_TomlParser* self, code_string c) { #line 268 "./src/stdlib/toml.am" if (code_string_equals(c, "_")) { return 1; } #line 269 "./src/stdlib/toml.am" if (code_string_equals(c, "-")) { return 1; } #line 270 "./src/stdlib/toml.am" if (String_IndexOf("0123456789", c) >= 0LL) { return 1; } #line 271 "./src/stdlib/toml.am" if (String_IndexOf("abcdefghijklmnopqrstuvwxyz", c) >= 0LL) { return 1; } #line 272 "./src/stdlib/toml.am" if (String_IndexOf("ABCDEFGHIJKLMNOPQRSTUVWXYZ", c) >= 0LL) { return 1; } #line 273 "./src/stdlib/toml.am" return 0; } static code_bool Amalgame_Compiler_TomlParser_IsDigit(Amalgame_Compiler_TomlParser* self, code_string c) { #line 277 "./src/stdlib/toml.am" if (String_IndexOf("0123456789", c) >= 0LL) { return 1; } #line 278 "./src/stdlib/toml.am" return 0; } code_string Amalgame_Compiler_TomlParser_ReadKey(Amalgame_Compiler_TomlParser* self) { #line 284 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(self); #line 285 "./src/stdlib/toml.am" code_string first = Amalgame_Compiler_TomlParser_Peek(self); #line 286 "./src/stdlib/toml.am" if ((code_string_equals(first, "\"")) || (code_string_equals(first, "'"))) { #line 287 "./src/stdlib/toml.am" return Amalgame_Compiler_TomlParser_ReadStringLiteral(self); } #line 289 "./src/stdlib/toml.am" code_string name = ""; #line 290 "./src/stdlib/toml.am" while (!Amalgame_Compiler_TomlParser_AtEnd(self)) { #line 291 "./src/stdlib/toml.am" code_string c = Amalgame_Compiler_TomlParser_Peek(self); #line 292 "./src/stdlib/toml.am" if (Amalgame_Compiler_TomlParser_IsBareKeyChar(self, c)) { #line 293 "./src/stdlib/toml.am" name = (code_string_concat(name, c)); #line 294 "./src/stdlib/toml.am" self->Pos = (self->Pos + 1LL); } else { #line 296 "./src/stdlib/toml.am" break; } } #line 299 "./src/stdlib/toml.am" if (String_Length(name) == 0LL) { #line 300 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_Fail(self, "expected key"); } #line 302 "./src/stdlib/toml.am" return name; } code_string Amalgame_Compiler_TomlParser_ReadStringLiteral(Amalgame_Compiler_TomlParser* self) { #line 308 "./src/stdlib/toml.am" code_string quote = Amalgame_Compiler_TomlParser_Advance(self); #line 309 "./src/stdlib/toml.am" code_string out = ""; #line 310 "./src/stdlib/toml.am" code_bool literal = code_string_equals(quote, "'"); #line 311 "./src/stdlib/toml.am" while (!Amalgame_Compiler_TomlParser_AtEnd(self)) { #line 312 "./src/stdlib/toml.am" code_string c = Amalgame_Compiler_TomlParser_Peek(self); #line 313 "./src/stdlib/toml.am" if (code_string_equals(c, quote)) { #line 314 "./src/stdlib/toml.am" self->Pos = (self->Pos + 1LL); #line 315 "./src/stdlib/toml.am" return out; } #line 317 "./src/stdlib/toml.am" if (code_string_equals(c, "\n")) { #line 318 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_Fail(self, "newline inside single-line string"); #line 319 "./src/stdlib/toml.am" return out; } #line 321 "./src/stdlib/toml.am" if (literal) { #line 322 "./src/stdlib/toml.am" out = (code_string_concat(out, c)); #line 323 "./src/stdlib/toml.am" self->Pos = (self->Pos + 1LL); } else if (code_string_equals(c, "\\")) { #line 325 "./src/stdlib/toml.am" self->Pos = (self->Pos + 1LL); #line 326 "./src/stdlib/toml.am" code_string esc = Amalgame_Compiler_TomlParser_Peek(self); #line 327 "./src/stdlib/toml.am" self->Pos = (self->Pos + 1LL); #line 328 "./src/stdlib/toml.am" if (code_string_equals(esc, "n")) { out = (code_string_concat(out, "\n")); } else if (code_string_equals(esc, "t")) { #line 329 "./src/stdlib/toml.am" out = (code_string_concat(out, "\t")); } else if (code_string_equals(esc, "r")) { #line 330 "./src/stdlib/toml.am" out = (code_string_concat(out, "\r")); } else if (code_string_equals(esc, "\"")) { #line 331 "./src/stdlib/toml.am" out = (code_string_concat(out, "\"")); } else if (code_string_equals(esc, "'")) { #line 332 "./src/stdlib/toml.am" out = (code_string_concat(out, "'")); } else if (code_string_equals(esc, "\\")) { #line 333 "./src/stdlib/toml.am" out = (code_string_concat(out, "\\")); } else { #line 337 "./src/stdlib/toml.am" out = (code_string_concat(out, esc)); } } else { #line 340 "./src/stdlib/toml.am" out = (code_string_concat(out, c)); #line 341 "./src/stdlib/toml.am" self->Pos = (self->Pos + 1LL); } } #line 344 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_Fail(self, "unterminated string"); #line 345 "./src/stdlib/toml.am" return out; } struct _Amalgame_Compiler_Toml { }; Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_Parse(code_string source); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ParseWithError(code_string source, Amalgame_Compiler_TomlParser* parser); static Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_RunParse(Amalgame_Compiler_TomlParser* p, code_string source); AmalgameList* Amalgame_Compiler_Toml_ReadHeaderPath(Amalgame_Compiler_TomlParser* p); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_NavigateOrCreate(Amalgame_Compiler_TomlValue* root, AmalgameList* path); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_AppendArrayTable(Amalgame_Compiler_TomlValue* root, AmalgameList* path); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadValue(Amalgame_Compiler_TomlParser* p); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadArray(Amalgame_Compiler_TomlParser* p); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadInlineTable(Amalgame_Compiler_TomlParser* p); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadBool(Amalgame_Compiler_TomlParser* p); Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadInt(Amalgame_Compiler_TomlParser* p); void Amalgame_Compiler_Toml_SkipWsAndNewlines(Amalgame_Compiler_TomlParser* p); code_string Amalgame_Compiler_Toml_Serialize(Amalgame_Compiler_TomlValue* doc); static code_string Amalgame_Compiler_Toml_WriteTable(Amalgame_Compiler_TomlValue* t, AmalgameList* path, code_string out); static code_string Amalgame_Compiler_Toml_WriteValue(Amalgame_Compiler_TomlValue* v); static code_string Amalgame_Compiler_Toml_EscapeString(code_string s); static code_string Amalgame_Compiler_Toml_JoinPath(AmalgameList* path); Amalgame_Compiler_Toml* Amalgame_Compiler_Toml_new() { Amalgame_Compiler_Toml* self = (Amalgame_Compiler_Toml*) GC_MALLOC(sizeof(Amalgame_Compiler_Toml)); return self; } Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_Parse(code_string source) { #line 362 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser* p = Amalgame_Compiler_TomlParser_new(source); #line 363 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* res = Amalgame_Compiler_Toml_RunParse(p, source); #line 364 "./src/stdlib/toml.am" if (p->HasError) { return Amalgame_Compiler_TomlValue_new(); } #line 365 "./src/stdlib/toml.am" return res; } Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ParseWithError(code_string source, Amalgame_Compiler_TomlParser* parser) { #line 372 "./src/stdlib/toml.am" return Amalgame_Compiler_Toml_RunParse(parser, source); } static Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_RunParse(Amalgame_Compiler_TomlParser* p, code_string source) { #line 376 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* root = Amalgame_Compiler_TomlValue_new(); #line 377 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_BecomeTable(root); #line 378 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* current = root; #line 380 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipBlankLines(p); #line 381 "./src/stdlib/toml.am" while (!Amalgame_Compiler_TomlParser_AtEnd(p)) { #line 382 "./src/stdlib/toml.am" if (p->HasError) { break; } #line 383 "./src/stdlib/toml.am" code_string c = Amalgame_Compiler_TomlParser_Peek(p); #line 384 "./src/stdlib/toml.am" if (code_string_equals(c, "[")) { #line 390 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); #line 391 "./src/stdlib/toml.am" code_bool isArrayHeader = 0; #line 392 "./src/stdlib/toml.am" if (code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), "[")) { #line 393 "./src/stdlib/toml.am" isArrayHeader = 1; #line 394 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); } #line 396 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); #line 397 "./src/stdlib/toml.am" AmalgameList* path = Amalgame_Compiler_Toml_ReadHeaderPath(p); #line 398 "./src/stdlib/toml.am" if (AmalgameList_count(path) == 0LL) { Amalgame_Compiler_TomlParser_Fail(p, "empty table header"); } #line 399 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); #line 400 "./src/stdlib/toml.am" if (!code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), "]")) { Amalgame_Compiler_TomlParser_Fail(p, "expected ']' after table header"); } else { #line 401 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); } #line 402 "./src/stdlib/toml.am" if (isArrayHeader) { #line 403 "./src/stdlib/toml.am" if (!code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), "]")) { Amalgame_Compiler_TomlParser_Fail(p, "expected ']]' to close array-of-tables header"); } else { #line 404 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); } } #line 406 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); #line 407 "./src/stdlib/toml.am" if (isArrayHeader) { #line 408 "./src/stdlib/toml.am" current = Amalgame_Compiler_Toml_AppendArrayTable(root, path); } else { #line 410 "./src/stdlib/toml.am" current = Amalgame_Compiler_Toml_NavigateOrCreate(root, path); } } else { #line 414 "./src/stdlib/toml.am" code_string key = Amalgame_Compiler_TomlParser_ReadKey(p); #line 415 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); #line 416 "./src/stdlib/toml.am" if (!code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), "=")) { Amalgame_Compiler_TomlParser_Fail(p, code_string_concat((code_string_concat("expected '=' after key '", key)), "'")); } else { #line 417 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); } #line 418 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); #line 419 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* val = Amalgame_Compiler_Toml_ReadValue(p); #line 420 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_SetEntry(current, key, val); } #line 422 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipBlankLines(p); } #line 424 "./src/stdlib/toml.am" return root; } AmalgameList* Amalgame_Compiler_Toml_ReadHeaderPath(Amalgame_Compiler_TomlParser* p) { #line 431 "./src/stdlib/toml.am" AmalgameList* out = AmalgameList_new(); #line 432 "./src/stdlib/toml.am" code_bool first = 1; #line 433 "./src/stdlib/toml.am" while (!Amalgame_Compiler_TomlParser_AtEnd(p)) { #line 434 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); #line 435 "./src/stdlib/toml.am" if (code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), "]")) { return out; } #line 436 "./src/stdlib/toml.am" if (!first) { #line 437 "./src/stdlib/toml.am" if (!code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), ".")) { #line 438 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_Fail(p, "expected '.' or ']' in table header"); #line 439 "./src/stdlib/toml.am" return out; } #line 441 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); #line 442 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); } #line 444 "./src/stdlib/toml.am" code_string seg = Amalgame_Compiler_TomlParser_ReadKey(p); #line 445 "./src/stdlib/toml.am" if (String_Length(seg) == 0LL) { return out; } #line 446 "./src/stdlib/toml.am" AmalgameList_add(out, (void*)(intptr_t)(seg)); #line 447 "./src/stdlib/toml.am" first = 0; } #line 449 "./src/stdlib/toml.am" return out; } Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_NavigateOrCreate(Amalgame_Compiler_TomlValue* root, AmalgameList* path) { #line 455 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* cur = root; #line 456 "./src/stdlib/toml.am" i64 n = AmalgameList_count(path); #line 457 "./src/stdlib/toml.am" for (i64 i = 0LL; i < n; i++) { #line 458 "./src/stdlib/toml.am" code_string seg = (code_string)AmalgameList_get(path, i); #line 459 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* existing = Amalgame_Compiler_TomlValue_Get(cur, seg); #line 460 "./src/stdlib/toml.am" if (Amalgame_Compiler_TomlValue_IsTable(existing)) { #line 461 "./src/stdlib/toml.am" cur = existing; } else { #line 463 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* fresh = Amalgame_Compiler_TomlValue_new(); #line 464 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_BecomeTable(fresh); #line 465 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_SetEntry(cur, seg, fresh); #line 466 "./src/stdlib/toml.am" cur = fresh; } } #line 469 "./src/stdlib/toml.am" return cur; } Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_AppendArrayTable(Amalgame_Compiler_TomlValue* root, AmalgameList* path) { #line 478 "./src/stdlib/toml.am" i64 n = AmalgameList_count(path); #line 479 "./src/stdlib/toml.am" if (n == 0LL) { return root; } #line 481 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* parent = root; #line 482 "./src/stdlib/toml.am" i64 parentDepth = n - 1LL; #line 483 "./src/stdlib/toml.am" for (i64 i = 0LL; i < parentDepth; i++) { #line 484 "./src/stdlib/toml.am" code_string seg = (code_string)AmalgameList_get(path, i); #line 485 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* existing = Amalgame_Compiler_TomlValue_Get(parent, seg); #line 486 "./src/stdlib/toml.am" if (Amalgame_Compiler_TomlValue_IsTable(existing)) { #line 487 "./src/stdlib/toml.am" parent = existing; } else { #line 489 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* fresh = Amalgame_Compiler_TomlValue_new(); #line 490 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_BecomeTable(fresh); #line 491 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_SetEntry(parent, seg, fresh); #line 492 "./src/stdlib/toml.am" parent = fresh; } } #line 496 "./src/stdlib/toml.am" code_string lastSeg = (code_string)AmalgameList_get(path, n - 1LL); #line 497 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* arr = Amalgame_Compiler_TomlValue_Get(parent, lastSeg); #line 498 "./src/stdlib/toml.am" if (!Amalgame_Compiler_TomlValue_IsArray(arr)) { #line 499 "./src/stdlib/toml.am" arr = Amalgame_Compiler_TomlValue_new(); #line 500 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_BecomeArray(arr); #line 501 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_SetEntry(parent, lastSeg, arr); } #line 503 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* newTable = Amalgame_Compiler_TomlValue_new(); #line 504 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_BecomeTable(newTable); #line 505 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_AppendItem(arr, newTable); #line 506 "./src/stdlib/toml.am" return newTable; } Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadValue(Amalgame_Compiler_TomlParser* p) { #line 510 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); #line 511 "./src/stdlib/toml.am" code_string c = Amalgame_Compiler_TomlParser_Peek(p); #line 512 "./src/stdlib/toml.am" if ((code_string_equals(c, "\"")) || (code_string_equals(c, "'"))) { #line 513 "./src/stdlib/toml.am" code_string s = Amalgame_Compiler_TomlParser_ReadStringLiteral(p); #line 514 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* v = Amalgame_Compiler_TomlValue_new(); #line 515 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_SetString(v, s); #line 516 "./src/stdlib/toml.am" return v; } #line 518 "./src/stdlib/toml.am" if (code_string_equals(c, "[")) { #line 519 "./src/stdlib/toml.am" return Amalgame_Compiler_Toml_ReadArray(p); } #line 521 "./src/stdlib/toml.am" if (code_string_equals(c, "{")) { #line 522 "./src/stdlib/toml.am" return Amalgame_Compiler_Toml_ReadInlineTable(p); } #line 524 "./src/stdlib/toml.am" if ((code_string_equals(c, "t")) || (code_string_equals(c, "f"))) { #line 525 "./src/stdlib/toml.am" return Amalgame_Compiler_Toml_ReadBool(p); } #line 530 "./src/stdlib/toml.am" code_bool isNumeric = 0; #line 531 "./src/stdlib/toml.am" if ((code_string_equals(c, "-")) || (code_string_equals(c, "+"))) { isNumeric = 1; } #line 532 "./src/stdlib/toml.am" if (String_IndexOf("0123456789", c) >= 0LL) { isNumeric = 1; } #line 533 "./src/stdlib/toml.am" if (isNumeric) { #line 534 "./src/stdlib/toml.am" return Amalgame_Compiler_Toml_ReadInt(p); } #line 536 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_Fail(p, code_string_concat((code_string_concat("unexpected character '", c)), "' starting value")); #line 537 "./src/stdlib/toml.am" return Amalgame_Compiler_TomlValue_new(); } Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadArray(Amalgame_Compiler_TomlParser* p) { #line 541 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); #line 542 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* arr = Amalgame_Compiler_TomlValue_new(); #line 543 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_BecomeArray(arr); #line 544 "./src/stdlib/toml.am" Amalgame_Compiler_Toml_SkipWsAndNewlines(p); #line 545 "./src/stdlib/toml.am" if (code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), "]")) { #line 546 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); #line 547 "./src/stdlib/toml.am" return arr; } #line 549 "./src/stdlib/toml.am" while (!Amalgame_Compiler_TomlParser_AtEnd(p)) { #line 550 "./src/stdlib/toml.am" Amalgame_Compiler_Toml_SkipWsAndNewlines(p); #line 551 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* v = Amalgame_Compiler_Toml_ReadValue(p); #line 552 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_AppendItem(arr, v); #line 553 "./src/stdlib/toml.am" Amalgame_Compiler_Toml_SkipWsAndNewlines(p); #line 554 "./src/stdlib/toml.am" code_string c = Amalgame_Compiler_TomlParser_Peek(p); #line 555 "./src/stdlib/toml.am" if (code_string_equals(c, ",")) { #line 556 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); #line 557 "./src/stdlib/toml.am" Amalgame_Compiler_Toml_SkipWsAndNewlines(p); #line 558 "./src/stdlib/toml.am" if (code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), "]")) { #line 560 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); #line 561 "./src/stdlib/toml.am" return arr; } } else if (code_string_equals(c, "]")) { #line 564 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); #line 565 "./src/stdlib/toml.am" return arr; } else { #line 567 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_Fail(p, "expected ',' or ']' in array"); #line 568 "./src/stdlib/toml.am" return arr; } } #line 571 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_Fail(p, "unterminated array"); #line 572 "./src/stdlib/toml.am" return arr; } Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadInlineTable(Amalgame_Compiler_TomlParser* p) { #line 576 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); #line 577 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* tbl = Amalgame_Compiler_TomlValue_new(); #line 578 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_BecomeTable(tbl); #line 579 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); #line 580 "./src/stdlib/toml.am" if (code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), "}")) { #line 581 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); #line 582 "./src/stdlib/toml.am" return tbl; } #line 584 "./src/stdlib/toml.am" while (!Amalgame_Compiler_TomlParser_AtEnd(p)) { #line 585 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); #line 586 "./src/stdlib/toml.am" code_string key = Amalgame_Compiler_TomlParser_ReadKey(p); #line 587 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); #line 588 "./src/stdlib/toml.am" if (!code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), "=")) { #line 589 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_Fail(p, "expected '=' in inline table"); #line 590 "./src/stdlib/toml.am" return tbl; } #line 592 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); #line 593 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); #line 594 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* v = Amalgame_Compiler_Toml_ReadValue(p); #line 595 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_SetEntry(tbl, key, v); #line 596 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_SkipInlineSpace(p); #line 597 "./src/stdlib/toml.am" code_string c = Amalgame_Compiler_TomlParser_Peek(p); #line 598 "./src/stdlib/toml.am" if (code_string_equals(c, ",")) { #line 599 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); } else if (code_string_equals(c, "}")) { #line 601 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); #line 602 "./src/stdlib/toml.am" return tbl; } else { #line 604 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_Fail(p, "expected ',' or '}' in inline table"); #line 605 "./src/stdlib/toml.am" return tbl; } } #line 608 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_Fail(p, "unterminated inline table"); #line 609 "./src/stdlib/toml.am" return tbl; } Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadBool(Amalgame_Compiler_TomlParser* p) { #line 613 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* v = Amalgame_Compiler_TomlValue_new(); #line 614 "./src/stdlib/toml.am" if (code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), "t")) { #line 615 "./src/stdlib/toml.am" if ((((code_string_equals(Amalgame_Compiler_TomlParser_PeekAt(p, 0LL), "t")) && (code_string_equals(Amalgame_Compiler_TomlParser_PeekAt(p, 1LL), "r"))) && (code_string_equals(Amalgame_Compiler_TomlParser_PeekAt(p, 2LL), "u"))) && (code_string_equals(Amalgame_Compiler_TomlParser_PeekAt(p, 3LL), "e"))) { #line 616 "./src/stdlib/toml.am" p->Pos = (p->Pos + 4LL); #line 617 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_SetBool(v, 1); #line 618 "./src/stdlib/toml.am" return v; } } #line 621 "./src/stdlib/toml.am" if (code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), "f")) { #line 622 "./src/stdlib/toml.am" if (((((code_string_equals(Amalgame_Compiler_TomlParser_PeekAt(p, 0LL), "f")) && (code_string_equals(Amalgame_Compiler_TomlParser_PeekAt(p, 1LL), "a"))) && (code_string_equals(Amalgame_Compiler_TomlParser_PeekAt(p, 2LL), "l"))) && (code_string_equals(Amalgame_Compiler_TomlParser_PeekAt(p, 3LL), "s"))) && (code_string_equals(Amalgame_Compiler_TomlParser_PeekAt(p, 4LL), "e"))) { #line 623 "./src/stdlib/toml.am" p->Pos = (p->Pos + 5LL); #line 624 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_SetBool(v, 0); #line 625 "./src/stdlib/toml.am" return v; } } #line 628 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_Fail(p, "expected 'true' or 'false'"); #line 629 "./src/stdlib/toml.am" return v; } Amalgame_Compiler_TomlValue* Amalgame_Compiler_Toml_ReadInt(Amalgame_Compiler_TomlParser* p) { #line 633 "./src/stdlib/toml.am" code_string raw = ""; #line 634 "./src/stdlib/toml.am" code_string first = Amalgame_Compiler_TomlParser_Peek(p); #line 635 "./src/stdlib/toml.am" if ((code_string_equals(first, "+")) || (code_string_equals(first, "-"))) { #line 636 "./src/stdlib/toml.am" raw = (code_string_concat(raw, first)); #line 637 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); } #line 639 "./src/stdlib/toml.am" while (!Amalgame_Compiler_TomlParser_AtEnd(p)) { #line 640 "./src/stdlib/toml.am" code_string c = Amalgame_Compiler_TomlParser_Peek(p); #line 641 "./src/stdlib/toml.am" if (String_IndexOf("0123456789", c) >= 0LL) { #line 642 "./src/stdlib/toml.am" raw = (code_string_concat(raw, c)); #line 643 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); } else { #line 645 "./src/stdlib/toml.am" break; } } #line 648 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* v = Amalgame_Compiler_TomlValue_new(); #line 649 "./src/stdlib/toml.am" if (((String_Length(raw) == 0LL) || (code_string_equals(raw, "+"))) || (code_string_equals(raw, "-"))) { #line 650 "./src/stdlib/toml.am" Amalgame_Compiler_TomlParser_Fail(p, "expected digits"); #line 651 "./src/stdlib/toml.am" return v; } #line 653 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue_SetInt(v, String_ToInt(raw)); #line 654 "./src/stdlib/toml.am" return v; } void Amalgame_Compiler_Toml_SkipWsAndNewlines(Amalgame_Compiler_TomlParser* p) { #line 660 "./src/stdlib/toml.am" while (!Amalgame_Compiler_TomlParser_AtEnd(p)) { #line 661 "./src/stdlib/toml.am" code_string c = Amalgame_Compiler_TomlParser_Peek(p); #line 662 "./src/stdlib/toml.am" if ((((code_string_equals(c, " ")) || (code_string_equals(c, "\t"))) || (code_string_equals(c, "\n"))) || (code_string_equals(c, "\r"))) { #line 663 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); } else if (code_string_equals(c, "#")) { #line 665 "./src/stdlib/toml.am" while (!Amalgame_Compiler_TomlParser_AtEnd(p) && (!code_string_equals(Amalgame_Compiler_TomlParser_Peek(p), "\n"))) { #line 666 "./src/stdlib/toml.am" p->Pos = (p->Pos + 1LL); } } else { #line 669 "./src/stdlib/toml.am" return; } } } code_string Amalgame_Compiler_Toml_Serialize(Amalgame_Compiler_TomlValue* doc) { #line 683 "./src/stdlib/toml.am" if (!Amalgame_Compiler_TomlValue_IsTable(doc)) { return ""; } #line 684 "./src/stdlib/toml.am" code_string out = ""; #line 685 "./src/stdlib/toml.am" AmalgameList* path = AmalgameList_new(); #line 686 "./src/stdlib/toml.am" out = Amalgame_Compiler_Toml_WriteTable(doc, path, out); #line 687 "./src/stdlib/toml.am" return out; } static code_string Amalgame_Compiler_Toml_WriteTable(Amalgame_Compiler_TomlValue* t, AmalgameList* path, code_string out) { #line 691 "./src/stdlib/toml.am" code_string s = out; #line 695 "./src/stdlib/toml.am" AmalgameList* keys = Amalgame_Compiler_TomlValue_Keys(t); #line 696 "./src/stdlib/toml.am" i64 n = AmalgameList_count(keys); #line 698 "./src/stdlib/toml.am" if (AmalgameList_count(path) > 0LL) { #line 699 "./src/stdlib/toml.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "[")), Amalgame_Compiler_Toml_JoinPath(path))), "]\n")); } #line 701 "./src/stdlib/toml.am" for (i64 i = 0LL; i < n; i++) { #line 702 "./src/stdlib/toml.am" code_string k = (code_string)AmalgameList_get(keys, i); #line 703 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* v = Amalgame_Compiler_TomlValue_Get(t, k); #line 704 "./src/stdlib/toml.am" if (Amalgame_Compiler_TomlValue_IsTable(v)) { continue; } #line 705 "./src/stdlib/toml.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, k)), " = ")), Amalgame_Compiler_Toml_WriteValue(v))), "\n")); } #line 708 "./src/stdlib/toml.am" for (i64 j = 0LL; j < n; j++) { #line 709 "./src/stdlib/toml.am" code_string k2 = (code_string)AmalgameList_get(keys, j); #line 710 "./src/stdlib/toml.am" Amalgame_Compiler_TomlValue* v2 = Amalgame_Compiler_TomlValue_Get(t, k2); #line 711 "./src/stdlib/toml.am" if (!Amalgame_Compiler_TomlValue_IsTable(v2)) { continue; } #line 712 "./src/stdlib/toml.am" AmalgameList* childPath = AmalgameList_new(); #line 713 "./src/stdlib/toml.am" i64 pn = AmalgameList_count(path); #line 714 "./src/stdlib/toml.am" for (i64 pi = 0LL; pi < pn; pi++) { AmalgameList_add(childPath, (void*)(intptr_t)((code_string)AmalgameList_get(path, pi))); } #line 715 "./src/stdlib/toml.am" AmalgameList_add(childPath, (void*)(intptr_t)(k2)); #line 716 "./src/stdlib/toml.am" s = (code_string_concat(s, "\n")); #line 717 "./src/stdlib/toml.am" s = Amalgame_Compiler_Toml_WriteTable(v2, childPath, s); } #line 719 "./src/stdlib/toml.am" return s; } static code_string Amalgame_Compiler_Toml_WriteValue(Amalgame_Compiler_TomlValue* v) { #line 723 "./src/stdlib/toml.am" if (Amalgame_Compiler_TomlValue_IsString(v)) { #line 724 "./src/stdlib/toml.am" return code_string_concat((code_string_concat("\"", Amalgame_Compiler_Toml_EscapeString(Amalgame_Compiler_TomlValue_AsString(v)))), "\""); } #line 726 "./src/stdlib/toml.am" if (Amalgame_Compiler_TomlValue_IsInt(v)) { #line 727 "./src/stdlib/toml.am" return String_FromInt(Amalgame_Compiler_TomlValue_AsInt(v)); } #line 729 "./src/stdlib/toml.am" if (Amalgame_Compiler_TomlValue_IsBool(v)) { #line 730 "./src/stdlib/toml.am" if (Amalgame_Compiler_TomlValue_AsBool(v)) { return "true"; } #line 731 "./src/stdlib/toml.am" return "false"; } #line 733 "./src/stdlib/toml.am" if (Amalgame_Compiler_TomlValue_IsArray(v)) { #line 734 "./src/stdlib/toml.am" code_string out = "["; #line 735 "./src/stdlib/toml.am" AmalgameList* items = Amalgame_Compiler_TomlValue_AsArray(v); #line 736 "./src/stdlib/toml.am" i64 n = AmalgameList_count(items); #line 737 "./src/stdlib/toml.am" for (i64 i = 0LL; i < n; i++) { #line 738 "./src/stdlib/toml.am" if (i > 0LL) { out = (code_string_concat(out, ", ")); } #line 739 "./src/stdlib/toml.am" out = (code_string_concat(out, Amalgame_Compiler_Toml_WriteValue((Amalgame_Compiler_TomlValue*)AmalgameList_get(items, i)))); } #line 741 "./src/stdlib/toml.am" out = (code_string_concat(out, "]")); #line 742 "./src/stdlib/toml.am" return out; } #line 744 "./src/stdlib/toml.am" if (Amalgame_Compiler_TomlValue_IsTable(v)) { #line 748 "./src/stdlib/toml.am" code_string out = "{ "; #line 749 "./src/stdlib/toml.am" AmalgameList* keys = Amalgame_Compiler_TomlValue_Keys(v); #line 750 "./src/stdlib/toml.am" i64 n = AmalgameList_count(keys); #line 751 "./src/stdlib/toml.am" for (i64 i = 0LL; i < n; i++) { #line 752 "./src/stdlib/toml.am" if (i > 0LL) { out = (code_string_concat(out, ", ")); } #line 753 "./src/stdlib/toml.am" code_string k = (code_string)AmalgameList_get(keys, i); #line 754 "./src/stdlib/toml.am" out = (code_string_concat((code_string_concat((code_string_concat(out, k)), " = ")), Amalgame_Compiler_Toml_WriteValue(Amalgame_Compiler_TomlValue_Get(v, k)))); } #line 756 "./src/stdlib/toml.am" out = (code_string_concat(out, " }")); #line 757 "./src/stdlib/toml.am" return out; } #line 759 "./src/stdlib/toml.am" return "\"\""; } static code_string Amalgame_Compiler_Toml_EscapeString(code_string s) { #line 763 "./src/stdlib/toml.am" code_string out = ""; #line 764 "./src/stdlib/toml.am" i64 n = String_Length(s); #line 765 "./src/stdlib/toml.am" for (i64 i = 0LL; i < n; i++) { #line 766 "./src/stdlib/toml.am" code_string c = String_CharAt1(s, i); #line 767 "./src/stdlib/toml.am" if (code_string_equals(c, "\\")) { out = (code_string_concat(out, "\\\\")); } else if (code_string_equals(c, "\"")) { #line 768 "./src/stdlib/toml.am" out = (code_string_concat(out, "\\\"")); } else if (code_string_equals(c, "\n")) { #line 769 "./src/stdlib/toml.am" out = (code_string_concat(out, "\\n")); } else if (code_string_equals(c, "\t")) { #line 770 "./src/stdlib/toml.am" out = (code_string_concat(out, "\\t")); } else if (code_string_equals(c, String_FromByte(13LL))) { #line 771 "./src/stdlib/toml.am" out = (code_string_concat(out, "\\r")); } else { #line 772 "./src/stdlib/toml.am" out = (code_string_concat(out, c)); } } #line 774 "./src/stdlib/toml.am" return out; } static code_string Amalgame_Compiler_Toml_JoinPath(AmalgameList* path) { #line 778 "./src/stdlib/toml.am" code_string out = ""; #line 779 "./src/stdlib/toml.am" i64 n = AmalgameList_count(path); #line 780 "./src/stdlib/toml.am" for (i64 i = 0LL; i < n; i++) { #line 781 "./src/stdlib/toml.am" if (i > 0LL) { out = (code_string_concat(out, ".")); } #line 782 "./src/stdlib/toml.am" out = (code_string_concat(out, (code_string)AmalgameList_get(path, i))); } #line 784 "./src/stdlib/toml.am" return out; } struct _Amalgame_Compiler_LoadedPackage { code_string Name; code_string ClassName; AmalgameList* ClassNames; code_string Header; code_string Ns; code_string Tag; code_string PkgDir; AmalgameList* FuncNames; AmalgameList* FuncRets; AmalgameList* FuncRetsRaw; AmalgameList* Sources; code_string CFlags; code_string CxxFlags; AmalgameList* Libs; code_bool Precompile; code_string Facade; }; Amalgame_Compiler_LoadedPackage* Amalgame_Compiler_LoadedPackage_new() { Amalgame_Compiler_LoadedPackage* self = (Amalgame_Compiler_LoadedPackage*) GC_MALLOC(sizeof(Amalgame_Compiler_LoadedPackage)); #line 151 "./src/package_registry.am" self->Name = ""; #line 152 "./src/package_registry.am" self->ClassName = ""; #line 153 "./src/package_registry.am" self->ClassNames = AmalgameList_new(); #line 154 "./src/package_registry.am" self->Header = ""; #line 155 "./src/package_registry.am" self->Ns = ""; #line 156 "./src/package_registry.am" self->Tag = ""; #line 157 "./src/package_registry.am" self->PkgDir = ""; #line 158 "./src/package_registry.am" self->FuncNames = AmalgameList_new(); #line 159 "./src/package_registry.am" self->FuncRets = AmalgameList_new(); #line 160 "./src/package_registry.am" self->FuncRetsRaw = AmalgameList_new(); #line 161 "./src/package_registry.am" self->Sources = AmalgameList_new(); #line 162 "./src/package_registry.am" self->CFlags = ""; #line 163 "./src/package_registry.am" self->CxxFlags = ""; #line 164 "./src/package_registry.am" self->Libs = AmalgameList_new(); #line 165 "./src/package_registry.am" self->Precompile = 0; #line 166 "./src/package_registry.am" self->Facade = ""; return self; } struct _Amalgame_Compiler_PackageRegistry { AmalgameList* Packages; }; Amalgame_Compiler_PackageRegistry* Amalgame_Compiler_PackageRegistry_Load(); Amalgame_Compiler_PackageRegistry* Amalgame_Compiler_PackageRegistry_LoadFrom(code_string lockPath, code_string cacheRoot); AmalgameList* Amalgame_Compiler_PackageRegistry_ClassNames(Amalgame_Compiler_PackageRegistry* self); AmalgameList* Amalgame_Compiler_PackageRegistry_Headers(Amalgame_Compiler_PackageRegistry* self); code_bool Amalgame_Compiler_PackageRegistry_HasCxxSources(Amalgame_Compiler_PackageRegistry* self); code_string Amalgame_Compiler_PackageRegistry_FacadeArchivePath(Amalgame_Compiler_LoadedPackage* p); AmalgameList* Amalgame_Compiler_PackageRegistry_CollectFacadeArchives(Amalgame_Compiler_PackageRegistry* self); AmalgameList* Amalgame_Compiler_PackageRegistry_CollectLibs(Amalgame_Compiler_PackageRegistry* self); code_bool Amalgame_Compiler_PackageRegistry_IsCxxSource(code_string path); code_string Amalgame_Compiler_PackageRegistry_AmalgameHome(); code_string Amalgame_Compiler_PackageRegistry_AmalgameStateDir(); code_string Amalgame_Compiler_PackageRegistry_DefaultCacheRoot(); code_string Amalgame_Compiler_PackageRegistry_CalibrationPath(); code_string Amalgame_Compiler_PackageRegistry_PrecompileCacheDir(code_string pkgDir); code_string Amalgame_Compiler_PackageRegistry_PlatformTag(); code_string Amalgame_Compiler_PackageRegistry_ManglePackageSymbol(code_string ns, code_string method); code_string Amalgame_Compiler_PackageRegistry_AmalgameTypeFromC(code_string cType); code_string Amalgame_Compiler_PackageRegistry_AmcVersion(); i64 Amalgame_Compiler_PackageRegistry_SupportedManifestSchema(); AmalgameList* Amalgame_Compiler_PackageRegistry_ParseVersion(code_string v); code_string Amalgame_Compiler_PackageRegistry_ReadCalibrationFile(); code_bool Amalgame_Compiler_PackageRegistry_VersionSatisfies(code_string current, code_string constraint); i64 Amalgame_Compiler_PackageRegistry_CompareCmp(code_string a, code_string b); code_bool Amalgame_Compiler_PackageRegistry_CaretSatisfies(code_string current, code_string base); code_bool Amalgame_Compiler_PackageRegistry_TildeSatisfies(code_string current, code_string base); Amalgame_Compiler_PackageRegistry* Amalgame_Compiler_PackageRegistry_new() { Amalgame_Compiler_PackageRegistry* self = (Amalgame_Compiler_PackageRegistry*) GC_MALLOC(sizeof(Amalgame_Compiler_PackageRegistry)); #line 174 "./src/package_registry.am" self->Packages = AmalgameList_new(); return self; } Amalgame_Compiler_PackageRegistry* Amalgame_Compiler_PackageRegistry_Load() { #line 182 "./src/package_registry.am" code_string cacheRoot = Amalgame_Compiler_PackageRegistry_DefaultCacheRoot(); #line 183 "./src/package_registry.am" return Amalgame_Compiler_PackageRegistry_LoadFrom("amalgame.lock", cacheRoot); } Amalgame_Compiler_PackageRegistry* Amalgame_Compiler_PackageRegistry_LoadFrom(code_string lockPath, code_string cacheRoot) { #line 190 "./src/package_registry.am" Amalgame_Compiler_PackageRegistry* reg = Amalgame_Compiler_PackageRegistry_new(); #line 191 "./src/package_registry.am" if (!File_Exists(lockPath)) { return reg; } #line 192 "./src/package_registry.am" code_string lockSrc = File_ReadAll(lockPath); #line 193 "./src/package_registry.am" Amalgame_Compiler_TomlValue* lockDoc = Amalgame_Compiler_Toml_Parse(lockSrc); #line 194 "./src/package_registry.am" if (Amalgame_Compiler_TomlValue_IsNull(lockDoc)) { return reg; } #line 197 "./src/package_registry.am" Amalgame_Compiler_TomlValue* pkgsArr = Amalgame_Compiler_TomlValue_Get(lockDoc, "package"); #line 198 "./src/package_registry.am" if (!Amalgame_Compiler_TomlValue_IsArray(pkgsArr)) { return reg; } #line 199 "./src/package_registry.am" i64 n = Amalgame_Compiler_TomlValue_Count(pkgsArr); #line 200 "./src/package_registry.am" for (i64 i = 0LL; i < n; i++) { #line 201 "./src/package_registry.am" Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(pkgsArr, i); #line 202 "./src/package_registry.am" Amalgame_Compiler_TomlValue* nameVal = Amalgame_Compiler_TomlValue_Get(entry, "name"); #line 203 "./src/package_registry.am" Amalgame_Compiler_TomlValue* gitVal = Amalgame_Compiler_TomlValue_Get(entry, "git"); #line 204 "./src/package_registry.am" Amalgame_Compiler_TomlValue* tagVal = Amalgame_Compiler_TomlValue_Get(entry, "tag"); #line 205 "./src/package_registry.am" Amalgame_Compiler_TomlValue* revVal = Amalgame_Compiler_TomlValue_Get(entry, "rev"); #line 206 "./src/package_registry.am" code_string pkgName = Amalgame_Compiler_TomlValue_AsString(nameVal); #line 207 "./src/package_registry.am" code_string pkgGit = Amalgame_Compiler_TomlValue_AsString(gitVal); #line 208 "./src/package_registry.am" code_string pkgTag = Amalgame_Compiler_TomlValue_AsString(tagVal); #line 209 "./src/package_registry.am" code_string pkgRev = Amalgame_Compiler_TomlValue_AsString(revVal); #line 210 "./src/package_registry.am" if (String_Length(pkgName) == 0LL) { continue; } #line 211 "./src/package_registry.am" if (String_Length(pkgGit) == 0LL) { continue; } #line 212 "./src/package_registry.am" if (String_Length(pkgTag) == 0LL) { continue; } #line 213 "./src/package_registry.am" if (String_Length(pkgRev) < 8LL) { continue; } #line 216 "./src/package_registry.am" code_string shortSha = String_Substring(pkgRev, 0LL, 8LL); #line 217 "./src/package_registry.am" code_string pkgDir = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(cacheRoot, "/")), pkgGit)), "/")), pkgTag)), "_")), shortSha); #line 218 "./src/package_registry.am" code_string manifestPath = code_string_concat(pkgDir, "/amalgame.toml"); #line 219 "./src/package_registry.am" if (!File_Exists(manifestPath)) { continue; } #line 220 "./src/package_registry.am" code_string manifestSrc = File_ReadAll(manifestPath); #line 221 "./src/package_registry.am" Amalgame_Compiler_TomlValue* manifest = Amalgame_Compiler_Toml_Parse(manifestSrc); #line 222 "./src/package_registry.am" if (Amalgame_Compiler_TomlValue_IsNull(manifest)) { continue; } #line 230 "./src/package_registry.am" Amalgame_Compiler_TomlValue* pkgTable = Amalgame_Compiler_TomlValue_Get(manifest, "package"); #line 231 "./src/package_registry.am" if (Amalgame_Compiler_TomlValue_IsTable(pkgTable)) { #line 232 "./src/package_registry.am" Amalgame_Compiler_TomlValue* schemaVal = Amalgame_Compiler_TomlValue_Get(pkgTable, "schema-version"); #line 233 "./src/package_registry.am" i64 schemaInt = Amalgame_Compiler_TomlValue_AsInt(schemaVal); #line 234 "./src/package_registry.am" if (schemaInt > Amalgame_Compiler_PackageRegistry_SupportedManifestSchema()) { #line 235 "./src/package_registry.am" continue; } } #line 241 "./src/package_registry.am" Amalgame_Compiler_TomlValue* stdlibTable = Amalgame_Compiler_TomlValue_Get(manifest, "stdlib"); #line 242 "./src/package_registry.am" if (!Amalgame_Compiler_TomlValue_IsTable(stdlibTable)) { continue; } #line 243 "./src/package_registry.am" Amalgame_Compiler_TomlValue* headerVal = Amalgame_Compiler_TomlValue_Get(stdlibTable, "header"); #line 244 "./src/package_registry.am" Amalgame_Compiler_TomlValue* nsVal = Amalgame_Compiler_TomlValue_Get(stdlibTable, "namespace"); #line 245 "./src/package_registry.am" code_string hdr = Amalgame_Compiler_TomlValue_AsString(headerVal); #line 246 "./src/package_registry.am" code_string ns = Amalgame_Compiler_TomlValue_AsString(nsVal); #line 247 "./src/package_registry.am" if (String_Length(hdr) == 0LL) { continue; } #line 251 "./src/package_registry.am" AmalgameList* classNames = AmalgameList_new(); #line 252 "./src/package_registry.am" Amalgame_Compiler_TomlValue* classesArr = Amalgame_Compiler_TomlValue_Get(stdlibTable, "classes"); #line 253 "./src/package_registry.am" if (Amalgame_Compiler_TomlValue_IsArray(classesArr)) { #line 254 "./src/package_registry.am" i64 cn = Amalgame_Compiler_TomlValue_Count(classesArr); #line 255 "./src/package_registry.am" for (i64 ci = 0LL; ci < cn; ci++) { #line 256 "./src/package_registry.am" code_string cv = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_At(classesArr, ci)); #line 257 "./src/package_registry.am" if (String_Length(cv) > 0LL) { AmalgameList_add(classNames, (void*)(intptr_t)(cv)); } } } #line 260 "./src/package_registry.am" if (AmalgameList_count(classNames) == 0LL) { #line 261 "./src/package_registry.am" Amalgame_Compiler_TomlValue* classVal = Amalgame_Compiler_TomlValue_Get(stdlibTable, "class"); #line 262 "./src/package_registry.am" code_string clsSingle = Amalgame_Compiler_TomlValue_AsString(classVal); #line 263 "./src/package_registry.am" if (String_Length(clsSingle) > 0LL) { AmalgameList_add(classNames, (void*)(intptr_t)(clsSingle)); } } #line 265 "./src/package_registry.am" if (AmalgameList_count(classNames) == 0LL) { continue; } #line 267 "./src/package_registry.am" Amalgame_Compiler_LoadedPackage* lp = Amalgame_Compiler_LoadedPackage_new(); #line 268 "./src/package_registry.am" lp->Name = pkgName; #line 269 "./src/package_registry.am" lp->Tag = pkgTag; #line 270 "./src/package_registry.am" lp->PkgDir = pkgDir; #line 271 "./src/package_registry.am" lp->ClassNames = classNames; #line 272 "./src/package_registry.am" lp->ClassName = (code_string)AmalgameList_get(classNames, 0LL); #line 277 "./src/package_registry.am" lp->Header = (code_string_concat((code_string_concat(pkgDir, "/")), hdr)); #line 278 "./src/package_registry.am" lp->Ns = ns; #line 284 "./src/package_registry.am" Amalgame_Compiler_TomlValue* sourcesArr = Amalgame_Compiler_TomlValue_Get(stdlibTable, "sources"); #line 285 "./src/package_registry.am" if (Amalgame_Compiler_TomlValue_IsArray(sourcesArr)) { #line 286 "./src/package_registry.am" i64 sn = Amalgame_Compiler_TomlValue_Count(sourcesArr); #line 287 "./src/package_registry.am" for (i64 si = 0LL; si < sn; si++) { #line 288 "./src/package_registry.am" Amalgame_Compiler_TomlValue* srcTv = Amalgame_Compiler_TomlValue_At(sourcesArr, si); #line 289 "./src/package_registry.am" code_string srcRel = Amalgame_Compiler_TomlValue_AsString(srcTv); #line 290 "./src/package_registry.am" if (String_Length(srcRel) > 0LL) { #line 291 "./src/package_registry.am" AmalgameList_add(lp->Sources, (void*)(intptr_t)(code_string_concat((code_string_concat(pkgDir, "/")), srcRel))); } } } #line 300 "./src/package_registry.am" Amalgame_Compiler_TomlValue* cflagsVal = Amalgame_Compiler_TomlValue_Get(stdlibTable, "cflags"); #line 301 "./src/package_registry.am" lp->CFlags = Amalgame_Compiler_TomlValue_AsString(cflagsVal); #line 302 "./src/package_registry.am" Amalgame_Compiler_TomlValue* cxxflagsVal = Amalgame_Compiler_TomlValue_Get(stdlibTable, "cxxflags"); #line 303 "./src/package_registry.am" lp->CxxFlags = Amalgame_Compiler_TomlValue_AsString(cxxflagsVal); #line 310 "./src/package_registry.am" Amalgame_Compiler_TomlValue* libsArr = Amalgame_Compiler_TomlValue_Get(stdlibTable, "libs"); #line 311 "./src/package_registry.am" if (Amalgame_Compiler_TomlValue_IsArray(libsArr)) { #line 312 "./src/package_registry.am" i64 ln = Amalgame_Compiler_TomlValue_Count(libsArr); #line 313 "./src/package_registry.am" for (i64 li = 0LL; li < ln; li++) { #line 314 "./src/package_registry.am" Amalgame_Compiler_TomlValue* libTv = Amalgame_Compiler_TomlValue_At(libsArr, li); #line 315 "./src/package_registry.am" code_string libName = Amalgame_Compiler_TomlValue_AsString(libTv); #line 316 "./src/package_registry.am" if (String_Length(libName) > 0LL) { #line 317 "./src/package_registry.am" AmalgameList_add(lp->Libs, (void*)(intptr_t)(libName)); } } } #line 329 "./src/package_registry.am" Amalgame_Compiler_TomlValue* precompileVal = Amalgame_Compiler_TomlValue_Get(stdlibTable, "precompile"); #line 330 "./src/package_registry.am" lp->Precompile = Amalgame_Compiler_TomlValue_AsBool(precompileVal); #line 342 "./src/package_registry.am" Amalgame_Compiler_TomlValue* facadeVal = Amalgame_Compiler_TomlValue_Get(stdlibTable, "facade"); #line 343 "./src/package_registry.am" code_string facadeRel = Amalgame_Compiler_TomlValue_AsString(facadeVal); #line 344 "./src/package_registry.am" if (String_Length(facadeRel) > 0LL) { #line 345 "./src/package_registry.am" lp->Facade = (code_string_concat((code_string_concat(pkgDir, "/")), facadeRel)); } #line 349 "./src/package_registry.am" Amalgame_Compiler_TomlValue* funcsTbl = Amalgame_Compiler_TomlValue_Get(stdlibTable, "functions"); #line 350 "./src/package_registry.am" if (Amalgame_Compiler_TomlValue_IsTable(funcsTbl)) { #line 351 "./src/package_registry.am" AmalgameList* funcKeys = Amalgame_Compiler_TomlValue_Keys(funcsTbl); #line 352 "./src/package_registry.am" i64 fn = AmalgameList_count(funcKeys); #line 353 "./src/package_registry.am" for (i64 j = 0LL; j < fn; j++) { #line 354 "./src/package_registry.am" code_string fName = (code_string)AmalgameList_get(funcKeys, j); #line 355 "./src/package_registry.am" Amalgame_Compiler_TomlValue* fDef = Amalgame_Compiler_TomlValue_Get(funcsTbl, fName); #line 356 "./src/package_registry.am" Amalgame_Compiler_TomlValue* fRet = Amalgame_Compiler_TomlValue_Get(fDef, "returns"); #line 357 "./src/package_registry.am" code_string retStr = Amalgame_Compiler_TomlValue_AsString(fRet); #line 358 "./src/package_registry.am" if (String_Length(retStr) == 0LL) { continue; } #line 359 "./src/package_registry.am" AmalgameList_add(lp->FuncNames, (void*)(intptr_t)(fName)); #line 360 "./src/package_registry.am" AmalgameList_add(lp->FuncRets, (void*)(intptr_t)(retStr)); #line 365 "./src/package_registry.am" Amalgame_Compiler_TomlValue* fRetGen = Amalgame_Compiler_TomlValue_Get(fDef, "returns_generic"); #line 366 "./src/package_registry.am" code_string retGenStr = Amalgame_Compiler_TomlValue_AsString(fRetGen); #line 367 "./src/package_registry.am" AmalgameList_add(lp->FuncRetsRaw, (void*)(intptr_t)(retGenStr)); } } #line 370 "./src/package_registry.am" AmalgameList_add(reg->Packages, (void*)(intptr_t)(lp)); } #line 372 "./src/package_registry.am" return reg; } AmalgameList* Amalgame_Compiler_PackageRegistry_ClassNames(Amalgame_Compiler_PackageRegistry* self) { #line 378 "./src/package_registry.am" AmalgameList* out = AmalgameList_new(); #line 379 "./src/package_registry.am" i64 n = AmalgameList_count(self->Packages); #line 380 "./src/package_registry.am" for (i64 i = 0LL; i < n; i++) { #line 381 "./src/package_registry.am" Amalgame_Compiler_LoadedPackage* p = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(self->Packages, i); #line 382 "./src/package_registry.am" AmalgameList_add(out, (void*)(intptr_t)(p->ClassName)); } #line 384 "./src/package_registry.am" return out; } AmalgameList* Amalgame_Compiler_PackageRegistry_Headers(Amalgame_Compiler_PackageRegistry* self) { #line 390 "./src/package_registry.am" AmalgameList* out = AmalgameList_new(); #line 391 "./src/package_registry.am" i64 n = AmalgameList_count(self->Packages); #line 392 "./src/package_registry.am" for (i64 i = 0LL; i < n; i++) { #line 393 "./src/package_registry.am" Amalgame_Compiler_LoadedPackage* p = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(self->Packages, i); #line 394 "./src/package_registry.am" AmalgameList_add(out, (void*)(intptr_t)(p->Header)); } #line 396 "./src/package_registry.am" return out; } code_bool Amalgame_Compiler_PackageRegistry_HasCxxSources(Amalgame_Compiler_PackageRegistry* self) { #line 404 "./src/package_registry.am" i64 n = AmalgameList_count(self->Packages); #line 405 "./src/package_registry.am" for (i64 i = 0LL; i < n; i++) { #line 406 "./src/package_registry.am" Amalgame_Compiler_LoadedPackage* p = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(self->Packages, i); #line 407 "./src/package_registry.am" i64 sn = AmalgameList_count(p->Sources); #line 408 "./src/package_registry.am" for (i64 j = 0LL; j < sn; j++) { #line 409 "./src/package_registry.am" if (Amalgame_Compiler_PackageRegistry_IsCxxSource((code_string)AmalgameList_get(p->Sources, j))) { return 1; } } } #line 412 "./src/package_registry.am" return 0; } code_string Amalgame_Compiler_PackageRegistry_FacadeArchivePath(Amalgame_Compiler_LoadedPackage* p) { #line 420 "./src/package_registry.am" code_string buildDir = Amalgame_Compiler_PackageRegistry_PrecompileCacheDir(p->PkgDir); #line 421 "./src/package_registry.am" return code_string_concat((code_string_concat((code_string_concat(buildDir, "/libamalgame-pkg-")), p->ClassName)), ".a"); } AmalgameList* Amalgame_Compiler_PackageRegistry_CollectFacadeArchives(Amalgame_Compiler_PackageRegistry* self) { #line 430 "./src/package_registry.am" AmalgameList* out = AmalgameList_new(); #line 431 "./src/package_registry.am" i64 n = AmalgameList_count(self->Packages); #line 432 "./src/package_registry.am" for (i64 i = 0LL; i < n; i++) { #line 433 "./src/package_registry.am" Amalgame_Compiler_LoadedPackage* p = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(self->Packages, i); #line 434 "./src/package_registry.am" if (String_Length(p->Facade) == 0LL) { continue; } #line 435 "./src/package_registry.am" code_string archive = Amalgame_Compiler_PackageRegistry_FacadeArchivePath(p); #line 436 "./src/package_registry.am" if (File_Exists(archive)) { #line 437 "./src/package_registry.am" AmalgameList_add(out, (void*)(intptr_t)(archive)); } } #line 440 "./src/package_registry.am" return out; } AmalgameList* Amalgame_Compiler_PackageRegistry_CollectLibs(Amalgame_Compiler_PackageRegistry* self) { #line 449 "./src/package_registry.am" AmalgameList* out = AmalgameList_new(); #line 450 "./src/package_registry.am" i64 n = AmalgameList_count(self->Packages); #line 451 "./src/package_registry.am" for (i64 i = 0LL; i < n; i++) { #line 452 "./src/package_registry.am" Amalgame_Compiler_LoadedPackage* p = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(self->Packages, i); #line 453 "./src/package_registry.am" i64 ln = AmalgameList_count(p->Libs); #line 454 "./src/package_registry.am" for (i64 j = 0LL; j < ln; j++) { #line 455 "./src/package_registry.am" AmalgameList_add(out, (void*)(intptr_t)((code_string)AmalgameList_get(p->Libs, j))); } } #line 458 "./src/package_registry.am" return out; } code_bool Amalgame_Compiler_PackageRegistry_IsCxxSource(code_string path) { #line 465 "./src/package_registry.am" if (String_EndsWith(path, ".cpp")) { return 1; } #line 466 "./src/package_registry.am" if (String_EndsWith(path, ".cc")) { return 1; } #line 467 "./src/package_registry.am" if (String_EndsWith(path, ".cxx")) { return 1; } #line 468 "./src/package_registry.am" return 0; } code_string Amalgame_Compiler_PackageRegistry_AmalgameHome() { #line 487 "./src/package_registry.am" code_string override = Env_Get("AMALGAME_HOME"); #line 488 "./src/package_registry.am" if (String_Length(override) > 0LL) { return override; } #line 489 "./src/package_registry.am" code_string home = Env_Get("HOME"); #line 490 "./src/package_registry.am" if (String_Length(home) > 0LL) { return home; } #line 491 "./src/package_registry.am" code_string userProfile = Env_Get("USERPROFILE"); #line 492 "./src/package_registry.am" if (String_Length(userProfile) > 0LL) { return userProfile; } #line 493 "./src/package_registry.am" return ""; } code_string Amalgame_Compiler_PackageRegistry_AmalgameStateDir() { #line 501 "./src/package_registry.am" code_string home = Amalgame_Compiler_PackageRegistry_AmalgameHome(); #line 502 "./src/package_registry.am" if (String_Length(home) == 0LL) { return ""; } #line 503 "./src/package_registry.am" return Path_Combine(home, ".amalgame"); } code_string Amalgame_Compiler_PackageRegistry_DefaultCacheRoot() { #line 516 "./src/package_registry.am" code_string envOverride = Env_Get("AMALGAME_PACKAGES_DIR"); #line 517 "./src/package_registry.am" if (String_Length(envOverride) > 0LL) { #line 518 "./src/package_registry.am" return envOverride; } #line 520 "./src/package_registry.am" code_string stateDir = Amalgame_Compiler_PackageRegistry_AmalgameStateDir(); #line 521 "./src/package_registry.am" if (String_Length(stateDir) > 0LL) { #line 522 "./src/package_registry.am" return Path_Combine(stateDir, "packages"); } #line 524 "./src/package_registry.am" return "/tmp/amalgame-packages"; } code_string Amalgame_Compiler_PackageRegistry_CalibrationPath() { #line 531 "./src/package_registry.am" code_string stateDir = Amalgame_Compiler_PackageRegistry_AmalgameStateDir(); #line 532 "./src/package_registry.am" if (String_Length(stateDir) == 0LL) { return ""; } #line 533 "./src/package_registry.am" return Path_Combine(stateDir, "calibration.toml"); } code_string Amalgame_Compiler_PackageRegistry_PrecompileCacheDir(code_string pkgDir) { #line 544 "./src/package_registry.am" code_string p = Amalgame_Compiler_PackageRegistry_PlatformTag(); #line 545 "./src/package_registry.am" code_string buildDir = Path_Combine(pkgDir, "build"); #line 546 "./src/package_registry.am" return Path_Combine(buildDir, p); } code_string Amalgame_Compiler_PackageRegistry_PlatformTag() { #line 557 "./src/package_registry.am" { /* inline-C */ #ifdef _WIN32 return (code_string) "windows-x86_64"; #endif } #line 565 "./src/package_registry.am" code_string unameS = String_Trim(Process_RunCapture("uname -s")->Stdout); #line 566 "./src/package_registry.am" code_string unameM = String_Trim(Process_RunCapture("uname -m")->Stdout); #line 567 "./src/package_registry.am" code_string os = "unknown"; #line 568 "./src/package_registry.am" if (String_StartsWith(unameS, "Linux")) { os = "linux"; } #line 569 "./src/package_registry.am" if (String_StartsWith(unameS, "Darwin")) { os = "macos"; } #line 570 "./src/package_registry.am" if (String_StartsWith(unameS, "MINGW")) { os = "windows"; } #line 571 "./src/package_registry.am" if (String_StartsWith(unameS, "MSYS")) { os = "windows"; } #line 572 "./src/package_registry.am" if (String_StartsWith(unameS, "CYGWIN")) { os = "windows"; } #line 573 "./src/package_registry.am" code_string arch = unameM; #line 574 "./src/package_registry.am" if (code_string_equals(arch, "")) { arch = "unknown"; } #line 575 "./src/package_registry.am" if (code_string_equals(arch, "amd64")) { arch = "x86_64"; } #line 576 "./src/package_registry.am" if (code_string_equals(arch, "aarch64")) { arch = "arm64"; } #line 577 "./src/package_registry.am" return code_string_concat((code_string_concat(os, "-")), arch); } code_string Amalgame_Compiler_PackageRegistry_ManglePackageSymbol(code_string ns, code_string method) { #line 595 "./src/package_registry.am" code_string mangledNs = String_Replace(ns, ".", "_"); #line 596 "./src/package_registry.am" return code_string_concat((code_string_concat(mangledNs, "_")), method); } code_string Amalgame_Compiler_PackageRegistry_AmalgameTypeFromC(code_string cType) { #line 604 "./src/package_registry.am" i64 n = String_Length(cType); #line 605 "./src/package_registry.am" if (n == 0LL) { return ""; } #line 606 "./src/package_registry.am" if (String_EndsWith(cType, "*")) { #line 607 "./src/package_registry.am" return String_Substring(cType, 0LL, n - 1LL); } #line 609 "./src/package_registry.am" return cType; } code_string Amalgame_Compiler_PackageRegistry_AmcVersion() { #line 620 "./src/package_registry.am" return "0.8.90"; } i64 Amalgame_Compiler_PackageRegistry_SupportedManifestSchema() { #line 633 "./src/package_registry.am" return 1LL; } AmalgameList* Amalgame_Compiler_PackageRegistry_ParseVersion(code_string v) { #line 641 "./src/package_registry.am" AmalgameList* out = AmalgameList_new(); #line 643 "./src/package_registry.am" code_string s = v; #line 644 "./src/package_registry.am" if (String_StartsWith(s, "v")) { #line 645 "./src/package_registry.am" s = String_Substring(s, 1LL, String_Length(s) - 1LL); } #line 648 "./src/package_registry.am" i64 dashIdx = String_IndexOf(s, "-"); #line 649 "./src/package_registry.am" if (dashIdx >= 0LL) { #line 650 "./src/package_registry.am" s = String_Substring(s, 0LL, dashIdx); } #line 652 "./src/package_registry.am" i64 plusIdx = String_IndexOf(s, "+"); #line 653 "./src/package_registry.am" if (plusIdx >= 0LL) { #line 654 "./src/package_registry.am" s = String_Substring(s, 0LL, plusIdx); } #line 656 "./src/package_registry.am" AmalgameList* parts = String_Split(s, "."); #line 657 "./src/package_registry.am" i64 n = AmalgameList_count(parts); #line 658 "./src/package_registry.am" i64 maj = 0LL; #line 659 "./src/package_registry.am" i64 min = 0LL; #line 660 "./src/package_registry.am" i64 pat = 0LL; #line 661 "./src/package_registry.am" if (n >= 1LL) { maj = String_ToInt((code_string)AmalgameList_get(parts, 0LL)); } #line 662 "./src/package_registry.am" if (n >= 2LL) { min = String_ToInt((code_string)AmalgameList_get(parts, 1LL)); } #line 663 "./src/package_registry.am" if (n >= 3LL) { pat = String_ToInt((code_string)AmalgameList_get(parts, 2LL)); } #line 664 "./src/package_registry.am" AmalgameList_add(out, (void*)(intptr_t)(maj)); #line 665 "./src/package_registry.am" AmalgameList_add(out, (void*)(intptr_t)(min)); #line 666 "./src/package_registry.am" AmalgameList_add(out, (void*)(intptr_t)(pat)); #line 667 "./src/package_registry.am" return out; } code_string Amalgame_Compiler_PackageRegistry_ReadCalibrationFile() { #line 678 "./src/package_registry.am" code_string path = Amalgame_Compiler_PackageRegistry_CalibrationPath(); #line 679 "./src/package_registry.am" if (String_Length(path) == 0LL) { return ""; } #line 680 "./src/package_registry.am" if (!File_Exists(path)) { return ""; } #line 681 "./src/package_registry.am" return File_ReadAll(path); } code_bool Amalgame_Compiler_PackageRegistry_VersionSatisfies(code_string current, code_string constraint) { #line 701 "./src/package_registry.am" if (String_Length(constraint) == 0LL) { return 1; } #line 702 "./src/package_registry.am" code_string c = String_Trim(constraint); #line 705 "./src/package_registry.am" if (String_StartsWith(c, ">=")) { #line 706 "./src/package_registry.am" return Amalgame_Compiler_PackageRegistry_CompareCmp(current, String_Substring(c, 2LL, String_Length(c) - 2LL)) >= 0LL; } #line 708 "./src/package_registry.am" if (String_StartsWith(c, "<=")) { #line 709 "./src/package_registry.am" return Amalgame_Compiler_PackageRegistry_CompareCmp(current, String_Substring(c, 2LL, String_Length(c) - 2LL)) <= 0LL; } #line 711 "./src/package_registry.am" if (String_StartsWith(c, ">")) { #line 712 "./src/package_registry.am" return Amalgame_Compiler_PackageRegistry_CompareCmp(current, String_Substring(c, 1LL, String_Length(c) - 1LL)) > 0LL; } #line 714 "./src/package_registry.am" if (String_StartsWith(c, "<")) { #line 715 "./src/package_registry.am" return Amalgame_Compiler_PackageRegistry_CompareCmp(current, String_Substring(c, 1LL, String_Length(c) - 1LL)) < 0LL; } #line 717 "./src/package_registry.am" if (String_StartsWith(c, "=")) { #line 718 "./src/package_registry.am" return Amalgame_Compiler_PackageRegistry_CompareCmp(current, String_Substring(c, 1LL, String_Length(c) - 1LL)) == 0LL; } #line 720 "./src/package_registry.am" if (String_StartsWith(c, "^")) { #line 721 "./src/package_registry.am" return Amalgame_Compiler_PackageRegistry_CaretSatisfies(current, String_Substring(c, 1LL, String_Length(c) - 1LL)); } #line 723 "./src/package_registry.am" if (String_StartsWith(c, "~")) { #line 724 "./src/package_registry.am" return Amalgame_Compiler_PackageRegistry_TildeSatisfies(current, String_Substring(c, 1LL, String_Length(c) - 1LL)); } #line 729 "./src/package_registry.am" return Amalgame_Compiler_PackageRegistry_CompareCmp(current, c) >= 0LL; } i64 Amalgame_Compiler_PackageRegistry_CompareCmp(code_string a, code_string b) { #line 736 "./src/package_registry.am" AmalgameList* pa = Amalgame_Compiler_PackageRegistry_ParseVersion(a); #line 737 "./src/package_registry.am" AmalgameList* pb = Amalgame_Compiler_PackageRegistry_ParseVersion(b); #line 738 "./src/package_registry.am" if ((i64)(intptr_t)AmalgameList_get(pa, 0LL) != (i64)(intptr_t)AmalgameList_get(pb, 0LL)) { return (i64)(intptr_t)AmalgameList_get(pa, 0LL) - (i64)(intptr_t)AmalgameList_get(pb, 0LL); } #line 739 "./src/package_registry.am" if ((i64)(intptr_t)AmalgameList_get(pa, 1LL) != (i64)(intptr_t)AmalgameList_get(pb, 1LL)) { return (i64)(intptr_t)AmalgameList_get(pa, 1LL) - (i64)(intptr_t)AmalgameList_get(pb, 1LL); } #line 740 "./src/package_registry.am" return (i64)(intptr_t)AmalgameList_get(pa, 2LL) - (i64)(intptr_t)AmalgameList_get(pb, 2LL); } code_bool Amalgame_Compiler_PackageRegistry_CaretSatisfies(code_string current, code_string base) { #line 751 "./src/package_registry.am" AmalgameList* cur = Amalgame_Compiler_PackageRegistry_ParseVersion(current); #line 752 "./src/package_registry.am" AmalgameList* req = Amalgame_Compiler_PackageRegistry_ParseVersion(base); #line 754 "./src/package_registry.am" if (Amalgame_Compiler_PackageRegistry_CompareCmp(current, base) < 0LL) { return 0; } #line 756 "./src/package_registry.am" if ((i64)(intptr_t)AmalgameList_get(req, 0LL) > 0LL) { #line 758 "./src/package_registry.am" return (i64)(intptr_t)AmalgameList_get(cur, 0LL) == (i64)(intptr_t)AmalgameList_get(req, 0LL); } #line 760 "./src/package_registry.am" if ((i64)(intptr_t)AmalgameList_get(req, 1LL) > 0LL) { #line 762 "./src/package_registry.am" return ((i64)(intptr_t)AmalgameList_get(cur, 0LL) == 0LL) && ((i64)(intptr_t)AmalgameList_get(cur, 1LL) == (i64)(intptr_t)AmalgameList_get(req, 1LL)); } #line 765 "./src/package_registry.am" return (((i64)(intptr_t)AmalgameList_get(cur, 0LL) == 0LL) && ((i64)(intptr_t)AmalgameList_get(cur, 1LL) == 0LL)) && ((i64)(intptr_t)AmalgameList_get(cur, 2LL) == (i64)(intptr_t)AmalgameList_get(req, 2LL)); } code_bool Amalgame_Compiler_PackageRegistry_TildeSatisfies(code_string current, code_string base) { #line 772 "./src/package_registry.am" AmalgameList* cur = Amalgame_Compiler_PackageRegistry_ParseVersion(current); #line 773 "./src/package_registry.am" AmalgameList* req = Amalgame_Compiler_PackageRegistry_ParseVersion(base); #line 774 "./src/package_registry.am" if (Amalgame_Compiler_PackageRegistry_CompareCmp(current, base) < 0LL) { return 0; } #line 775 "./src/package_registry.am" return ((i64)(intptr_t)AmalgameList_get(cur, 0LL) == (i64)(intptr_t)AmalgameList_get(req, 0LL)) && ((i64)(intptr_t)AmalgameList_get(cur, 1LL) == (i64)(intptr_t)AmalgameList_get(req, 1LL)); } struct _Amalgame_Compiler_CalibrationSample { code_string Lang; i64 SizeKb; i64 ElapsedS; code_string PkgVer; }; Amalgame_Compiler_CalibrationSample* Amalgame_Compiler_CalibrationSample_new() { Amalgame_Compiler_CalibrationSample* self = (Amalgame_Compiler_CalibrationSample*) GC_MALLOC(sizeof(Amalgame_Compiler_CalibrationSample)); #line 791 "./src/package_registry.am" self->Lang = ""; #line 792 "./src/package_registry.am" self->SizeKb = 0LL; #line 793 "./src/package_registry.am" self->ElapsedS = 0LL; #line 794 "./src/package_registry.am" self->PkgVer = ""; return self; } struct _Amalgame_Compiler_Calibration { AmalgameList* Samples; }; Amalgame_Compiler_Calibration* Amalgame_Compiler_Calibration_Load(); void Amalgame_Compiler_Calibration_Add(Amalgame_Compiler_Calibration* self, code_string lang, i64 sizeKb, i64 elapsedS, code_string pkgVer); i64 Amalgame_Compiler_Calibration_EstimateSeconds(Amalgame_Compiler_Calibration* self, code_string lang, i64 sizeKb); i64 Amalgame_Compiler_Calibration_SampleCount(Amalgame_Compiler_Calibration* self, code_string lang); code_bool Amalgame_Compiler_Calibration_Save(Amalgame_Compiler_Calibration* self); Amalgame_Compiler_Calibration* Amalgame_Compiler_Calibration_new() { Amalgame_Compiler_Calibration* self = (Amalgame_Compiler_Calibration*) GC_MALLOC(sizeof(Amalgame_Compiler_Calibration)); #line 821 "./src/package_registry.am" self->Samples = AmalgameList_new(); return self; } Amalgame_Compiler_Calibration* Amalgame_Compiler_Calibration_Load() { #line 829 "./src/package_registry.am" Amalgame_Compiler_Calibration* cal = Amalgame_Compiler_Calibration_new(); #line 830 "./src/package_registry.am" code_string raw = Amalgame_Compiler_PackageRegistry_ReadCalibrationFile(); #line 831 "./src/package_registry.am" if (String_Length(raw) == 0LL) { return cal; } #line 832 "./src/package_registry.am" Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(raw); #line 833 "./src/package_registry.am" if (Amalgame_Compiler_TomlValue_IsNull(doc)) { return cal; } #line 836 "./src/package_registry.am" Amalgame_Compiler_TomlValue* schemaVal = Amalgame_Compiler_TomlValue_Get(doc, "schema-version"); #line 837 "./src/package_registry.am" if (Amalgame_Compiler_TomlValue_AsInt(schemaVal) > 1LL) { return cal; } #line 838 "./src/package_registry.am" Amalgame_Compiler_TomlValue* arr = Amalgame_Compiler_TomlValue_Get(doc, "sample"); #line 839 "./src/package_registry.am" if (!Amalgame_Compiler_TomlValue_IsArray(arr)) { return cal; } #line 840 "./src/package_registry.am" i64 n = Amalgame_Compiler_TomlValue_Count(arr); #line 841 "./src/package_registry.am" for (i64 i = 0LL; i < n; i++) { #line 842 "./src/package_registry.am" Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(arr, i); #line 843 "./src/package_registry.am" Amalgame_Compiler_CalibrationSample* s = Amalgame_Compiler_CalibrationSample_new(); #line 844 "./src/package_registry.am" s->Lang = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "lang")); #line 845 "./src/package_registry.am" s->SizeKb = Amalgame_Compiler_TomlValue_AsInt(Amalgame_Compiler_TomlValue_Get(entry, "size_kb")); #line 846 "./src/package_registry.am" s->ElapsedS = Amalgame_Compiler_TomlValue_AsInt(Amalgame_Compiler_TomlValue_Get(entry, "elapsed_s")); #line 847 "./src/package_registry.am" s->PkgVer = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "pkg_ver")); #line 848 "./src/package_registry.am" if (String_Length(s->Lang) == 0LL) { continue; } #line 849 "./src/package_registry.am" if ((s->SizeKb <= 0LL) || (s->ElapsedS <= 0LL)) { continue; } #line 850 "./src/package_registry.am" AmalgameList_add(cal->Samples, (void*)(intptr_t)(s)); } #line 852 "./src/package_registry.am" return cal; } void Amalgame_Compiler_Calibration_Add(Amalgame_Compiler_Calibration* self, code_string lang, i64 sizeKb, i64 elapsedS, code_string pkgVer) { #line 859 "./src/package_registry.am" Amalgame_Compiler_CalibrationSample* s = Amalgame_Compiler_CalibrationSample_new(); #line 860 "./src/package_registry.am" s->Lang = lang; #line 861 "./src/package_registry.am" s->SizeKb = sizeKb; #line 862 "./src/package_registry.am" s->ElapsedS = elapsedS; #line 863 "./src/package_registry.am" s->PkgVer = pkgVer; #line 864 "./src/package_registry.am" AmalgameList_add(self->Samples, (void*)(intptr_t)(s)); } i64 Amalgame_Compiler_Calibration_EstimateSeconds(Amalgame_Compiler_Calibration* self, code_string lang, i64 sizeKb) { #line 871 "./src/package_registry.am" i64 totalKb = 0LL; #line 872 "./src/package_registry.am" i64 totalSec = 0LL; #line 873 "./src/package_registry.am" i64 n = AmalgameList_count(self->Samples); #line 874 "./src/package_registry.am" for (i64 i = 0LL; i < n; i++) { #line 875 "./src/package_registry.am" Amalgame_Compiler_CalibrationSample* s = (Amalgame_Compiler_CalibrationSample*)AmalgameList_get(self->Samples, i); #line 876 "./src/package_registry.am" if (code_string_equals(s->Lang, lang)) { #line 877 "./src/package_registry.am" totalKb = (totalKb + s->SizeKb); #line 878 "./src/package_registry.am" totalSec = (totalSec + s->ElapsedS); } } #line 881 "./src/package_registry.am" if (totalKb <= 0LL) { return -1LL; } #line 882 "./src/package_registry.am" return (sizeKb * totalSec) / totalKb; } i64 Amalgame_Compiler_Calibration_SampleCount(Amalgame_Compiler_Calibration* self, code_string lang) { #line 886 "./src/package_registry.am" i64 n = 0LL; #line 887 "./src/package_registry.am" i64 len = AmalgameList_count(self->Samples); #line 888 "./src/package_registry.am" for (i64 i = 0LL; i < len; i++) { #line 889 "./src/package_registry.am" Amalgame_Compiler_CalibrationSample* s = (Amalgame_Compiler_CalibrationSample*)AmalgameList_get(self->Samples, i); #line 890 "./src/package_registry.am" if (code_string_equals(s->Lang, lang)) { n = (n + 1LL); } } #line 892 "./src/package_registry.am" return n; } code_bool Amalgame_Compiler_Calibration_Save(Amalgame_Compiler_Calibration* self) { #line 899 "./src/package_registry.am" code_string path = Amalgame_Compiler_PackageRegistry_CalibrationPath(); #line 900 "./src/package_registry.am" if (String_Length(path) == 0LL) { return 0; } #line 901 "./src/package_registry.am" code_string stateDir = Amalgame_Compiler_PackageRegistry_AmalgameStateDir(); #line 902 "./src/package_registry.am" if (String_Length(stateDir) > 0LL) { #line 906 "./src/package_registry.am" Process_RunCapture(code_string_concat((code_string_concat("mkdir -p '", stateDir)), "'")); } #line 908 "./src/package_registry.am" code_string s = "# Amalgame calibration store — auto-managed by `amc package add`.\n"; #line 909 "./src/package_registry.am" s = (code_string_concat(s, "# Each precompile contributes a sample; the weighted average\n")); #line 910 "./src/package_registry.am" s = (code_string_concat(s, "# across samples of the same language drives ETA.\n")); #line 911 "./src/package_registry.am" s = (code_string_concat(s, "schema-version = 1\n\n")); #line 912 "./src/package_registry.am" i64 n = AmalgameList_count(self->Samples); #line 913 "./src/package_registry.am" for (i64 i = 0LL; i < n; i++) { #line 914 "./src/package_registry.am" Amalgame_Compiler_CalibrationSample* sm = (Amalgame_Compiler_CalibrationSample*)AmalgameList_get(self->Samples, i); #line 915 "./src/package_registry.am" s = (code_string_concat(s, "[[sample]]\n")); #line 916 "./src/package_registry.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "lang = \"")), sm->Lang)), "\"\n")); #line 917 "./src/package_registry.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "size_kb = ")), String_FromInt(sm->SizeKb))), "\n")); #line 918 "./src/package_registry.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "elapsed_s = ")), String_FromInt(sm->ElapsedS))), "\n")); #line 919 "./src/package_registry.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "pkg_ver = \"")), sm->PkgVer)), "\"\n")); #line 920 "./src/package_registry.am" s = (code_string_concat(s, "\n")); } #line 922 "./src/package_registry.am" return File_WriteAll(path, s); } struct _Amalgame_Compiler_Emitter { AmalgameList* Lines; i64 Indent; code_bool Streaming; }; void Amalgame_Compiler_Emitter_SetStreaming(Amalgame_Compiler_Emitter* self, code_bool v); void Amalgame_Compiler_Emitter_Emit(Amalgame_Compiler_Emitter* self, code_string text); void Amalgame_Compiler_Emitter_EmitLine(Amalgame_Compiler_Emitter* self, code_string text); void Amalgame_Compiler_Emitter_EmitBlank(Amalgame_Compiler_Emitter* self); void Amalgame_Compiler_Emitter_Indent_(Amalgame_Compiler_Emitter* self); void Amalgame_Compiler_Emitter_Dedent(Amalgame_Compiler_Emitter* self); code_string Amalgame_Compiler_Emitter_GetOutput(Amalgame_Compiler_Emitter* self); Amalgame_Compiler_Emitter* Amalgame_Compiler_Emitter_new() { Amalgame_Compiler_Emitter* self = (Amalgame_Compiler_Emitter*) GC_MALLOC(sizeof(Amalgame_Compiler_Emitter)); #line 13 "./src/generator/c_gen.am" self->Lines = AmalgameList_new(); #line 14 "./src/generator/c_gen.am" self->Indent = 0LL; #line 15 "./src/generator/c_gen.am" self->Streaming = 0; return self; } void Amalgame_Compiler_Emitter_SetStreaming(Amalgame_Compiler_Emitter* self, code_bool v) { #line 18 "./src/generator/c_gen.am" self->Streaming = v; } void Amalgame_Compiler_Emitter_Emit(Amalgame_Compiler_Emitter* self, code_string text) { #line 21 "./src/generator/c_gen.am" if (self->Streaming) { #line 22 "./src/generator/c_gen.am" File_StreamLine(text); } else { #line 24 "./src/generator/c_gen.am" AmalgameList_add(self->Lines, (void*)(intptr_t)(text)); } } void Amalgame_Compiler_Emitter_EmitLine(Amalgame_Compiler_Emitter* self, code_string text) { #line 29 "./src/generator/c_gen.am" code_string line = ""; #line 30 "./src/generator/c_gen.am" i64 i = self->Indent; #line 31 "./src/generator/c_gen.am" for (i64 k = 0LL; k < i; k++) { #line 32 "./src/generator/c_gen.am" line = (code_string_concat(line, " ")); } #line 34 "./src/generator/c_gen.am" line = (code_string_concat(line, text)); #line 35 "./src/generator/c_gen.am" if (self->Streaming) { #line 36 "./src/generator/c_gen.am" File_StreamLine(line); } else { #line 38 "./src/generator/c_gen.am" AmalgameList_add(self->Lines, (void*)(intptr_t)(line)); } } void Amalgame_Compiler_Emitter_EmitBlank(Amalgame_Compiler_Emitter* self) { #line 43 "./src/generator/c_gen.am" if (self->Streaming) { #line 44 "./src/generator/c_gen.am" File_StreamLine(""); } else { #line 46 "./src/generator/c_gen.am" AmalgameList_add(self->Lines, (void*)(intptr_t)("")); } } void Amalgame_Compiler_Emitter_Indent_(Amalgame_Compiler_Emitter* self) { #line 51 "./src/generator/c_gen.am" self->Indent = (self->Indent + 1LL); } void Amalgame_Compiler_Emitter_Dedent(Amalgame_Compiler_Emitter* self) { #line 55 "./src/generator/c_gen.am" self->Indent = (self->Indent - 1LL); } code_string Amalgame_Compiler_Emitter_GetOutput(Amalgame_Compiler_Emitter* self) { #line 59 "./src/generator/c_gen.am" code_string result = ""; #line 60 "./src/generator/c_gen.am" i64 count = AmalgameList_count(self->Lines); #line 61 "./src/generator/c_gen.am" for (i64 i = 0LL; i < count; i++) { #line 62 "./src/generator/c_gen.am" code_string line = (code_string)AmalgameList_get(self->Lines, i); #line 63 "./src/generator/c_gen.am" result = (code_string_concat((code_string_concat(result, line)), "\n")); } #line 65 "./src/generator/c_gen.am" return result; } struct _Amalgame_Compiler_CGen { Amalgame_Compiler_Emitter* Out; code_string NsPrefix; AmalgameList* LocalTypeNames; AmalgameList* LocalTypeCType; code_string CurrentClass; code_string CurrentRetType; AmalgameList* FieldNames; AmalgameList* FieldCTypes; AmalgameList* ListElemNames; AmalgameList* ListElemCTypes; AmalgameList* EnumNames; AmalgameList* MethodRetNames; AmalgameList* MethodRetTypes; AmalgameList* MethodRetRawNames; AmalgameList* MethodRetRawTypes; AmalgameList* MethodVariadicNames; AmalgameList* MethodVariadicArity; i64 LambdaCounter; code_bool InLambdaBody; code_string CurrentSource; i64 LastLineEmitted; AmalgameList* InferCacheKeys; AmalgameList* InferCacheVals; AmalgameList* PkgClasses; AmalgameList* PkgFuncs; AmalgameList* PkgFuncCTypes; AmalgameList* PkgHeaders; AmalgameList* PkgHeaderNs; AmalgameList* PkgClassNs; AmalgameList* ImportedNs; code_bool ImportsFiltered; code_bool Embedded; AmalgameList* ExternalClasses; AmalgameList* ExternalClassNsArr; AmalgameList* ExternalEnums; AmalgameList* ExternalEnumNsArr; AmalgameList* PkgOpaqueTypes; AmalgameList* LocalClasses; AmalgameList* IfaceShortNames; AmalgameList* IfaceMangledNames; AmalgameList* IfaceNodes; AmalgameList* ParamIfaceKeys; AmalgameList* ParamIfaceVals; }; code_string Amalgame_Compiler_CGen_Generate(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); void Amalgame_Compiler_CGen_SetStreaming(Amalgame_Compiler_CGen* self, code_bool v); void Amalgame_Compiler_CGen_BeginMulti(Amalgame_Compiler_CGen* self, code_string ns); void Amalgame_Compiler_CGen_AddFilePass1(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); void Amalgame_Compiler_CGen_EmitSeparator(Amalgame_Compiler_CGen* self); void Amalgame_Compiler_CGen_AddFilePass2(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog, code_string sourcePath); void Amalgame_Compiler_CGen_AddFilePass2Forwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); void Amalgame_Compiler_CGen_AddFilePass2Bodies(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog, code_string sourcePath); static void Amalgame_Compiler_CGen_EmitMethodForwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); static void Amalgame_Compiler_CGen_EmitConstructorForwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); static void Amalgame_Compiler_CGen_EmitLambdaForwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* node); static void Amalgame_Compiler_CGen_EmitLambdaBodies(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* node); static void Amalgame_Compiler_CGen_EmitOneLambdaForward(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* lam); static void Amalgame_Compiler_CGen_EmitOneLambdaBody(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* lam); code_string Amalgame_Compiler_CGen_FinishMulti(Amalgame_Compiler_CGen* self); AmalgameList* Amalgame_Compiler_CGen_GetLines(Amalgame_Compiler_CGen* self); static code_string Amalgame_Compiler_CGen_SymName(Amalgame_Compiler_CGen* self, code_string name); static void Amalgame_Compiler_CGen_LocalTypeSet(Amalgame_Compiler_CGen* self, code_string varName, code_string ctype); static code_string Amalgame_Compiler_CGen_LocalTypeGet(Amalgame_Compiler_CGen* self, code_string varName); static void Amalgame_Compiler_CGen_LocalTypeClear(Amalgame_Compiler_CGen* self); static void Amalgame_Compiler_CGen_FieldTypeSet(Amalgame_Compiler_CGen* self, code_string className, code_string fieldName, code_string ctype); static code_string Amalgame_Compiler_CGen_FieldTypeGet(Amalgame_Compiler_CGen* self, code_string className, code_string fieldName); static code_string Amalgame_Compiler_CGen_ResolveReceiverClass(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* node); static void Amalgame_Compiler_CGen_TrackMapResultElem(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_CGen_TrackGenericLocal(Amalgame_Compiler_CGen* self, code_string varName, code_string rawType); static code_string Amalgame_Compiler_CGen_PeelOneGenericLayer(Amalgame_Compiler_CGen* self, code_string rawType); static code_string Amalgame_Compiler_CGen_RecoverChainedListElemRaw(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* recv); static void Amalgame_Compiler_CGen_ListElemSet(Amalgame_Compiler_CGen* self, code_string className, code_string fieldName, code_string elemCType); static code_string Amalgame_Compiler_CGen_ListElemGet(Amalgame_Compiler_CGen* self, code_string className, code_string fieldName); static void Amalgame_Compiler_CGen_MethodRetSet(Amalgame_Compiler_CGen* self, code_string className, code_string methodName, code_string ctype); static void Amalgame_Compiler_CGen_MethodRetRawSet(Amalgame_Compiler_CGen* self, code_string className, code_string methodName, code_string rawType); static code_string Amalgame_Compiler_CGen_MethodRetRawGet(Amalgame_Compiler_CGen* self, code_string className, code_string methodName); static code_string Amalgame_Compiler_CGen_MethodRetGet(Amalgame_Compiler_CGen* self, code_string className, code_string methodName); static void Amalgame_Compiler_CGen_MethodVariadicSet(Amalgame_Compiler_CGen* self, code_string cname, i64 fixedArity); static i64 Amalgame_Compiler_CGen_MethodVariadicGet(Amalgame_Compiler_CGen* self, code_string cname); static code_string Amalgame_Compiler_CGen_InferTypeFromExpr(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* expr); static code_string Amalgame_Compiler_CGen_InferTypeFromExprUncached(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* expr); static code_bool Amalgame_Compiler_CGen_IsValidInterpExpr(Amalgame_Compiler_CGen* self, code_string s); static code_string Amalgame_Compiler_CGen_EmitInterpolatedString(Amalgame_Compiler_CGen* self, code_string raw); static code_string Amalgame_Compiler_CGen_WrapForInterp(Amalgame_Compiler_CGen* self, code_string cExpr, code_string cType); static code_string Amalgame_Compiler_CGen_BuiltinCallReturnType(Amalgame_Compiler_CGen* self, code_string cName); static code_string Amalgame_Compiler_CGen_InterpExprToC(Amalgame_Compiler_CGen* self, code_string expr); static code_string Amalgame_Compiler_CGen_EscapeStringForC(Amalgame_Compiler_CGen* self, code_string raw); static void Amalgame_Compiler_CGen_EmitHeader(Amalgame_Compiler_CGen* self); code_bool Amalgame_Compiler_CGen_NamespaceImported(Amalgame_Compiler_CGen* self, code_string ns); void Amalgame_Compiler_CGen_SetImportedNamespaces(Amalgame_Compiler_CGen* self, AmalgameList* imports); void Amalgame_Compiler_CGen_SetEmbedded(Amalgame_Compiler_CGen* self, code_bool v); static code_string Amalgame_Compiler_CGen_AllocFn(Amalgame_Compiler_CGen* self); void Amalgame_Compiler_CGen_EmitNetHeader(Amalgame_Compiler_CGen* self); void Amalgame_Compiler_CGen_RegisterPackages(Amalgame_Compiler_CGen* self, Amalgame_Compiler_PackageRegistry* reg); void Amalgame_Compiler_CGen_RegisterExternalProg(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); void Amalgame_Compiler_CGen_RegisterExternalProgPass1(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); void Amalgame_Compiler_CGen_RegisterExternalProgPass2(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); static code_string Amalgame_Compiler_CGen_ExternalMethodSig(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string mangledClass, code_string shortClassName); code_string Amalgame_Compiler_CGen_ExternalClassMangled(Amalgame_Compiler_CGen* self, code_string tname); code_string Amalgame_Compiler_CGen_ExternalEnumMangled(Amalgame_Compiler_CGen* self, code_string tname); static code_bool Amalgame_Compiler_CGen_IsExternalClass(Amalgame_Compiler_CGen* self, code_string tname); static AmalgameList* Amalgame_Compiler_CGen_SplitTopLevelCommas(Amalgame_Compiler_CGen* self, code_string s); static code_bool Amalgame_Compiler_CGen_IsLocalClass(Amalgame_Compiler_CGen* self, code_string tname); static void Amalgame_Compiler_CGen_RegisterIface(Amalgame_Compiler_CGen* self, code_string shortName, code_string mangled, Amalgame_Compiler_AstNode* node); void Amalgame_Compiler_CGen_PreNoteInterfaces(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog); static code_bool Amalgame_Compiler_CGen_IsInterface(Amalgame_Compiler_CGen* self, code_string tname); static code_string Amalgame_Compiler_CGen_IfaceMangledFor(Amalgame_Compiler_CGen* self, code_string tname); static Amalgame_Compiler_AstNode* Amalgame_Compiler_CGen_IfaceNodeFor(Amalgame_Compiler_CGen* self, code_string nameOrMangled); static code_string Amalgame_Compiler_CGen_IfaceItabSym(Amalgame_Compiler_CGen* self, code_string classMangled, code_string ifaceMangled); static code_string Amalgame_Compiler_CGen_IfaceFnPtrField(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* m); static code_string Amalgame_Compiler_CGen_IfaceFnPtrCast(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* m); static void Amalgame_Compiler_CGen_RegisterParamIfaces(Amalgame_Compiler_CGen* self, code_string mangled, Amalgame_Compiler_AstNode* m); static code_string Amalgame_Compiler_CGen_CoerceArg(Amalgame_Compiler_CGen* self, code_string callee, i64 idx, Amalgame_Compiler_AstNode* argExpr); static code_string Amalgame_Compiler_CGen_CoerceToIface(Amalgame_Compiler_CGen* self, code_string ifaceMangled, Amalgame_Compiler_AstNode* argExpr); static code_string Amalgame_Compiler_CGen_BoxIface(Amalgame_Compiler_CGen* self, code_string ifaceMangled, code_string fatExpr); static code_string Amalgame_Compiler_CGen_ResolveListElemC(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* callee); static code_string Amalgame_Compiler_CGen_PkgClassMangledPrefix(Amalgame_Compiler_CGen* self, code_string tname); static code_string Amalgame_Compiler_CGen_ClassMangledFor(Amalgame_Compiler_CGen* self, code_string tname); static void Amalgame_Compiler_CGen_EmitForwardDecl(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_CGen_EmitDecl(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_CGen_EmitEnum(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* en); static void Amalgame_Compiler_CGen_EmitClass(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* cls); static void Amalgame_Compiler_CGen_EmitClassItabs(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* cls, code_string name); static code_string Amalgame_Compiler_CGen_TupleStructName(Amalgame_Compiler_CGen* self, code_string tupleType); static void Amalgame_Compiler_CGen_EnsureTupleStruct(Amalgame_Compiler_CGen* self, code_string tupleType); static code_string Amalgame_Compiler_CGen_MethodSig(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string className); static code_string Amalgame_Compiler_CGen_AsyncEnvName(Amalgame_Compiler_CGen* self, code_string mangledClass, code_string mname); static code_string Amalgame_Compiler_CGen_AsyncImplSig(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string className); static code_string Amalgame_Compiler_CGen_AsyncWrapperSig(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string className); static code_string Amalgame_Compiler_CGen_AsyncRetCType(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method); static void Amalgame_Compiler_CGen_EmitAsyncForwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string mangledClass); static void Amalgame_Compiler_CGen_EmitAsyncMethod(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string mangledClass); static code_string Amalgame_Compiler_CGen_BoxAsVoidI64(Amalgame_Compiler_CGen* self, code_string expr); static code_string Amalgame_Compiler_CGen_ResolveAwaitRetC(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* operand); static void Amalgame_Compiler_CGen_EmitMethod(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string className); static code_string Amalgame_Compiler_CGen_EmitIfBranch(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* block); static void Amalgame_Compiler_CGen_EmitMatch(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_CGen_EmitMatchBody(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* body); static void Amalgame_Compiler_CGen_EmitIf(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_CGen_EmitIfTail(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_CGen_EmitBlock(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* block); static void Amalgame_Compiler_CGen_EmitLineDirective(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_CGen_EmitStmt(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt); static code_string Amalgame_Compiler_CGen_EmitExprStr(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* expr); static code_string Amalgame_Compiler_CGen_EmitListLiteral(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_CGen_EmitVariadicTail(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* call, i64 fixedArity); static code_string Amalgame_Compiler_CGen_EmitMatchExpr(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_CGen_EmitListComp(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_CGen_TryEmitListCall(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* callExpr); static code_string Amalgame_Compiler_CGen_EmitClosureArg(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* arg); static code_string Amalgame_Compiler_CGen_EmitLambdaAsClosure(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* lam); static code_string Amalgame_Compiler_CGen_EmitLambdaCaptureCopy(Amalgame_Compiler_CGen* self, code_string envVar, Amalgame_Compiler_AstNode* cap); static code_string Amalgame_Compiler_CGen_EmitCalleeStr(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* callee); static code_bool Amalgame_Compiler_CGen_IsEnum(Amalgame_Compiler_CGen* self, code_string t); static code_bool Amalgame_Compiler_CGen_IsCPointerType(Amalgame_Compiler_CGen* self, code_string ct); static code_string Amalgame_Compiler_CGen_BoxAsVoid(Amalgame_Compiler_CGen* self, code_string expr); static code_string Amalgame_Compiler_CGen_UnboxScalar(Amalgame_Compiler_CGen* self, code_string ctype, code_string expr); static code_string Amalgame_Compiler_CGen_TypeToC(Amalgame_Compiler_CGen* self, code_string t); Amalgame_Compiler_CGen* Amalgame_Compiler_CGen_new() { Amalgame_Compiler_CGen* self = (Amalgame_Compiler_CGen*) GC_MALLOC(sizeof(Amalgame_Compiler_CGen)); #line 240 "./src/generator/c_gen.am" self->Out = Amalgame_Compiler_Emitter_new(); #line 241 "./src/generator/c_gen.am" self->NsPrefix = ""; #line 242 "./src/generator/c_gen.am" self->LocalTypeNames = AmalgameList_new(); #line 243 "./src/generator/c_gen.am" self->LocalTypeCType = AmalgameList_new(); #line 244 "./src/generator/c_gen.am" self->CurrentClass = ""; #line 245 "./src/generator/c_gen.am" self->CurrentRetType = ""; #line 246 "./src/generator/c_gen.am" self->FieldNames = AmalgameList_new(); #line 247 "./src/generator/c_gen.am" self->FieldCTypes = AmalgameList_new(); #line 248 "./src/generator/c_gen.am" self->ListElemNames = AmalgameList_new(); #line 249 "./src/generator/c_gen.am" self->ListElemCTypes = AmalgameList_new(); #line 250 "./src/generator/c_gen.am" self->EnumNames = AmalgameList_new(); #line 251 "./src/generator/c_gen.am" self->MethodRetNames = AmalgameList_new(); #line 252 "./src/generator/c_gen.am" self->MethodRetTypes = AmalgameList_new(); #line 253 "./src/generator/c_gen.am" self->MethodRetRawNames = AmalgameList_new(); #line 254 "./src/generator/c_gen.am" self->MethodRetRawTypes = AmalgameList_new(); #line 255 "./src/generator/c_gen.am" self->MethodVariadicNames = AmalgameList_new(); #line 256 "./src/generator/c_gen.am" self->MethodVariadicArity = AmalgameList_new(); #line 257 "./src/generator/c_gen.am" self->LambdaCounter = 0LL; #line 258 "./src/generator/c_gen.am" self->InLambdaBody = 0; #line 259 "./src/generator/c_gen.am" self->PkgClasses = AmalgameList_new(); #line 260 "./src/generator/c_gen.am" self->PkgFuncs = AmalgameList_new(); #line 261 "./src/generator/c_gen.am" self->PkgFuncCTypes = AmalgameList_new(); #line 262 "./src/generator/c_gen.am" self->PkgHeaders = AmalgameList_new(); #line 263 "./src/generator/c_gen.am" self->PkgHeaderNs = AmalgameList_new(); #line 264 "./src/generator/c_gen.am" self->PkgClassNs = AmalgameList_new(); #line 265 "./src/generator/c_gen.am" self->ImportedNs = AmalgameList_new(); #line 266 "./src/generator/c_gen.am" self->ImportsFiltered = 0; #line 267 "./src/generator/c_gen.am" self->Embedded = 0; #line 268 "./src/generator/c_gen.am" self->ExternalClasses = AmalgameList_new(); #line 269 "./src/generator/c_gen.am" self->ExternalClassNsArr = AmalgameList_new(); #line 270 "./src/generator/c_gen.am" self->ExternalEnums = AmalgameList_new(); #line 271 "./src/generator/c_gen.am" self->ExternalEnumNsArr = AmalgameList_new(); #line 272 "./src/generator/c_gen.am" self->PkgOpaqueTypes = AmalgameList_new(); #line 273 "./src/generator/c_gen.am" self->LocalClasses = AmalgameList_new(); #line 274 "./src/generator/c_gen.am" self->IfaceShortNames = AmalgameList_new(); #line 275 "./src/generator/c_gen.am" self->IfaceMangledNames = AmalgameList_new(); #line 276 "./src/generator/c_gen.am" self->IfaceNodes = AmalgameList_new(); #line 277 "./src/generator/c_gen.am" self->ParamIfaceKeys = AmalgameList_new(); #line 278 "./src/generator/c_gen.am" self->ParamIfaceVals = AmalgameList_new(); #line 279 "./src/generator/c_gen.am" self->CurrentSource = ""; #line 280 "./src/generator/c_gen.am" self->LastLineEmitted = -1LL; #line 281 "./src/generator/c_gen.am" self->InferCacheKeys = AmalgameList_new(); #line 282 "./src/generator/c_gen.am" self->InferCacheVals = AmalgameList_new(); #line 285 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameTcpConn", "RemoteIp", "code_string"); #line 286 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameTcpConn", "RemotePort", "i64"); #line 287 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameTcpConn", "Connected", "code_bool"); #line 288 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameTcpConn", "Fd", "i64"); #line 289 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameTcpServer", "Fd", "i64"); #line 290 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameTcpServer", "Port", "i64"); #line 291 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameTcpServer", "Listening", "code_bool"); #line 292 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameTcpClient", "Connected", "code_bool"); #line 293 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameTcpClient", "RemoteHost", "code_string"); #line 294 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameTcpClient", "RemotePort", "i64"); #line 296 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameUdpSocket", "BoundPort", "i64"); #line 297 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameUdpSocket", "Bound", "code_bool"); #line 298 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameUdpDatagram", "Data", "code_string"); #line 299 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameUdpDatagram", "DataLen", "i64"); #line 300 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameUdpDatagram", "FromIp", "code_string"); #line 301 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameUdpDatagram", "FromPort", "i64"); #line 302 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameProcessResult", "Exit", "i64"); #line 303 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameProcessResult", "Stdout", "code_string"); #line 304 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, "AmalgameProcessResult", "Stderr", "code_string"); return self; } code_string Amalgame_Compiler_CGen_Generate(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog) { #line 308 "./src/generator/c_gen.am" code_string ns = prog->Str; #line 309 "./src/generator/c_gen.am" if (String_Length(ns) > 0LL) { #line 310 "./src/generator/c_gen.am" self->NsPrefix = String_Replace(ns, ".", "_"); } #line 316 "./src/generator/c_gen.am" if (!self->ImportsFiltered) { #line 317 "./src/generator/c_gen.am" AmalgameList* autoImports = AmalgameList_new(); #line 318 "./src/generator/c_gen.am" i64 ai = AmalgameList_count(prog->Args); #line 319 "./src/generator/c_gen.am" for (i64 ii = 0LL; ii < ai; ii++) { #line 320 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* impNode = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Args, ii); #line 321 "./src/generator/c_gen.am" AmalgameList_add(autoImports, (void*)(intptr_t)(impNode->Str)); } #line 323 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_SetImportedNamespaces(self, autoImports); } #line 335 "./src/generator/c_gen.am" if (String_Length(ns) > 0LL) { #line 336 "./src/generator/c_gen.am" code_bool alreadyPresent = 0; #line 337 "./src/generator/c_gen.am" i64 existing = AmalgameList_count(self->ImportedNs); #line 338 "./src/generator/c_gen.am" for (i64 ei = 0LL; ei < existing; ei++) { #line 339 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->ImportedNs, ei), ns)) { #line 340 "./src/generator/c_gen.am" alreadyPresent = 1; } } #line 343 "./src/generator/c_gen.am" if (!alreadyPresent) { #line 344 "./src/generator/c_gen.am" AmalgameList_add(self->ImportedNs, (void*)(intptr_t)(ns)); } } #line 347 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitHeader(self); #line 348 "./src/generator/c_gen.am" i64 decls = AmalgameList_count(prog->Children); #line 349 "./src/generator/c_gen.am" for (i64 i = 0LL; i < decls; i++) { #line 350 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i); #line 351 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitForwardDecl(self, decl); } #line 353 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); #line 356 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitConstructorForwards(self, prog); #line 357 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); #line 358 "./src/generator/c_gen.am" for (i64 j = 0LL; j < decls; j++) { #line 359 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, j); #line 360 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitDecl(self, decl); } #line 362 "./src/generator/c_gen.am" return Amalgame_Compiler_Emitter_GetOutput(self->Out); } void Amalgame_Compiler_CGen_SetStreaming(Amalgame_Compiler_CGen* self, code_bool v) { #line 367 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_SetStreaming(self->Out, v); } void Amalgame_Compiler_CGen_BeginMulti(Amalgame_Compiler_CGen* self, code_string ns) { #line 371 "./src/generator/c_gen.am" if (String_Length(ns) > 0LL) { #line 372 "./src/generator/c_gen.am" self->NsPrefix = String_Replace(ns, ".", "_"); } #line 383 "./src/generator/c_gen.am" if (String_Length(ns) > 0LL) { #line 384 "./src/generator/c_gen.am" code_string nsDot = String_Replace(ns, "_", "."); #line 385 "./src/generator/c_gen.am" code_bool alreadyPresent = 0; #line 386 "./src/generator/c_gen.am" i64 existing = AmalgameList_count(self->ImportedNs); #line 387 "./src/generator/c_gen.am" for (i64 ei = 0LL; ei < existing; ei++) { #line 388 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->ImportedNs, ei), nsDot)) { #line 389 "./src/generator/c_gen.am" alreadyPresent = 1; } } #line 392 "./src/generator/c_gen.am" if (!alreadyPresent) { #line 393 "./src/generator/c_gen.am" AmalgameList_add(self->ImportedNs, (void*)(intptr_t)(nsDot)); } } #line 396 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitHeader(self); #line 409 "./src/generator/c_gen.am" i64 pc = AmalgameList_count(self->PkgClasses); #line 410 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pc; pi++) { #line 411 "./src/generator/c_gen.am" code_string cname = (code_string)AmalgameList_get(self->PkgClasses, pi); #line 412 "./src/generator/c_gen.am" code_string cns = (code_string)AmalgameList_get(self->PkgClassNs, pi); #line 413 "./src/generator/c_gen.am" code_string cnsPrefix = String_Replace(cns, ".", "_"); #line 414 "./src/generator/c_gen.am" if (code_string_equals(cnsPrefix, self->NsPrefix)) { continue; } #line 421 "./src/generator/c_gen.am" if (self->ImportsFiltered) { #line 422 "./src/generator/c_gen.am" if (!Amalgame_Compiler_CGen_NamespaceImported(self, cns)) { continue; } } #line 428 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsInterface(self, cname)) { continue; } #line 429 "./src/generator/c_gen.am" code_string mangled = Amalgame_Compiler_CGen_PkgClassMangledPrefix(self, cname); #line 430 "./src/generator/c_gen.am" if (String_Length(mangled) > 0LL) { #line 431 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("typedef struct _", mangled)), " ")), mangled)), "; /* pkg-class */")); } } } void Amalgame_Compiler_CGen_AddFilePass1(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog) { #line 437 "./src/generator/c_gen.am" i64 decls = AmalgameList_count(prog->Children); #line 438 "./src/generator/c_gen.am" for (i64 i = 0LL; i < decls; i++) { #line 439 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i); #line 440 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitForwardDecl(self, decl); } } void Amalgame_Compiler_CGen_EmitSeparator(Amalgame_Compiler_CGen* self) { #line 445 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); } void Amalgame_Compiler_CGen_AddFilePass2(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog, code_string sourcePath) { #line 454 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_AddFilePass2Forwards(self, prog); #line 455 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_AddFilePass2Bodies(self, prog, sourcePath); } void Amalgame_Compiler_CGen_AddFilePass2Forwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog) { #line 465 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitConstructorForwards(self, prog); #line 466 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitMethodForwards(self, prog); #line 471 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitLambdaForwards(self, prog); } void Amalgame_Compiler_CGen_AddFilePass2Bodies(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog, code_string sourcePath) { #line 482 "./src/generator/c_gen.am" self->CurrentSource = sourcePath; #line 483 "./src/generator/c_gen.am" self->LastLineEmitted = -1LL; #line 485 "./src/generator/c_gen.am" i64 decls = AmalgameList_count(prog->Children); #line 486 "./src/generator/c_gen.am" for (i64 j = 0LL; j < decls; j++) { #line 487 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, j); #line 488 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitDecl(self, decl); } #line 493 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitLambdaBodies(self, prog); } static void Amalgame_Compiler_CGen_EmitMethodForwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog) { #line 501 "./src/generator/c_gen.am" i64 decls = AmalgameList_count(prog->Children); #line 502 "./src/generator/c_gen.am" for (i64 i = 0LL; i < decls; i++) { #line 503 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i); #line 504 "./src/generator/c_gen.am" if ((decl->Kind == Amalgame_Compiler_NodeKind_CLASS_DECL) && !decl->Flag2) { #line 505 "./src/generator/c_gen.am" code_string cname = Amalgame_Compiler_CGen_SymName(self, decl->Name); #line 506 "./src/generator/c_gen.am" i64 members = AmalgameList_count(decl->Children); #line 507 "./src/generator/c_gen.am" for (i64 j = 0LL; j < members; j++) { #line 508 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(decl->Children, j); #line 509 "./src/generator/c_gen.am" if (((m->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) && (!code_string_equals(m->Name, decl->Name))) && !m->Flag3) { #line 510 "./src/generator/c_gen.am" code_bool isPublic = m->Flag; #line 511 "./src/generator/c_gen.am" code_string prefix = ""; #line 512 "./src/generator/c_gen.am" if (!isPublic) { prefix = "static "; } #line 513 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat(prefix, Amalgame_Compiler_CGen_MethodSig(self, m, cname))), ";")); #line 514 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_RegisterParamIfaces(self, code_string_concat((code_string_concat(cname, "_")), m->Name), m); } } } } } static void Amalgame_Compiler_CGen_EmitConstructorForwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog) { #line 524 "./src/generator/c_gen.am" i64 decls = AmalgameList_count(prog->Children); #line 525 "./src/generator/c_gen.am" for (i64 i = 0LL; i < decls; i++) { #line 526 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i); #line 527 "./src/generator/c_gen.am" if ((decl->Kind == Amalgame_Compiler_NodeKind_CLASS_DECL) && !decl->Flag2) { #line 528 "./src/generator/c_gen.am" code_string name = Amalgame_Compiler_CGen_SymName(self, decl->Name); #line 529 "./src/generator/c_gen.am" code_bool ctorFound = 0; #line 530 "./src/generator/c_gen.am" i64 members = AmalgameList_count(decl->Children); #line 531 "./src/generator/c_gen.am" for (i64 j = 0LL; j < members; j++) { #line 532 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(decl->Children, j); #line 533 "./src/generator/c_gen.am" if ((m->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) && (code_string_equals(m->Name, decl->Name))) { #line 534 "./src/generator/c_gen.am" ctorFound = 1; #line 535 "./src/generator/c_gen.am" code_string sig = code_string_concat((code_string_concat((code_string_concat(name, "* ")), name)), "_new("); #line 536 "./src/generator/c_gen.am" i64 pcount = AmalgameList_count(m->Params); #line 537 "./src/generator/c_gen.am" code_bool first = 1; #line 538 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pcount; pi++) { #line 539 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(m->Params, pi); #line 540 "./src/generator/c_gen.am" if (!first) { sig = (code_string_concat(sig, ", ")); } #line 543 "./src/generator/c_gen.am" if (p->Flag) { #line 544 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat(sig, "AmalgameList* ")), p->Name)); } else { #line 546 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat((code_string_concat(sig, Amalgame_Compiler_CGen_TypeToC(self, p->Str))), " ")), p->Name)); } #line 548 "./src/generator/c_gen.am" first = 0; } #line 550 "./src/generator/c_gen.am" sig = (code_string_concat(sig, ");")); #line 551 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, sig); #line 552 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_RegisterParamIfaces(self, code_string_concat(name, "_new"), m); #line 559 "./src/generator/c_gen.am" if (pcount > 0LL) { #line 560 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* lastP = (Amalgame_Compiler_AstNode*)AmalgameList_get(m->Params, pcount - 1LL); #line 561 "./src/generator/c_gen.am" if (lastP->Flag) { #line 562 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodVariadicSet(self, code_string_concat(name, "_new"), pcount - 1LL); } } } } #line 570 "./src/generator/c_gen.am" if (!ctorFound) { #line 571 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(name, "* ")), name)), "_new();")); } } } } static void Amalgame_Compiler_CGen_EmitLambdaForwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* node) { #line 584 "./src/generator/c_gen.am" if (node == NULL) { return; } #line 585 "./src/generator/c_gen.am" if ((node->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) && (code_string_equals(node->Name, "__lambda__"))) { #line 586 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitOneLambdaForward(self, node); } #line 588 "./src/generator/c_gen.am" if (node->Left != NULL) { Amalgame_Compiler_CGen_EmitLambdaForwards(self, node->Left); } #line 589 "./src/generator/c_gen.am" if (node->Right != NULL) { Amalgame_Compiler_CGen_EmitLambdaForwards(self, node->Right); } #line 590 "./src/generator/c_gen.am" if (node->Cond != NULL) { Amalgame_Compiler_CGen_EmitLambdaForwards(self, node->Cond); } #line 591 "./src/generator/c_gen.am" if (node->Body != NULL) { Amalgame_Compiler_CGen_EmitLambdaForwards(self, node->Body); } #line 592 "./src/generator/c_gen.am" if (node->Else != NULL) { Amalgame_Compiler_CGen_EmitLambdaForwards(self, node->Else); } #line 593 "./src/generator/c_gen.am" i64 cn = AmalgameList_count(node->Children); #line 594 "./src/generator/c_gen.am" for (i64 i = 0LL; i < cn; i++) { #line 595 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitLambdaForwards(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(node->Children, i)); } #line 597 "./src/generator/c_gen.am" i64 pn = AmalgameList_count(node->Params); #line 598 "./src/generator/c_gen.am" for (i64 j = 0LL; j < pn; j++) { #line 599 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitLambdaForwards(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(node->Params, j)); } #line 601 "./src/generator/c_gen.am" i64 an = AmalgameList_count(node->Args); #line 602 "./src/generator/c_gen.am" for (i64 k = 0LL; k < an; k++) { #line 603 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitLambdaForwards(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(node->Args, k)); } } static void Amalgame_Compiler_CGen_EmitLambdaBodies(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* node) { #line 608 "./src/generator/c_gen.am" if (node == NULL) { return; } #line 609 "./src/generator/c_gen.am" if ((node->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) && (code_string_equals(node->Name, "__lambda__"))) { #line 610 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitOneLambdaBody(self, node); } #line 612 "./src/generator/c_gen.am" if (node->Left != NULL) { Amalgame_Compiler_CGen_EmitLambdaBodies(self, node->Left); } #line 613 "./src/generator/c_gen.am" if (node->Right != NULL) { Amalgame_Compiler_CGen_EmitLambdaBodies(self, node->Right); } #line 614 "./src/generator/c_gen.am" if (node->Cond != NULL) { Amalgame_Compiler_CGen_EmitLambdaBodies(self, node->Cond); } #line 615 "./src/generator/c_gen.am" if (node->Body != NULL) { Amalgame_Compiler_CGen_EmitLambdaBodies(self, node->Body); } #line 616 "./src/generator/c_gen.am" if (node->Else != NULL) { Amalgame_Compiler_CGen_EmitLambdaBodies(self, node->Else); } #line 617 "./src/generator/c_gen.am" i64 cn = AmalgameList_count(node->Children); #line 618 "./src/generator/c_gen.am" for (i64 i = 0LL; i < cn; i++) { #line 619 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitLambdaBodies(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(node->Children, i)); } #line 621 "./src/generator/c_gen.am" i64 pn = AmalgameList_count(node->Params); #line 622 "./src/generator/c_gen.am" for (i64 j = 0LL; j < pn; j++) { #line 623 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitLambdaBodies(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(node->Params, j)); } #line 625 "./src/generator/c_gen.am" i64 an = AmalgameList_count(node->Args); #line 626 "./src/generator/c_gen.am" for (i64 k = 0LL; k < an; k++) { #line 627 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitLambdaBodies(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(node->Args, k)); } } static void Amalgame_Compiler_CGen_EmitOneLambdaForward(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* lam) { #line 635 "./src/generator/c_gen.am" i64 id = self->LambdaCounter; #line 636 "./src/generator/c_gen.am" self->LambdaCounter = (id + 1LL); #line 637 "./src/generator/c_gen.am" code_string idStr = String_FromInt(id); #line 638 "./src/generator/c_gen.am" lam->Str2 = idStr; #line 639 "./src/generator/c_gen.am" code_string envName = code_string_concat("LamEnv_", idStr); #line 640 "./src/generator/c_gen.am" code_string fnName = code_string_concat((code_string_concat("lam_", idStr)), "_fn"); #line 641 "./src/generator/c_gen.am" i64 cn = AmalgameList_count(lam->Args); #line 642 "./src/generator/c_gen.am" i64 pn = AmalgameList_count(lam->Params); #line 645 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("typedef struct ", envName)), " {")); #line 646 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 647 "./src/generator/c_gen.am" if (cn == 0LL) { #line 648 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "char _empty;"); } else { #line 650 "./src/generator/c_gen.am" for (i64 i = 0LL; i < cn; i++) { #line 651 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* cap = (Amalgame_Compiler_AstNode*)AmalgameList_get(lam->Args, i); #line 652 "./src/generator/c_gen.am" code_string ct = Amalgame_Compiler_CGen_TypeToC(self, cap->Str); #line 653 "./src/generator/c_gen.am" if ((String_Length(ct) == 0LL) || (code_string_equals(ct, "void"))) { #line 654 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("void* _", cap->Name)), ";")); } else { #line 656 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(ct, " _")), cap->Name)), ";")); } } } #line 660 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 661 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("} ", envName)), ";")); #line 664 "./src/generator/c_gen.am" code_string fwdLine = code_string_concat((code_string_concat("static void* ", fnName)), "(void* __envRaw"); #line 665 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pn; pi++) { #line 666 "./src/generator/c_gen.am" fwdLine = (code_string_concat((code_string_concat(fwdLine, ", void* __arg")), String_FromInt(pi))); } #line 668 "./src/generator/c_gen.am" fwdLine = (code_string_concat(fwdLine, ");")); #line 669 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, fwdLine); } static void Amalgame_Compiler_CGen_EmitOneLambdaBody(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* lam) { #line 674 "./src/generator/c_gen.am" code_string idStr = lam->Str2; #line 675 "./src/generator/c_gen.am" code_string envName = code_string_concat("LamEnv_", idStr); #line 676 "./src/generator/c_gen.am" code_string fnName = code_string_concat((code_string_concat("lam_", idStr)), "_fn"); #line 677 "./src/generator/c_gen.am" i64 cn = AmalgameList_count(lam->Args); #line 678 "./src/generator/c_gen.am" i64 pn = AmalgameList_count(lam->Params); #line 688 "./src/generator/c_gen.am" code_string sigLine = code_string_concat((code_string_concat("static void* ", fnName)), "(void* __envRaw"); #line 689 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pn; pi++) { #line 690 "./src/generator/c_gen.am" sigLine = (code_string_concat((code_string_concat(sigLine, ", void* __arg")), String_FromInt(pi))); } #line 692 "./src/generator/c_gen.am" sigLine = (code_string_concat(sigLine, ") {")); #line 693 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, sigLine); #line 694 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 695 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(envName, "* __env = (")), envName)), "*)__envRaw;")); #line 697 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pn; pi++) { #line 698 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(lam->Params, pi); #line 699 "./src/generator/c_gen.am" code_string pTypeRaw = p->Str; #line 700 "./src/generator/c_gen.am" code_string pTypeC = "i64"; #line 701 "./src/generator/c_gen.am" if ((String_Length(pTypeRaw) > 0LL) && (!code_string_equals(pTypeRaw, "?"))) { #line 702 "./src/generator/c_gen.am" pTypeC = Amalgame_Compiler_CGen_TypeToC(self, pTypeRaw); } #line 704 "./src/generator/c_gen.am" code_string argName = code_string_concat("__arg", String_FromInt(pi)); #line 705 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsCPointerType(self, pTypeC)) { #line 706 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(pTypeC, " ")), p->Name)), " = (")), pTypeC)), ")")), argName)), ";")); } else { #line 708 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(pTypeC, " ")), p->Name)), " = ")), Amalgame_Compiler_CGen_UnboxScalar(self, pTypeC, argName))), ";")); } } #line 712 "./src/generator/c_gen.am" for (i64 i = 0LL; i < cn; i++) { #line 713 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* cap = (Amalgame_Compiler_AstNode*)AmalgameList_get(lam->Args, i); #line 714 "./src/generator/c_gen.am" code_string ct = Amalgame_Compiler_CGen_TypeToC(self, cap->Str); #line 715 "./src/generator/c_gen.am" if ((String_Length(ct) == 0LL) || (code_string_equals(ct, "void"))) { #line 716 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("void* ", cap->Name)), " = __env->_")), cap->Name)), ";")); } else { #line 718 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(ct, " ")), cap->Name)), " = __env->_")), cap->Name)), ";")); } #line 720 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, cap->Name, ct); } #line 725 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pn; pi++) { #line 726 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(lam->Params, pi); #line 727 "./src/generator/c_gen.am" code_string pTypeRaw = p->Str; #line 728 "./src/generator/c_gen.am" code_string pTypeC = "i64"; #line 729 "./src/generator/c_gen.am" if ((String_Length(pTypeRaw) > 0LL) && (!code_string_equals(pTypeRaw, "?"))) { #line 730 "./src/generator/c_gen.am" pTypeC = Amalgame_Compiler_CGen_TypeToC(self, pTypeRaw); } #line 732 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, p->Name, pTypeC); } #line 738 "./src/generator/c_gen.am" if (lam->Body != NULL) { #line 739 "./src/generator/c_gen.am" code_bool prevInLam = self->InLambdaBody; #line 740 "./src/generator/c_gen.am" self->InLambdaBody = 1; #line 741 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitBlock(self, lam->Body); #line 742 "./src/generator/c_gen.am" self->InLambdaBody = prevInLam; #line 743 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("return ", Amalgame_Compiler_CGen_BoxAsVoid(self, "0"))), ";")); } else if (lam->Left != NULL) { #line 745 "./src/generator/c_gen.am" code_string bodyStr = Amalgame_Compiler_CGen_EmitExprStr(self, lam->Left); #line 746 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("return ", Amalgame_Compiler_CGen_BoxAsVoid(self, bodyStr))), ";")); } else { #line 748 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("return ", Amalgame_Compiler_CGen_BoxAsVoid(self, "0"))), ";")); } #line 751 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pn; pi++) { #line 752 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(lam->Params, pi); #line 753 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, p->Name, ""); } #line 755 "./src/generator/c_gen.am" for (i64 i = 0LL; i < cn; i++) { #line 756 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* cap = (Amalgame_Compiler_AstNode*)AmalgameList_get(lam->Args, i); #line 757 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, cap->Name, ""); } #line 759 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 760 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); } code_string Amalgame_Compiler_CGen_FinishMulti(Amalgame_Compiler_CGen* self) { #line 764 "./src/generator/c_gen.am" return Amalgame_Compiler_Emitter_GetOutput(self->Out); } AmalgameList* Amalgame_Compiler_CGen_GetLines(Amalgame_Compiler_CGen* self) { #line 768 "./src/generator/c_gen.am" return self->Out->Lines; } static code_string Amalgame_Compiler_CGen_SymName(Amalgame_Compiler_CGen* self, code_string name) { #line 772 "./src/generator/c_gen.am" code_string ns = self->NsPrefix; #line 773 "./src/generator/c_gen.am" if (String_Length(ns) > 0LL) { #line 774 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(ns, "_")), name); } #line 776 "./src/generator/c_gen.am" return name; } static void Amalgame_Compiler_CGen_LocalTypeSet(Amalgame_Compiler_CGen* self, code_string varName, code_string ctype) { #line 784 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->LocalTypeNames); #line 785 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 786 "./src/generator/c_gen.am" code_string k = (code_string)AmalgameList_get(self->LocalTypeNames, i); #line 787 "./src/generator/c_gen.am" if (code_string_equals(k, varName)) { #line 791 "./src/generator/c_gen.am" AmalgameList_add(self->LocalTypeNames, (void*)(intptr_t)(varName)); #line 792 "./src/generator/c_gen.am" AmalgameList_add(self->LocalTypeCType, (void*)(intptr_t)(ctype)); #line 793 "./src/generator/c_gen.am" return; } } #line 796 "./src/generator/c_gen.am" AmalgameList_add(self->LocalTypeNames, (void*)(intptr_t)(varName)); #line 797 "./src/generator/c_gen.am" AmalgameList_add(self->LocalTypeCType, (void*)(intptr_t)(ctype)); } static code_string Amalgame_Compiler_CGen_LocalTypeGet(Amalgame_Compiler_CGen* self, code_string varName) { #line 802 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->LocalTypeNames); #line 803 "./src/generator/c_gen.am" code_string result = ""; #line 804 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 805 "./src/generator/c_gen.am" code_string k = (code_string)AmalgameList_get(self->LocalTypeNames, i); #line 806 "./src/generator/c_gen.am" if (code_string_equals(k, varName)) { #line 807 "./src/generator/c_gen.am" result = (code_string)AmalgameList_get(self->LocalTypeCType, i); } } #line 810 "./src/generator/c_gen.am" return result; } static void Amalgame_Compiler_CGen_LocalTypeClear(Amalgame_Compiler_CGen* self) { #line 814 "./src/generator/c_gen.am" self->LocalTypeNames = AmalgameList_new(); #line 815 "./src/generator/c_gen.am" self->LocalTypeCType = AmalgameList_new(); } static void Amalgame_Compiler_CGen_FieldTypeSet(Amalgame_Compiler_CGen* self, code_string className, code_string fieldName, code_string ctype) { #line 819 "./src/generator/c_gen.am" code_string key = code_string_concat((code_string_concat(className, ".")), fieldName); #line 820 "./src/generator/c_gen.am" AmalgameList_add(self->FieldNames, (void*)(intptr_t)(key)); #line 821 "./src/generator/c_gen.am" AmalgameList_add(self->FieldCTypes, (void*)(intptr_t)(ctype)); } static code_string Amalgame_Compiler_CGen_FieldTypeGet(Amalgame_Compiler_CGen* self, code_string className, code_string fieldName) { #line 825 "./src/generator/c_gen.am" code_string key = code_string_concat((code_string_concat(className, ".")), fieldName); #line 826 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->FieldNames); #line 827 "./src/generator/c_gen.am" code_string result = ""; #line 828 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 829 "./src/generator/c_gen.am" code_string k = (code_string)AmalgameList_get(self->FieldNames, i); #line 830 "./src/generator/c_gen.am" if (code_string_equals(k, key)) { #line 831 "./src/generator/c_gen.am" result = (code_string)AmalgameList_get(self->FieldCTypes, i); } } #line 834 "./src/generator/c_gen.am" return result; } static code_string Amalgame_Compiler_CGen_ResolveReceiverClass(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* node) { #line 842 "./src/generator/c_gen.am" if (node == NULL) { return ""; } #line 843 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind nk = node->Kind; #line 844 "./src/generator/c_gen.am" if (nk == Amalgame_Compiler_NodeKind_THIS_EXPR) { return self->CurrentClass; } #line 845 "./src/generator/c_gen.am" if (nk == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 846 "./src/generator/c_gen.am" code_string t = Amalgame_Compiler_CGen_LocalTypeGet(self, node->Name); #line 847 "./src/generator/c_gen.am" if (String_Length(t) == 0LL) { return ""; } #line 848 "./src/generator/c_gen.am" return String_Replace(t, "*", ""); } #line 850 "./src/generator/c_gen.am" if (nk == Amalgame_Compiler_NodeKind_MEMBER) { #line 851 "./src/generator/c_gen.am" code_string parentCls = Amalgame_Compiler_CGen_ResolveReceiverClass(self, node->Left); #line 852 "./src/generator/c_gen.am" if (String_Length(parentCls) == 0LL) { return ""; } #line 853 "./src/generator/c_gen.am" code_string ft = Amalgame_Compiler_CGen_FieldTypeGet(self, parentCls, node->Name); #line 854 "./src/generator/c_gen.am" if (String_Length(ft) == 0LL) { return ""; } #line 855 "./src/generator/c_gen.am" return String_Replace(ft, "*", ""); } #line 857 "./src/generator/c_gen.am" return ""; } static void Amalgame_Compiler_CGen_TrackMapResultElem(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt) { #line 868 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* call = stmt->Left; #line 869 "./src/generator/c_gen.am" if (call == NULL) { return; } #line 870 "./src/generator/c_gen.am" if (AmalgameList_count(call->Args) == 0LL) { return; } #line 871 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* lam = (Amalgame_Compiler_AstNode*)AmalgameList_get(call->Args, 0LL); #line 872 "./src/generator/c_gen.am" if (lam == NULL) { return; } #line 873 "./src/generator/c_gen.am" if (lam->Kind != Amalgame_Compiler_NodeKind_METHOD_DECL) { return; } #line 874 "./src/generator/c_gen.am" if (!code_string_equals(lam->Name, "__lambda__")) { return; } #line 875 "./src/generator/c_gen.am" if (lam->Left == NULL) { return; } #line 876 "./src/generator/c_gen.am" i64 pn = AmalgameList_count(lam->Params); #line 877 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pn; pi++) { #line 878 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(lam->Params, pi); #line 879 "./src/generator/c_gen.am" code_string pTypeRaw = p->Str; #line 880 "./src/generator/c_gen.am" code_string pTypeC = "i64"; #line 881 "./src/generator/c_gen.am" if ((String_Length(pTypeRaw) > 0LL) && (!code_string_equals(pTypeRaw, "?"))) { #line 882 "./src/generator/c_gen.am" pTypeC = Amalgame_Compiler_CGen_TypeToC(self, pTypeRaw); } #line 884 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, p->Name, pTypeC); } #line 886 "./src/generator/c_gen.am" code_string retC = Amalgame_Compiler_CGen_InferTypeFromExpr(self, lam->Left); #line 887 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pn; pi++) { #line 888 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(lam->Params, pi); #line 889 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, p->Name, ""); } #line 891 "./src/generator/c_gen.am" if ((String_Length(retC) > 0LL) && (!code_string_equals(retC, "void*"))) { #line 892 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, "__local__", stmt->Name, retC); } } static void Amalgame_Compiler_CGen_TrackGenericLocal(Amalgame_Compiler_CGen* self, code_string varName, code_string rawType) { #line 902 "./src/generator/c_gen.am" if (String_StartsWith(rawType, "List<") && String_EndsWith(rawType, ">")) { #line 903 "./src/generator/c_gen.am" code_string inner = String_Substring(rawType, 5LL, String_Length(rawType) - 6LL); #line 904 "./src/generator/c_gen.am" if (String_Length(inner) > 0LL) { #line 905 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, "__local__", varName, Amalgame_Compiler_CGen_TypeToC(self, inner)); #line 911 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, "__local_raw__", varName, inner); } #line 913 "./src/generator/c_gen.am" return; } #line 915 "./src/generator/c_gen.am" if (String_StartsWith(rawType, "Map<") && String_EndsWith(rawType, ">")) { #line 916 "./src/generator/c_gen.am" code_string inner = String_Substring(rawType, 4LL, String_Length(rawType) - 5LL); #line 917 "./src/generator/c_gen.am" i64 comma = String_IndexOf(inner, ","); #line 918 "./src/generator/c_gen.am" if (comma > 0LL) { #line 919 "./src/generator/c_gen.am" code_string vRaw = String_Substring(inner, comma + 1LL, (String_Length(inner) - comma) - 1LL); #line 920 "./src/generator/c_gen.am" code_string vTrim = String_Trim(vRaw); #line 921 "./src/generator/c_gen.am" if (String_Length(vTrim) > 0LL) { #line 922 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, "__local_map__", varName, Amalgame_Compiler_CGen_TypeToC(self, vTrim)); #line 926 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, "__local_map_raw__", varName, vTrim); } } } } static code_string Amalgame_Compiler_CGen_PeelOneGenericLayer(Amalgame_Compiler_CGen* self, code_string rawType) { #line 936 "./src/generator/c_gen.am" if (String_StartsWith(rawType, "List<") && String_EndsWith(rawType, ">")) { #line 937 "./src/generator/c_gen.am" return String_Substring(rawType, 5LL, String_Length(rawType) - 6LL); } #line 939 "./src/generator/c_gen.am" if (String_StartsWith(rawType, "Map<") && String_EndsWith(rawType, ">")) { #line 940 "./src/generator/c_gen.am" code_string inner = String_Substring(rawType, 4LL, String_Length(rawType) - 5LL); #line 943 "./src/generator/c_gen.am" i64 comma = String_IndexOf(inner, ","); #line 944 "./src/generator/c_gen.am" if (comma > 0LL) { #line 945 "./src/generator/c_gen.am" return String_Trim(String_Substring(inner, comma + 1LL, (String_Length(inner) - comma) - 1LL)); } } #line 948 "./src/generator/c_gen.am" return ""; } static code_string Amalgame_Compiler_CGen_RecoverChainedListElemRaw(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* recv) { #line 963 "./src/generator/c_gen.am" if (recv == NULL) { return ""; } #line 964 "./src/generator/c_gen.am" if (recv->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 965 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_ListElemGet(self, "__local_raw__", recv->Name); } #line 967 "./src/generator/c_gen.am" if (recv->Kind == Amalgame_Compiler_NodeKind_CALL) { #line 968 "./src/generator/c_gen.am" if (recv->Left == NULL) { return ""; } #line 969 "./src/generator/c_gen.am" if (recv->Left->Kind != Amalgame_Compiler_NodeKind_MEMBER) { return ""; } #line 970 "./src/generator/c_gen.am" if (!code_string_equals(recv->Left->Name, "Get")) { return ""; } #line 971 "./src/generator/c_gen.am" code_string innerElemRaw = Amalgame_Compiler_CGen_RecoverChainedListElemRaw(self, recv->Left->Left); #line 972 "./src/generator/c_gen.am" if (String_Length(innerElemRaw) == 0LL) { return ""; } #line 973 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_PeelOneGenericLayer(self, innerElemRaw); } #line 975 "./src/generator/c_gen.am" return ""; } static void Amalgame_Compiler_CGen_ListElemSet(Amalgame_Compiler_CGen* self, code_string className, code_string fieldName, code_string elemCType) { #line 979 "./src/generator/c_gen.am" code_string key = code_string_concat((code_string_concat(className, ".")), fieldName); #line 980 "./src/generator/c_gen.am" AmalgameList_add(self->ListElemNames, (void*)(intptr_t)(key)); #line 981 "./src/generator/c_gen.am" AmalgameList_add(self->ListElemCTypes, (void*)(intptr_t)(elemCType)); } static code_string Amalgame_Compiler_CGen_ListElemGet(Amalgame_Compiler_CGen* self, code_string className, code_string fieldName) { #line 985 "./src/generator/c_gen.am" code_string key = code_string_concat((code_string_concat(className, ".")), fieldName); #line 986 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->ListElemNames); #line 987 "./src/generator/c_gen.am" code_string result = ""; #line 988 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 989 "./src/generator/c_gen.am" code_string k = (code_string)AmalgameList_get(self->ListElemNames, i); #line 990 "./src/generator/c_gen.am" if (code_string_equals(k, key)) { #line 991 "./src/generator/c_gen.am" result = (code_string)AmalgameList_get(self->ListElemCTypes, i); } } #line 994 "./src/generator/c_gen.am" return result; } static void Amalgame_Compiler_CGen_MethodRetSet(Amalgame_Compiler_CGen* self, code_string className, code_string methodName, code_string ctype) { #line 998 "./src/generator/c_gen.am" code_string key = code_string_concat((code_string_concat(className, "::")), methodName); #line 999 "./src/generator/c_gen.am" AmalgameList_add(self->MethodRetNames, (void*)(intptr_t)(key)); #line 1000 "./src/generator/c_gen.am" AmalgameList_add(self->MethodRetTypes, (void*)(intptr_t)(ctype)); } static void Amalgame_Compiler_CGen_MethodRetRawSet(Amalgame_Compiler_CGen* self, code_string className, code_string methodName, code_string rawType) { #line 1004 "./src/generator/c_gen.am" code_string key = code_string_concat((code_string_concat(className, "::")), methodName); #line 1005 "./src/generator/c_gen.am" AmalgameList_add(self->MethodRetRawNames, (void*)(intptr_t)(key)); #line 1006 "./src/generator/c_gen.am" AmalgameList_add(self->MethodRetRawTypes, (void*)(intptr_t)(rawType)); } static code_string Amalgame_Compiler_CGen_MethodRetRawGet(Amalgame_Compiler_CGen* self, code_string className, code_string methodName) { #line 1010 "./src/generator/c_gen.am" code_string key = code_string_concat((code_string_concat(className, "::")), methodName); #line 1011 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->MethodRetRawNames); #line 1012 "./src/generator/c_gen.am" code_string result = ""; #line 1013 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 1014 "./src/generator/c_gen.am" code_string k = (code_string)AmalgameList_get(self->MethodRetRawNames, i); #line 1015 "./src/generator/c_gen.am" if (code_string_equals(k, key)) { #line 1016 "./src/generator/c_gen.am" result = (code_string)AmalgameList_get(self->MethodRetRawTypes, i); } } #line 1019 "./src/generator/c_gen.am" return result; } static code_string Amalgame_Compiler_CGen_MethodRetGet(Amalgame_Compiler_CGen* self, code_string className, code_string methodName) { #line 1023 "./src/generator/c_gen.am" code_string key = code_string_concat((code_string_concat(className, "::")), methodName); #line 1024 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->MethodRetNames); #line 1025 "./src/generator/c_gen.am" code_string result = ""; #line 1026 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 1027 "./src/generator/c_gen.am" code_string k = (code_string)AmalgameList_get(self->MethodRetNames, i); #line 1028 "./src/generator/c_gen.am" if (code_string_equals(k, key)) { #line 1029 "./src/generator/c_gen.am" result = (code_string)AmalgameList_get(self->MethodRetTypes, i); } } #line 1032 "./src/generator/c_gen.am" return result; } static void Amalgame_Compiler_CGen_MethodVariadicSet(Amalgame_Compiler_CGen* self, code_string cname, i64 fixedArity) { #line 1039 "./src/generator/c_gen.am" AmalgameList_add(self->MethodVariadicNames, (void*)(intptr_t)(cname)); #line 1040 "./src/generator/c_gen.am" AmalgameList_add(self->MethodVariadicArity, (void*)(intptr_t)(fixedArity)); } static i64 Amalgame_Compiler_CGen_MethodVariadicGet(Amalgame_Compiler_CGen* self, code_string cname) { #line 1048 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->MethodVariadicNames); #line 1049 "./src/generator/c_gen.am" i64 result = 0LL - 1LL; #line 1050 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 1051 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->MethodVariadicNames, i), cname)) { #line 1052 "./src/generator/c_gen.am" result = (i64)(intptr_t)AmalgameList_get(self->MethodVariadicArity, i); } } #line 1055 "./src/generator/c_gen.am" return result; } static code_string Amalgame_Compiler_CGen_InferTypeFromExpr(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* expr) { #line 1065 "./src/generator/c_gen.am" if (expr == NULL) { return ""; } #line 1066 "./src/generator/c_gen.am" i64 key = 0LL; #line 1067 "./src/generator/c_gen.am" { /* inline-C */ key = (i64)expr; } #line 1070 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->InferCacheKeys); #line 1071 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 1072 "./src/generator/c_gen.am" if ((i64)(intptr_t)AmalgameList_get(self->InferCacheKeys, i) == key) { #line 1073 "./src/generator/c_gen.am" return (code_string)AmalgameList_get(self->InferCacheVals, i); } } #line 1076 "./src/generator/c_gen.am" code_string result = Amalgame_Compiler_CGen_InferTypeFromExprUncached(self, expr); #line 1077 "./src/generator/c_gen.am" AmalgameList_add(self->InferCacheKeys, (void*)(intptr_t)(key)); #line 1078 "./src/generator/c_gen.am" AmalgameList_add(self->InferCacheVals, (void*)(intptr_t)(result)); #line 1079 "./src/generator/c_gen.am" return result; } static code_string Amalgame_Compiler_CGen_InferTypeFromExprUncached(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* expr) { #line 1083 "./src/generator/c_gen.am" if (expr == NULL) { return ""; } #line 1084 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind k = expr->Kind; #line 1085 "./src/generator/c_gen.am" { /* match k */ if (k == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 1095 "./src/generator/c_gen.am" if (String_Length(self->CurrentClass) > 0LL) { #line 1096 "./src/generator/c_gen.am" return code_string_concat(self->CurrentClass, "*"); } } else if (k == Amalgame_Compiler_NodeKind_LIST_COMP) { #line 1099 "./src/generator/c_gen.am" return "AmalgameList*"; } else if (k == Amalgame_Compiler_NodeKind_LIST_LITERAL) { #line 1100 "./src/generator/c_gen.am" return "AmalgameList*"; } else if ((k == Amalgame_Compiler_NodeKind_IF_STMT) && (code_string_equals(expr->Name, "__match__"))) { #line 1104 "./src/generator/c_gen.am" if (AmalgameList_count(expr->Children) > 0LL) { #line 1105 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* firstArm = (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Children, 0LL); #line 1106 "./src/generator/c_gen.am" if (firstArm->Right != NULL) { #line 1107 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_InferTypeFromExpr(self, firstArm->Right); } } #line 1110 "./src/generator/c_gen.am" return ""; } else if (k == Amalgame_Compiler_NodeKind_IF_STMT) { #line 1115 "./src/generator/c_gen.am" if (expr->Body != NULL) { #line 1116 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* body = expr->Body; #line 1117 "./src/generator/c_gen.am" if ((body->Kind == Amalgame_Compiler_NodeKind_BLOCK) && (AmalgameList_count(body->Children) > 0LL)) { #line 1118 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* last = (Amalgame_Compiler_AstNode*)AmalgameList_get(body->Children, AmalgameList_count(body->Children) - 1LL); #line 1119 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_InferTypeFromExpr(self, last); } #line 1121 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_InferTypeFromExpr(self, body); } #line 1123 "./src/generator/c_gen.am" return ""; } else if (k == Amalgame_Compiler_NodeKind_LITERAL_INT) { #line 1125 "./src/generator/c_gen.am" return "i64"; } else if (k == Amalgame_Compiler_NodeKind_LITERAL_FLOAT) { #line 1126 "./src/generator/c_gen.am" return "double"; } else if (k == Amalgame_Compiler_NodeKind_LITERAL_STRING) { #line 1127 "./src/generator/c_gen.am" return "code_string"; } else if (k == Amalgame_Compiler_NodeKind_LITERAL_BOOL) { #line 1128 "./src/generator/c_gen.am" return "code_bool"; } else if (k == Amalgame_Compiler_NodeKind_BINARY) { #line 1130 "./src/generator/c_gen.am" code_string bop = expr->Str; #line 1131 "./src/generator/c_gen.am" code_bool isCmpOp = (((code_string_equals(bop, "&&")) || (code_string_equals(bop, "||"))) || (code_string_equals(bop, "=="))) || (code_string_equals(bop, "!=")); #line 1132 "./src/generator/c_gen.am" code_bool isRelOp = (((code_string_equals(bop, "<")) || (code_string_equals(bop, ">"))) || (code_string_equals(bop, "<="))) || (code_string_equals(bop, ">=")); #line 1133 "./src/generator/c_gen.am" if (isCmpOp || isRelOp) { #line 1134 "./src/generator/c_gen.am" return "code_bool"; } #line 1137 "./src/generator/c_gen.am" if (((((code_string_equals(bop, "+")) || (code_string_equals(bop, "-"))) || (code_string_equals(bop, "*"))) || (code_string_equals(bop, "/"))) || (code_string_equals(bop, "%"))) { #line 1138 "./src/generator/c_gen.am" code_string lt = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Left); #line 1139 "./src/generator/c_gen.am" code_string rt = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Right); #line 1140 "./src/generator/c_gen.am" if ((code_string_equals(lt, "code_string")) || (code_string_equals(rt, "code_string"))) { return "code_string"; } #line 1141 "./src/generator/c_gen.am" if (expr->Left != NULL) { #line 1142 "./src/generator/c_gen.am" if (expr->Left->Kind == Amalgame_Compiler_NodeKind_LITERAL_STRING) { return "code_string"; } #line 1143 "./src/generator/c_gen.am" if (expr->Left->Kind == Amalgame_Compiler_NodeKind_LITERAL_INT) { return "i64"; } } #line 1145 "./src/generator/c_gen.am" if (expr->Right != NULL) { #line 1146 "./src/generator/c_gen.am" if (expr->Right->Kind == Amalgame_Compiler_NodeKind_LITERAL_STRING) { return "code_string"; } #line 1147 "./src/generator/c_gen.am" if (expr->Right->Kind == Amalgame_Compiler_NodeKind_LITERAL_INT) { return "i64"; } } #line 1149 "./src/generator/c_gen.am" if ((code_string_equals(lt, "i64")) || (code_string_equals(rt, "i64"))) { return "i64"; } #line 1150 "./src/generator/c_gen.am" if ((code_string_equals(lt, "double")) || (code_string_equals(rt, "double"))) { return "double"; } } } else if (k == Amalgame_Compiler_NodeKind_UNARY) { #line 1154 "./src/generator/c_gen.am" if (code_string_equals(expr->Str, "!")) { return "code_bool"; } #line 1158 "./src/generator/c_gen.am" if (code_string_equals(expr->Str, "await")) { #line 1159 "./src/generator/c_gen.am" code_string ar = Amalgame_Compiler_CGen_ResolveAwaitRetC(self, expr->Left); #line 1160 "./src/generator/c_gen.am" if (String_Length(ar) > 0LL) { return ar; } } } else if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 1165 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_LocalTypeGet(self, expr->Name); } else if (k == Amalgame_Compiler_NodeKind_MEMBER) { #line 1169 "./src/generator/c_gen.am" if (expr->Left != NULL) { #line 1170 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind lk = expr->Left->Kind; #line 1171 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 1172 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_FieldTypeGet(self, self->CurrentClass, expr->Name); } #line 1174 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 1175 "./src/generator/c_gen.am" code_string lname = expr->Left->Name; #line 1176 "./src/generator/c_gen.am" code_string varCType = Amalgame_Compiler_CGen_LocalTypeGet(self, lname); #line 1177 "./src/generator/c_gen.am" code_string bare = String_Replace(varCType, "*", ""); #line 1178 "./src/generator/c_gen.am" if (String_Length(bare) > 0LL) { #line 1179 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_FieldTypeGet(self, bare, expr->Name); } #line 1182 "./src/generator/c_gen.am" code_string symT = Amalgame_Compiler_CGen_SymName(self, lname); #line 1183 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsEnum(self, symT)) { return symT; } #line 1184 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsEnum(self, lname)) { return Amalgame_Compiler_CGen_SymName(self, lname); } } #line 1187 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_CALL) { #line 1188 "./src/generator/c_gen.am" code_string callRetT = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Left); #line 1189 "./src/generator/c_gen.am" code_string bareCall = String_Replace(callRetT, "*", ""); #line 1190 "./src/generator/c_gen.am" if (String_Length(bareCall) > 0LL) { #line 1191 "./src/generator/c_gen.am" code_string ft = Amalgame_Compiler_CGen_FieldTypeGet(self, bareCall, expr->Name); #line 1192 "./src/generator/c_gen.am" if (String_Length(ft) > 0LL) { return ft; } } } #line 1197 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_MEMBER) { #line 1198 "./src/generator/c_gen.am" if (expr->Left->Left != NULL) { #line 1199 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind llk2 = expr->Left->Left->Kind; #line 1200 "./src/generator/c_gen.am" if (llk2 == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 1201 "./src/generator/c_gen.am" code_string fname2 = expr->Left->Name; #line 1202 "./src/generator/c_gen.am" code_string parentT = Amalgame_Compiler_CGen_FieldTypeGet(self, self->CurrentClass, fname2); #line 1203 "./src/generator/c_gen.am" code_string bareP = String_Replace(parentT, "*", ""); #line 1204 "./src/generator/c_gen.am" if (String_Length(bareP) > 0LL) { #line 1205 "./src/generator/c_gen.am" code_string ft2 = Amalgame_Compiler_CGen_FieldTypeGet(self, bareP, expr->Name); #line 1206 "./src/generator/c_gen.am" if (String_Length(ft2) > 0LL) { return ft2; } } } #line 1209 "./src/generator/c_gen.am" if (llk2 == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 1210 "./src/generator/c_gen.am" code_string vname3 = expr->Left->Left->Name; #line 1211 "./src/generator/c_gen.am" code_string vtype3 = Amalgame_Compiler_CGen_LocalTypeGet(self, vname3); #line 1212 "./src/generator/c_gen.am" code_string bareV = String_Replace(vtype3, "*", ""); #line 1213 "./src/generator/c_gen.am" if (String_Length(bareV) > 0LL) { #line 1214 "./src/generator/c_gen.am" code_string fname3 = expr->Left->Name; #line 1215 "./src/generator/c_gen.am" code_string parentT3 = Amalgame_Compiler_CGen_FieldTypeGet(self, bareV, fname3); #line 1216 "./src/generator/c_gen.am" code_string bareP3 = String_Replace(parentT3, "*", ""); #line 1217 "./src/generator/c_gen.am" if (String_Length(bareP3) > 0LL) { #line 1218 "./src/generator/c_gen.am" code_string ft3 = Amalgame_Compiler_CGen_FieldTypeGet(self, bareP3, expr->Name); #line 1219 "./src/generator/c_gen.am" if (String_Length(ft3) > 0LL) { return ft3; } } } } #line 1224 "./src/generator/c_gen.am" if (llk2 == Amalgame_Compiler_NodeKind_MEMBER) { #line 1225 "./src/generator/c_gen.am" if (expr->Left->Left->Left != NULL) { #line 1226 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* lll = expr->Left->Left->Left; #line 1227 "./src/generator/c_gen.am" if (lll->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 1228 "./src/generator/c_gen.am" code_string vn4 = lll->Name; #line 1229 "./src/generator/c_gen.am" code_string vt4 = Amalgame_Compiler_CGen_LocalTypeGet(self, vn4); #line 1230 "./src/generator/c_gen.am" code_string bare4 = String_Replace(vt4, "*", ""); #line 1231 "./src/generator/c_gen.am" if (String_Length(bare4) > 0LL) { #line 1232 "./src/generator/c_gen.am" code_string fn4 = expr->Left->Left->Name; #line 1233 "./src/generator/c_gen.am" code_string pt4 = Amalgame_Compiler_CGen_FieldTypeGet(self, bare4, fn4); #line 1234 "./src/generator/c_gen.am" code_string bp4 = String_Replace(pt4, "*", ""); #line 1235 "./src/generator/c_gen.am" if (String_Length(bp4) > 0LL) { #line 1236 "./src/generator/c_gen.am" code_string fn5 = expr->Left->Name; #line 1237 "./src/generator/c_gen.am" code_string pt5 = Amalgame_Compiler_CGen_FieldTypeGet(self, bp4, fn5); #line 1238 "./src/generator/c_gen.am" code_string bp5 = String_Replace(pt5, "*", ""); #line 1239 "./src/generator/c_gen.am" if (String_Length(bp5) > 0LL) { #line 1240 "./src/generator/c_gen.am" code_string ft5 = Amalgame_Compiler_CGen_FieldTypeGet(self, bp5, expr->Name); #line 1241 "./src/generator/c_gen.am" if (String_Length(ft5) > 0LL) { return ft5; } } } } } } } } } } #line 1251 "./src/generator/c_gen.am" return ""; } else if (k == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 1254 "./src/generator/c_gen.am" code_string tname = expr->Name; #line 1255 "./src/generator/c_gen.am" if (String_StartsWith(tname, "List<") || (code_string_equals(tname, "List"))) { return "AmalgameList*"; } #line 1256 "./src/generator/c_gen.am" if (String_StartsWith(tname, "Map<") || (code_string_equals(tname, "Map"))) { return "AmalgameMap*"; } #line 1257 "./src/generator/c_gen.am" if (String_StartsWith(tname, "Set<") || (code_string_equals(tname, "Set"))) { return "AmalgameSet*"; } #line 1264 "./src/generator/c_gen.am" if (code_string_equals(tname, "Match")) { return "AmalgameRegexMatch*"; } #line 1265 "./src/generator/c_gen.am" if (code_string_equals(tname, "WebSocket")) { return "AmalgameWebSocket*"; } #line 1266 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsEnum(self, tname)) { return Amalgame_Compiler_CGen_SymName(self, tname); } #line 1271 "./src/generator/c_gen.am" code_string externalMangled = Amalgame_Compiler_CGen_ExternalClassMangled(self, tname); #line 1272 "./src/generator/c_gen.am" if (String_Length(externalMangled) > 0LL) { #line 1273 "./src/generator/c_gen.am" return code_string_concat(externalMangled, "*"); } #line 1281 "./src/generator/c_gen.am" return code_string_concat(Amalgame_Compiler_CGen_ClassMangledFor(self, tname), "*"); } else if (k == Amalgame_Compiler_NodeKind_CALL) { #line 1288 "./src/generator/c_gen.am" if ((((expr->Left != NULL) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) && (code_string_equals(expr->Left->Name, "persist"))) && (AmalgameList_count(expr->Args) == 1LL)) { #line 1290 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_InferTypeFromExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 0LL)); } #line 1296 "./src/generator/c_gen.am" if ((expr->Left != NULL) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER)) { #line 1297 "./src/generator/c_gen.am" code_string mname = expr->Left->Name; #line 1298 "./src/generator/c_gen.am" if ((code_string_equals(mname, "Filter")) || (code_string_equals(mname, "Map"))) { return "AmalgameList*"; } #line 1299 "./src/generator/c_gen.am" if ((code_string_equals(mname, "Any")) || (code_string_equals(mname, "All"))) { return "code_bool"; } #line 1300 "./src/generator/c_gen.am" if (code_string_equals(mname, "CountIf")) { return "i64"; } } #line 1302 "./src/generator/c_gen.am" if (expr->Left != NULL) { #line 1303 "./src/generator/c_gen.am" code_string calleeStr = Amalgame_Compiler_CGen_EmitCalleeStr(self, expr->Left); #line 1304 "./src/generator/c_gen.am" if (((((code_string_equals(calleeStr, "AmalgameMap_has")) || (code_string_equals(calleeStr, "AmalgameMap_remove"))) || (code_string_equals(calleeStr, "AmalgameSet_contains"))) || (code_string_equals(calleeStr, "AmalgameSet_remove"))) || (code_string_equals(calleeStr, "AmalgameSet_add"))) { return "code_bool"; } #line 1305 "./src/generator/c_gen.am" if ((code_string_equals(calleeStr, "AmalgameMap_size")) || (code_string_equals(calleeStr, "AmalgameSet_size"))) { return "i64"; } #line 1306 "./src/generator/c_gen.am" if ((code_string_equals(calleeStr, "AmalgameList_isEmpty")) || (code_string_equals(calleeStr, "AmalgameList_remove"))) { return "code_bool"; } #line 1309 "./src/generator/c_gen.am" code_string algPrefix = "__alg__"; #line 1310 "./src/generator/c_gen.am" i64 enCount2 = AmalgameList_count(self->EnumNames); #line 1311 "./src/generator/c_gen.am" for (i64 eni = 0LL; eni < enCount2; eni++) { #line 1312 "./src/generator/c_gen.am" code_string ename = (code_string)AmalgameList_get(self->EnumNames, eni); #line 1313 "./src/generator/c_gen.am" if (String_StartsWith(ename, algPrefix)) { #line 1314 "./src/generator/c_gen.am" code_string enumType = String_Substring(ename, String_Length(algPrefix), String_Length(ename) - String_Length(algPrefix)); #line 1315 "./src/generator/c_gen.am" if (String_StartsWith(calleeStr, code_string_concat(enumType, "_"))) { #line 1316 "./src/generator/c_gen.am" return enumType; } } } #line 1322 "./src/generator/c_gen.am" if ((expr->Left != NULL) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 1323 "./src/generator/c_gen.am" code_string calleeLocalType = Amalgame_Compiler_CGen_LocalTypeGet(self, expr->Left->Name); #line 1324 "./src/generator/c_gen.am" if (code_string_equals(calleeLocalType, "__macro__")) { return "i64"; } } #line 1326 "./src/generator/c_gen.am" if ((((code_string_equals(calleeStr, "String_Length")) || (code_string_equals(calleeStr, "String_IndexOf"))) || (code_string_equals(calleeStr, "String_LastIndexOf"))) || (code_string_equals(calleeStr, "String_ToInt"))) { return "i64"; } #line 1327 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "String_ToFloat")) { return "double"; } #line 1328 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "String_ToBool")) { return "code_bool"; } #line 1329 "./src/generator/c_gen.am" if ((((code_string_equals(calleeStr, "String_Contains")) || (code_string_equals(calleeStr, "String_StartsWith"))) || (code_string_equals(calleeStr, "String_EndsWith"))) || (code_string_equals(calleeStr, "String_IsEmpty"))) { return "code_bool"; } #line 1330 "./src/generator/c_gen.am" if (String_StartsWith(calleeStr, "String_")) { return "code_string"; } #line 1332 "./src/generator/c_gen.am" if ((code_string_equals(calleeStr, "Args_Count")) || (code_string_equals(calleeStr, "Exit_Get"))) { return "i64"; } #line 1333 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Args_Get")) { return "code_string"; } #line 1334 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Exit_Set")) { return "void"; } #line 1335 "./src/generator/c_gen.am" if (String_EndsWith(calleeStr, "_CharAt")) { return "code_string"; } #line 1336 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "code_string_concat")) { return "code_string"; } #line 1337 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "AmalgameList_count")) { return "i64"; } #line 1338 "./src/generator/c_gen.am" if (String_StartsWith(calleeStr, "AmalgameList_count")) { return "i64"; } #line 1340 "./src/generator/c_gen.am" if ((((((code_string_equals(calleeStr, "File_Exists")) || (code_string_equals(calleeStr, "File_WriteAll"))) || (code_string_equals(calleeStr, "File_AppendAll"))) || (code_string_equals(calleeStr, "File_Delete"))) || (code_string_equals(calleeStr, "File_IsFile"))) || (code_string_equals(calleeStr, "File_IsDir"))) { return "code_bool"; } #line 1341 "./src/generator/c_gen.am" if ((((code_string_equals(calleeStr, "File_WriteLines")) || (code_string_equals(calleeStr, "File_OpenWrite"))) || (code_string_equals(calleeStr, "File_StreamLine"))) || (code_string_equals(calleeStr, "File_CloseWrite"))) { return "void"; } #line 1342 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "File_WriteLines")) { return "void"; } #line 1343 "./src/generator/c_gen.am" if ((code_string_equals(calleeStr, "File_ReadAll")) || (code_string_equals(calleeStr, "File_ReadLine"))) { return "code_string"; } #line 1344 "./src/generator/c_gen.am" if ((code_string_equals(calleeStr, "File_Size")) || (code_string_equals(calleeStr, "File_Mtime"))) { return "i64"; } #line 1346 "./src/generator/c_gen.am" if (((((((code_string_equals(calleeStr, "Path_Combine")) || (code_string_equals(calleeStr, "Path_GetExtension"))) || (code_string_equals(calleeStr, "Path_GetFilename"))) || (code_string_equals(calleeStr, "Path_GetDirectory"))) || (code_string_equals(calleeStr, "Path_GetStem"))) || (code_string_equals(calleeStr, "Path_Normalize"))) || (code_string_equals(calleeStr, "Path_Sep"))) { return "code_string"; } #line 1347 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Path_IsAbsolute")) { return "code_bool"; } #line 1351 "./src/generator/c_gen.am" if ((code_string_equals(calleeStr, "Log_GetMinLevel")) || (code_string_equals(calleeStr, "Log_GetFile"))) { return "code_string"; } #line 1352 "./src/generator/c_gen.am" if ((((((code_string_equals(calleeStr, "Log_SetMinLevel")) || (code_string_equals(calleeStr, "Log_SetFile"))) || (code_string_equals(calleeStr, "Log_Debug"))) || (code_string_equals(calleeStr, "Log_Info"))) || (code_string_equals(calleeStr, "Log_Warn"))) || (code_string_equals(calleeStr, "Log_Error"))) { return "void"; } #line 1354 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Service_ShouldStop")) { return "code_bool"; } #line 1355 "./src/generator/c_gen.am" if (((code_string_equals(calleeStr, "Service_Install")) || (code_string_equals(calleeStr, "Service_RequestStop"))) || (code_string_equals(calleeStr, "Service_Sleep"))) { return "void"; } #line 1366 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Env_Get")) { return "code_string"; } #line 1367 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Env_Has")) { return "code_bool"; } #line 1368 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Process_RunCapture")) { return "AmalgameProcessResult*"; } #line 1369 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Process_Run")) { return "i64"; } #line 1370 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Process_RunCaptureBoth")) { return "AmalgameProcessResult*"; } #line 1371 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Process_RunCaptureBothTimeout")) { return "AmalgameProcessResult*"; } #line 1372 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Process_RunTimeout")) { return "i64"; } #line 1373 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Process_Spawn")) { return "AmalgameProcessHandle*"; } #line 1374 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Process_IsAlive")) { return "code_bool"; } #line 1375 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Process_ExitCode")) { return "i64"; } #line 1376 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Process_Wait")) { return "code_bool"; } #line 1377 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Process_WriteLine")) { return "code_bool"; } #line 1378 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Process_ReadLine")) { return "code_string"; } #line 1379 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Process_ReadErrLine")) { return "code_string"; } #line 1380 "./src/generator/c_gen.am" if ((code_string_equals(calleeStr, "Console_ReadLine")) || (code_string_equals(calleeStr, "Console_ReadBytes"))) { return "code_string"; } #line 1381 "./src/generator/c_gen.am" if ((code_string_equals(calleeStr, "Console_Flush")) || (code_string_equals(calleeStr, "Console_Write"))) { return "void"; } #line 1386 "./src/generator/c_gen.am" if ((((code_string_equals(calleeStr, "String_Length")) || (code_string_equals(calleeStr, "String_IndexOf"))) || (code_string_equals(calleeStr, "String_LastIndexOf"))) || (code_string_equals(calleeStr, "String_ToInt"))) { return "i64"; } #line 1387 "./src/generator/c_gen.am" if ((((code_string_equals(calleeStr, "String_StartsWith")) || (code_string_equals(calleeStr, "String_EndsWith"))) || (code_string_equals(calleeStr, "String_Contains"))) || (code_string_equals(calleeStr, "String_IsEmpty"))) { return "code_bool"; } #line 1388 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "TcpServer_Listen")) { return "AmalgameTcpServer*"; } #line 1389 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "TcpServer_Accept")) { return "AmalgameTcpConn*"; } #line 1390 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "TcpClient_Connect")) { return "AmalgameTcpClient*"; } #line 1391 "./src/generator/c_gen.am" if ((((code_string_equals(calleeStr, "TcpServer_IsListening")) || (code_string_equals(calleeStr, "TcpConn_Send"))) || (code_string_equals(calleeStr, "TcpConn_Close"))) || (code_string_equals(calleeStr, "TcpServer_Stop"))) { return "code_bool"; } #line 1392 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "TcpConn_Receive")) { return "code_string"; } #line 1394 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "UdpSocket_New")) { return "AmalgameUdpSocket*"; } #line 1395 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "UdpSocket_ReceiveFrom")) { return "AmalgameUdpDatagram*"; } #line 1397 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "UdpSocket_SetRecvBuf")) { return "i64"; } #line 1409 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Regex_Match")) { return "AmalgameRegexMatch*"; } #line 1410 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Regex_Test")) { return "code_bool"; } #line 1411 "./src/generator/c_gen.am" if ((code_string_equals(calleeStr, "Regex_Replace")) || (code_string_equals(calleeStr, "Regex_ReplaceAll"))) { return "code_string"; } #line 1412 "./src/generator/c_gen.am" if ((code_string_equals(calleeStr, "Match_GetText")) || (code_string_equals(calleeStr, "Match_GroupText"))) { return "code_string"; } #line 1413 "./src/generator/c_gen.am" if (((((code_string_equals(calleeStr, "Match_GetStart")) || (code_string_equals(calleeStr, "Match_GetEnd"))) || (code_string_equals(calleeStr, "Match_GroupCount"))) || (code_string_equals(calleeStr, "Match_GroupStart"))) || (code_string_equals(calleeStr, "Match_GroupEnd"))) { return "i64"; } #line 1415 "./src/generator/c_gen.am" if (((((code_string_equals(calleeStr, "Compress_Gzip")) || (code_string_equals(calleeStr, "Compress_Gunzip"))) || (code_string_equals(calleeStr, "Compress_Deflate"))) || (code_string_equals(calleeStr, "Compress_Inflate"))) || (code_string_equals(calleeStr, "Compress_GzipString"))) { return "AmalgameList*"; } #line 1416 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "Compress_GunzipString")) { return "code_string"; } #line 1418 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "WebSocket_Connect")) { return "AmalgameWebSocket*"; } #line 1419 "./src/generator/c_gen.am" if ((code_string_equals(calleeStr, "WebSocket_SendText")) || (code_string_equals(calleeStr, "WebSocket_IsConnected"))) { return "code_bool"; } #line 1420 "./src/generator/c_gen.am" if (((code_string_equals(calleeStr, "WebSocket_ReceiveText")) || (code_string_equals(calleeStr, "WebSocket_GetHost"))) || (code_string_equals(calleeStr, "WebSocket_AcceptKey"))) { return "code_string"; } #line 1421 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "WebSocket_GetPort")) { return "i64"; } #line 1422 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, "WebSocket_Close")) { return "void"; } #line 1435 "./src/generator/c_gen.am" i64 pkgN = AmalgameList_count(self->PkgFuncs); #line 1436 "./src/generator/c_gen.am" for (i64 pkgI = 0LL; pkgI < pkgN; pkgI++) { #line 1437 "./src/generator/c_gen.am" if (code_string_equals(calleeStr, (code_string)AmalgameList_get(self->PkgFuncs, pkgI))) { #line 1438 "./src/generator/c_gen.am" return (code_string)AmalgameList_get(self->PkgFuncCTypes, pkgI); } } #line 1441 "./src/generator/c_gen.am" if (expr->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER) { #line 1442 "./src/generator/c_gen.am" code_string mname2 = expr->Left->Name; #line 1450 "./src/generator/c_gen.am" if (code_string_equals(mname2, "Count")) { return "i64"; } #line 1451 "./src/generator/c_gen.am" if (code_string_equals(mname2, "Size")) { #line 1452 "./src/generator/c_gen.am" if (expr->Left->Left != NULL) { #line 1453 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind llkS = expr->Left->Left->Kind; #line 1454 "./src/generator/c_gen.am" if (llkS == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 1455 "./src/generator/c_gen.am" code_string recvT = Amalgame_Compiler_CGen_LocalTypeGet(self, expr->Left->Left->Name); #line 1456 "./src/generator/c_gen.am" if ((((code_string_equals(recvT, "AmalgameList*")) || (code_string_equals(recvT, "AmalgameMap*"))) || (code_string_equals(recvT, "AmalgameSet*"))) || (code_string_equals(recvT, "AmalgameDict*"))) { #line 1457 "./src/generator/c_gen.am" return "i64"; } } #line 1460 "./src/generator/c_gen.am" if (llkS == Amalgame_Compiler_NodeKind_MEMBER) { #line 1461 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* ll = expr->Left->Left; #line 1462 "./src/generator/c_gen.am" if ((ll->Left != NULL) && (ll->Left->Kind == Amalgame_Compiler_NodeKind_THIS_EXPR)) { #line 1463 "./src/generator/c_gen.am" code_string ft = Amalgame_Compiler_CGen_FieldTypeGet(self, self->CurrentClass, ll->Name); #line 1464 "./src/generator/c_gen.am" if ((((code_string_equals(ft, "AmalgameList*")) || (code_string_equals(ft, "AmalgameMap*"))) || (code_string_equals(ft, "AmalgameSet*"))) || (code_string_equals(ft, "AmalgameDict*"))) { #line 1465 "./src/generator/c_gen.am" return "i64"; } } } } } #line 1474 "./src/generator/c_gen.am" if (code_string_equals(mname2, "Clear")) { return "void"; } #line 1475 "./src/generator/c_gen.am" if (code_string_equals(mname2, "Reserve")) { return "void"; } #line 1476 "./src/generator/c_gen.am" if (((((code_string_equals(mname2, "IsEmpty")) || (code_string_equals(mname2, "Has"))) || (code_string_equals(mname2, "Contains"))) || (code_string_equals(mname2, "Remove"))) || (code_string_equals(mname2, "Add"))) { #line 1478 "./src/generator/c_gen.am" if ((expr->Left->Left != NULL) && (expr->Left->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 1479 "./src/generator/c_gen.am" code_string objN = expr->Left->Left->Name; #line 1480 "./src/generator/c_gen.am" code_string objT = Amalgame_Compiler_CGen_LocalTypeGet(self, objN); #line 1481 "./src/generator/c_gen.am" if ((code_string_equals(objT, "AmalgameList*")) && (code_string_equals(mname2, "IsEmpty"))) { return "code_bool"; } #line 1482 "./src/generator/c_gen.am" if ((code_string_equals(objT, "AmalgameList*")) && (code_string_equals(mname2, "Remove"))) { return "code_bool"; } #line 1483 "./src/generator/c_gen.am" if ((code_string_equals(objT, "AmalgameMap*")) && ((code_string_equals(mname2, "Has")) || (code_string_equals(mname2, "Remove")))) { return "code_bool"; } #line 1484 "./src/generator/c_gen.am" if ((code_string_equals(objT, "AmalgameSet*")) && (((code_string_equals(mname2, "Contains")) || (code_string_equals(mname2, "Remove"))) || (code_string_equals(mname2, "Add")))) { return "code_bool"; } } } #line 1487 "./src/generator/c_gen.am" if (code_string_equals(mname2, "Get")) { #line 1489 "./src/generator/c_gen.am" if (expr->Left->Left != NULL) { #line 1490 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* ll = expr->Left->Left; #line 1491 "./src/generator/c_gen.am" if (ll->Kind == Amalgame_Compiler_NodeKind_THIS_EXPR) { } #line 1495 "./src/generator/c_gen.am" if (ll->Kind == Amalgame_Compiler_NodeKind_MEMBER) { #line 1496 "./src/generator/c_gen.am" if (ll->Left != NULL) { #line 1497 "./src/generator/c_gen.am" if (ll->Left->Kind == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 1498 "./src/generator/c_gen.am" code_string fn3 = ll->Name; #line 1499 "./src/generator/c_gen.am" code_string et = Amalgame_Compiler_CGen_ListElemGet(self, self->CurrentClass, fn3); #line 1500 "./src/generator/c_gen.am" if (String_Length(et) > 0LL) { return et; } } #line 1511 "./src/generator/c_gen.am" if (ll->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 1512 "./src/generator/c_gen.am" code_string objN3 = ll->Left->Name; #line 1513 "./src/generator/c_gen.am" code_string objT3 = Amalgame_Compiler_CGen_LocalTypeGet(self, objN3); #line 1514 "./src/generator/c_gen.am" code_string bareO = String_Replace(objT3, "*", ""); #line 1515 "./src/generator/c_gen.am" if (String_Length(bareO) > 0LL) { #line 1516 "./src/generator/c_gen.am" code_string etV = Amalgame_Compiler_CGen_ListElemGet(self, bareO, ll->Name); #line 1517 "./src/generator/c_gen.am" if (String_Length(etV) > 0LL) { return etV; } } } } } #line 1522 "./src/generator/c_gen.am" if (ll->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 1523 "./src/generator/c_gen.am" code_string vn3 = ll->Name; #line 1524 "./src/generator/c_gen.am" code_string vtype = Amalgame_Compiler_CGen_LocalTypeGet(self, vn3); #line 1525 "./src/generator/c_gen.am" code_string bare3 = String_Replace(vtype, "*", ""); #line 1532 "./src/generator/c_gen.am" if (String_Length(bare3) > 0LL) { #line 1533 "./src/generator/c_gen.am" code_string urt = Amalgame_Compiler_CGen_MethodRetGet(self, bare3, "Get"); #line 1534 "./src/generator/c_gen.am" if (String_Length(urt) > 0LL) { return urt; } } #line 1543 "./src/generator/c_gen.am" code_string listElem = Amalgame_Compiler_CGen_ListElemGet(self, "__local__", vn3); #line 1544 "./src/generator/c_gen.am" if (String_Length(listElem) > 0LL) { return listElem; } #line 1545 "./src/generator/c_gen.am" code_string mapElem = Amalgame_Compiler_CGen_ListElemGet(self, "__local_map__", vn3); #line 1546 "./src/generator/c_gen.am" if (String_Length(mapElem) > 0LL) { return mapElem; } } #line 1553 "./src/generator/c_gen.am" if (ll->Kind == Amalgame_Compiler_NodeKind_CALL) { #line 1554 "./src/generator/c_gen.am" code_string chainT = Amalgame_Compiler_CGen_InferTypeFromExpr(self, ll); #line 1555 "./src/generator/c_gen.am" code_string chainBare = String_Replace(chainT, "*", ""); #line 1556 "./src/generator/c_gen.am" if (String_Length(chainBare) > 0LL) { #line 1557 "./src/generator/c_gen.am" code_string urt = Amalgame_Compiler_CGen_MethodRetGet(self, chainBare, "Get"); #line 1558 "./src/generator/c_gen.am" if (String_Length(urt) > 0LL) { return urt; } } } } #line 1562 "./src/generator/c_gen.am" return "void*"; } #line 1564 "./src/generator/c_gen.am" if (expr->Left->Left != NULL) { #line 1565 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind llk2 = expr->Left->Left->Kind; #line 1567 "./src/generator/c_gen.am" if (llk2 == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 1568 "./src/generator/c_gen.am" code_string retT = Amalgame_Compiler_CGen_MethodRetGet(self, self->CurrentClass, mname2); #line 1569 "./src/generator/c_gen.am" if (String_Length(retT) > 0LL) { return retT; } } #line 1576 "./src/generator/c_gen.am" if (llk2 == Amalgame_Compiler_NodeKind_CALL) { #line 1577 "./src/generator/c_gen.am" code_string chainT2 = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Left->Left); #line 1578 "./src/generator/c_gen.am" code_string chainBare2 = String_Replace(chainT2, "*", ""); #line 1579 "./src/generator/c_gen.am" if (String_Length(chainBare2) > 0LL) { #line 1580 "./src/generator/c_gen.am" code_string retTC = Amalgame_Compiler_CGen_MethodRetGet(self, chainBare2, mname2); #line 1581 "./src/generator/c_gen.am" if (String_Length(retTC) > 0LL) { return retTC; } } } #line 1589 "./src/generator/c_gen.am" if (llk2 == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 1590 "./src/generator/c_gen.am" code_string recvT = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Left->Left); #line 1591 "./src/generator/c_gen.am" code_string recvBare = String_Replace(recvT, "*", ""); #line 1592 "./src/generator/c_gen.am" if (String_Length(recvBare) > 0LL) { #line 1593 "./src/generator/c_gen.am" code_string retTN = Amalgame_Compiler_CGen_MethodRetGet(self, recvBare, mname2); #line 1594 "./src/generator/c_gen.am" if (String_Length(retTN) > 0LL) { return retTN; } } } #line 1598 "./src/generator/c_gen.am" if (llk2 == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 1599 "./src/generator/c_gen.am" code_string cname2 = expr->Left->Left->Name; #line 1600 "./src/generator/c_gen.am" code_string firstC = String_Substring(cname2, 0LL, 1LL); #line 1601 "./src/generator/c_gen.am" code_bool isUpp = code_string_equals(firstC, String_ToUpper(firstC)); #line 1602 "./src/generator/c_gen.am" if (isUpp) { #line 1611 "./src/generator/c_gen.am" code_string extMangled = Amalgame_Compiler_CGen_ExternalClassMangled(self, cname2); #line 1612 "./src/generator/c_gen.am" if (String_Length(extMangled) > 0LL) { #line 1613 "./src/generator/c_gen.am" code_string retTE = Amalgame_Compiler_CGen_MethodRetGet(self, extMangled, mname2); #line 1614 "./src/generator/c_gen.am" if (String_Length(retTE) > 0LL) { return retTE; } } #line 1620 "./src/generator/c_gen.am" code_string pkgMangled2 = Amalgame_Compiler_CGen_PkgClassMangledPrefix(self, cname2); #line 1621 "./src/generator/c_gen.am" if ((String_Length(pkgMangled2) > 0LL) && !Amalgame_Compiler_CGen_IsLocalClass(self, cname2)) { #line 1622 "./src/generator/c_gen.am" code_string retTP = Amalgame_Compiler_CGen_MethodRetGet(self, pkgMangled2, mname2); #line 1623 "./src/generator/c_gen.am" if (String_Length(retTP) > 0LL) { return retTP; } } #line 1625 "./src/generator/c_gen.am" code_string symCls = Amalgame_Compiler_CGen_SymName(self, cname2); #line 1626 "./src/generator/c_gen.am" code_string retT2 = Amalgame_Compiler_CGen_MethodRetGet(self, symCls, mname2); #line 1627 "./src/generator/c_gen.am" if (String_Length(retT2) > 0LL) { return retT2; } } #line 1630 "./src/generator/c_gen.am" if (!isUpp) { #line 1631 "./src/generator/c_gen.am" code_string objType = Amalgame_Compiler_CGen_LocalTypeGet(self, cname2); #line 1632 "./src/generator/c_gen.am" code_string bareCls = String_Replace(objType, "*", ""); #line 1633 "./src/generator/c_gen.am" if (String_Length(bareCls) > 0LL) { #line 1634 "./src/generator/c_gen.am" code_string retT3 = Amalgame_Compiler_CGen_MethodRetGet(self, bareCls, mname2); #line 1635 "./src/generator/c_gen.am" if (String_Length(retT3) > 0LL) { return retT3; } } } } } } } } else { } } #line 1645 "./src/generator/c_gen.am" return ""; } static code_bool Amalgame_Compiler_CGen_IsValidInterpExpr(Amalgame_Compiler_CGen* self, code_string s) { #line 1659 "./src/generator/c_gen.am" i64 n = String_Length(s); #line 1660 "./src/generator/c_gen.am" if (n == 0LL) { return 0; } #line 1661 "./src/generator/c_gen.am" code_string first = String_Substring(s, 0LL, 1LL); #line 1662 "./src/generator/c_gen.am" code_bool identStart = String_Contains("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_", first); #line 1663 "./src/generator/c_gen.am" if (!identStart) { return 0; } #line 1664 "./src/generator/c_gen.am" code_string identCont = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_."; #line 1665 "./src/generator/c_gen.am" i64 i = 1LL; #line 1666 "./src/generator/c_gen.am" while (i < n) { #line 1667 "./src/generator/c_gen.am" code_string ch = String_Substring(s, i, 1LL); #line 1668 "./src/generator/c_gen.am" if (code_string_equals(ch, "(")) { #line 1675 "./src/generator/c_gen.am" code_string last = String_Substring(s, n - 1LL, 1LL); #line 1676 "./src/generator/c_gen.am" if (code_string_equals(last, ")")) { return 1; } #line 1677 "./src/generator/c_gen.am" return 0; } #line 1679 "./src/generator/c_gen.am" code_bool ok = String_Contains(identCont, ch); #line 1680 "./src/generator/c_gen.am" if (!ok) { return 0; } #line 1681 "./src/generator/c_gen.am" i = (i + 1LL); } #line 1683 "./src/generator/c_gen.am" return 1; } static code_string Amalgame_Compiler_CGen_EmitInterpolatedString(Amalgame_Compiler_CGen* self, code_string raw) { #line 1693 "./src/generator/c_gen.am" i64 hasInterp = String_IndexOf(raw, "{"); #line 1694 "./src/generator/c_gen.am" if (hasInterp < 0LL) { #line 1695 "./src/generator/c_gen.am" code_string escaped = Amalgame_Compiler_CGen_EscapeStringForC(self, raw); #line 1696 "./src/generator/c_gen.am" return code_string_concat((code_string_concat("\"", escaped)), "\""); } #line 1698 "./src/generator/c_gen.am" i64 len = String_Length(raw); #line 1700 "./src/generator/c_gen.am" code_bool hasValid = 0; #line 1701 "./src/generator/c_gen.am" i64 ci = 0LL; #line 1702 "./src/generator/c_gen.am" while (ci < len) { #line 1703 "./src/generator/c_gen.am" code_string cch = String_Substring(raw, ci, 1LL); #line 1704 "./src/generator/c_gen.am" if (code_string_equals(cch, "{")) { #line 1705 "./src/generator/c_gen.am" code_string rest = String_Substring(raw, ci + 1LL, (len - ci) - 1LL); #line 1706 "./src/generator/c_gen.am" i64 close = String_IndexOf(rest, "}"); #line 1707 "./src/generator/c_gen.am" if (close > 0LL) { #line 1708 "./src/generator/c_gen.am" code_string inner = String_Substring(raw, ci + 1LL, close); #line 1709 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsValidInterpExpr(self, inner)) { #line 1710 "./src/generator/c_gen.am" hasValid = 1; #line 1711 "./src/generator/c_gen.am" ci = len; } else { #line 1713 "./src/generator/c_gen.am" ci = (ci + 1LL); } } else { #line 1716 "./src/generator/c_gen.am" ci = (ci + 1LL); } } else { #line 1719 "./src/generator/c_gen.am" ci = (ci + 1LL); } } #line 1722 "./src/generator/c_gen.am" if (!hasValid) { #line 1723 "./src/generator/c_gen.am" code_string escaped = Amalgame_Compiler_CGen_EscapeStringForC(self, raw); #line 1724 "./src/generator/c_gen.am" return code_string_concat((code_string_concat("\"", escaped)), "\""); } #line 1727 "./src/generator/c_gen.am" code_string result = "\"\""; #line 1728 "./src/generator/c_gen.am" i64 i = 0LL; #line 1729 "./src/generator/c_gen.am" i64 segStart = 0LL; #line 1730 "./src/generator/c_gen.am" while (i < len) { #line 1731 "./src/generator/c_gen.am" code_string ch = String_Substring(raw, i, 1LL); #line 1732 "./src/generator/c_gen.am" if (code_string_equals(ch, "{")) { #line 1733 "./src/generator/c_gen.am" code_string rest2 = String_Substring(raw, i + 1LL, (len - i) - 1LL); #line 1734 "./src/generator/c_gen.am" i64 close2 = String_IndexOf(rest2, "}"); #line 1735 "./src/generator/c_gen.am" if (close2 > 0LL) { #line 1736 "./src/generator/c_gen.am" code_string expr = String_Substring(raw, i + 1LL, close2); #line 1737 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsValidInterpExpr(self, expr)) { #line 1738 "./src/generator/c_gen.am" if (i > segStart) { #line 1739 "./src/generator/c_gen.am" code_string seg = String_Substring(raw, segStart, i - segStart); #line 1740 "./src/generator/c_gen.am" code_string esc = Amalgame_Compiler_CGen_EscapeStringForC(self, seg); #line 1741 "./src/generator/c_gen.am" result = (code_string_concat((code_string_concat((code_string_concat((code_string_concat("code_string_concat(", result)), ", \"")), esc)), "\")")); } #line 1743 "./src/generator/c_gen.am" code_string cExpr = Amalgame_Compiler_CGen_InterpExprToC(self, expr); #line 1744 "./src/generator/c_gen.am" result = (code_string_concat((code_string_concat((code_string_concat((code_string_concat("code_string_concat(", result)), ", ")), cExpr)), ")")); #line 1745 "./src/generator/c_gen.am" segStart = (((i + 1LL) + close2) + 1LL); #line 1746 "./src/generator/c_gen.am" i = segStart; } else { #line 1748 "./src/generator/c_gen.am" i = (i + 1LL); } } else { #line 1751 "./src/generator/c_gen.am" i = (i + 1LL); } } else { #line 1754 "./src/generator/c_gen.am" i = (i + 1LL); } } #line 1757 "./src/generator/c_gen.am" if (segStart < len) { #line 1758 "./src/generator/c_gen.am" code_string seg = String_Substring(raw, segStart, len - segStart); #line 1759 "./src/generator/c_gen.am" code_string esc = Amalgame_Compiler_CGen_EscapeStringForC(self, seg); #line 1760 "./src/generator/c_gen.am" result = (code_string_concat((code_string_concat((code_string_concat((code_string_concat("code_string_concat(", result)), ", \"")), esc)), "\")")); } #line 1762 "./src/generator/c_gen.am" return result; } static code_string Amalgame_Compiler_CGen_WrapForInterp(Amalgame_Compiler_CGen* self, code_string cExpr, code_string cType) { #line 1768 "./src/generator/c_gen.am" if (code_string_equals(cType, "code_string")) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", cExpr)), " ? ")), cExpr)), " : \"\")"); } #line 1769 "./src/generator/c_gen.am" if (code_string_equals(cType, "i64")) { return code_string_concat((code_string_concat("String_FromInt(", cExpr)), ")"); } #line 1770 "./src/generator/c_gen.am" if (code_string_equals(cType, "double")) { return code_string_concat((code_string_concat("String_FromFloat(", cExpr)), ")"); } #line 1771 "./src/generator/c_gen.am" if (code_string_equals(cType, "code_bool")) { return code_string_concat((code_string_concat("((", cExpr)), ") ? \"true\" : \"false\")"); } #line 1773 "./src/generator/c_gen.am" return code_string_concat((code_string_concat("String_FromInt((i64)(", cExpr)), "))"); } static code_string Amalgame_Compiler_CGen_BuiltinCallReturnType(Amalgame_Compiler_CGen* self, code_string cName) { #line 1779 "./src/generator/c_gen.am" if ((((code_string_equals(cName, "String_Length")) || (code_string_equals(cName, "String_IndexOf"))) || (code_string_equals(cName, "String_LastIndexOf"))) || (code_string_equals(cName, "String_ToInt"))) { return "i64"; } #line 1780 "./src/generator/c_gen.am" if (code_string_equals(cName, "String_ToFloat")) { return "double"; } #line 1781 "./src/generator/c_gen.am" if (((((code_string_equals(cName, "String_IsEmpty")) || (code_string_equals(cName, "String_Contains"))) || (code_string_equals(cName, "String_StartsWith"))) || (code_string_equals(cName, "String_EndsWith"))) || (code_string_equals(cName, "String_ToBool"))) { return "code_bool"; } #line 1782 "./src/generator/c_gen.am" if (String_StartsWith(cName, "String_")) { return "code_string"; } #line 1786 "./src/generator/c_gen.am" if (code_string_equals(cName, "File_ReadAll")) { return "code_string"; } #line 1787 "./src/generator/c_gen.am" if ((((((code_string_equals(cName, "File_Exists")) || (code_string_equals(cName, "File_WriteAll"))) || (code_string_equals(cName, "File_AppendAll"))) || (code_string_equals(cName, "File_Delete"))) || (code_string_equals(cName, "File_IsFile"))) || (code_string_equals(cName, "File_IsDir"))) { return "code_bool"; } #line 1788 "./src/generator/c_gen.am" if ((((code_string_equals(cName, "File_Size")) || (code_string_equals(cName, "File_Mtime"))) || (code_string_equals(cName, "Args_Count"))) || (code_string_equals(cName, "Exit_Get"))) { return "i64"; } #line 1789 "./src/generator/c_gen.am" if (code_string_equals(cName, "Args_Get")) { return "code_string"; } #line 1790 "./src/generator/c_gen.am" return ""; } static code_string Amalgame_Compiler_CGen_InterpExprToC(Amalgame_Compiler_CGen* self, code_string expr) { #line 1798 "./src/generator/c_gen.am" i64 parenIdx = String_IndexOf(expr, "("); #line 1799 "./src/generator/c_gen.am" if (parenIdx > 0LL) { #line 1800 "./src/generator/c_gen.am" code_string callee = String_Substring(expr, 0LL, parenIdx); #line 1801 "./src/generator/c_gen.am" code_string rest = String_Substring(expr, parenIdx, String_Length(expr) - parenIdx); #line 1807 "./src/generator/c_gen.am" i64 dotIn = String_IndexOf(callee, "."); #line 1808 "./src/generator/c_gen.am" if ((dotIn > 0LL) && (String_IndexOf(String_Substring(callee, dotIn + 1LL, (String_Length(callee) - dotIn) - 1LL), ".") == -1LL)) { #line 1809 "./src/generator/c_gen.am" code_string objName = String_Substring(callee, 0LL, dotIn); #line 1810 "./src/generator/c_gen.am" code_string mName = String_Substring(callee, dotIn + 1LL, (String_Length(callee) - dotIn) - 1LL); #line 1811 "./src/generator/c_gen.am" code_string objType = Amalgame_Compiler_CGen_LocalTypeGet(self, objName); #line 1812 "./src/generator/c_gen.am" if ((String_Length(objType) > 0LL) && String_Contains(objType, "*")) { #line 1813 "./src/generator/c_gen.am" code_string bareT = String_Replace(objType, "*", ""); #line 1814 "./src/generator/c_gen.am" code_string inside = String_Substring(rest, 1LL, String_Length(rest) - 2LL); #line 1815 "./src/generator/c_gen.am" code_string iCall = ""; #line 1816 "./src/generator/c_gen.am" if (String_Length(inside) == 0LL) { #line 1817 "./src/generator/c_gen.am" iCall = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(bareT, "_")), mName)), "(")), objName)), ")")); } else { #line 1819 "./src/generator/c_gen.am" iCall = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(bareT, "_")), mName)), "(")), objName)), ", ")), inside)), ")")); } #line 1821 "./src/generator/c_gen.am" code_string iRetT = Amalgame_Compiler_CGen_MethodRetGet(self, bareT, mName); #line 1822 "./src/generator/c_gen.am" if (String_Length(iRetT) > 0LL) { #line 1823 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_WrapForInterp(self, iCall, iRetT); } #line 1825 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", iCall)), " ? ")), iCall)), " : \"\")"); } } #line 1828 "./src/generator/c_gen.am" code_string cCallee = String_Replace(callee, ".", "_"); #line 1829 "./src/generator/c_gen.am" code_string cCall = code_string_concat(cCallee, rest); #line 1830 "./src/generator/c_gen.am" code_string retT = Amalgame_Compiler_CGen_BuiltinCallReturnType(self, cCallee); #line 1831 "./src/generator/c_gen.am" if (String_Length(retT) > 0LL) { #line 1832 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_WrapForInterp(self, cCall, retT); } #line 1835 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", cCall)), " ? ")), cCall)), " : \"\")"); } #line 1838 "./src/generator/c_gen.am" if (String_StartsWith(expr, "this.")) { #line 1839 "./src/generator/c_gen.am" code_string field = String_Substring(expr, 5LL, String_Length(expr) - 5LL); #line 1840 "./src/generator/c_gen.am" code_string ft = Amalgame_Compiler_CGen_FieldTypeGet(self, self->CurrentClass, field); #line 1841 "./src/generator/c_gen.am" if (code_string_equals(ft, "i64")) { return code_string_concat((code_string_concat("String_FromInt(self->", field)), ")"); } #line 1842 "./src/generator/c_gen.am" if (code_string_equals(ft, "double")) { return code_string_concat((code_string_concat("String_FromFloat(self->", field)), ")"); } #line 1843 "./src/generator/c_gen.am" if (code_string_equals(ft, "code_bool")) { return code_string_concat((code_string_concat("((self->", field)), ") ? \"true\" : \"false\")"); } #line 1844 "./src/generator/c_gen.am" if (code_string_equals(ft, "code_string")) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("(self->", field)), " ? self->")), field)), " : \"\")"); } #line 1846 "./src/generator/c_gen.am" if ((String_Length(ft) > 0LL) && !String_Contains(ft, "*")) { return code_string_concat((code_string_concat("String_FromInt((i64)self->", field)), ")"); } #line 1847 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("(self->", field)), " ? self->")), field)), " : \"\")"); } #line 1850 "./src/generator/c_gen.am" i64 dotIdx = String_IndexOf(expr, "."); #line 1851 "./src/generator/c_gen.am" if (dotIdx > 0LL) { #line 1852 "./src/generator/c_gen.am" code_string objName = String_Substring(expr, 0LL, dotIdx); #line 1853 "./src/generator/c_gen.am" code_string field2 = String_Substring(expr, dotIdx + 1LL, (String_Length(expr) - dotIdx) - 1LL); #line 1854 "./src/generator/c_gen.am" code_string objType = Amalgame_Compiler_CGen_LocalTypeGet(self, objName); #line 1855 "./src/generator/c_gen.am" code_string bareT = String_Replace(objType, "*", ""); #line 1856 "./src/generator/c_gen.am" if (String_Length(bareT) > 0LL) { #line 1857 "./src/generator/c_gen.am" code_string ft2 = Amalgame_Compiler_CGen_FieldTypeGet(self, bareT, field2); #line 1858 "./src/generator/c_gen.am" if (code_string_equals(ft2, "i64")) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("String_FromInt(", objName)), "->")), field2)), ")"); } #line 1859 "./src/generator/c_gen.am" if (code_string_equals(ft2, "double")) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("String_FromFloat(", objName)), "->")), field2)), ")"); } #line 1860 "./src/generator/c_gen.am" if (code_string_equals(ft2, "code_bool")) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("((", objName)), "->")), field2)), ") ? \"true\" : \"false\")"); } #line 1861 "./src/generator/c_gen.am" if (code_string_equals(ft2, "code_string")) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", objName)), "->")), field2)), " ? ")), objName)), "->")), field2)), " : \"\")"); } #line 1863 "./src/generator/c_gen.am" if ((String_Length(ft2) > 0LL) && !String_Contains(ft2, "*")) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("String_FromInt((i64)", objName)), "->")), field2)), ")"); } #line 1864 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", objName)), "->")), field2)), " ? ")), objName)), "->")), field2)), " : \"\")"); } } #line 1868 "./src/generator/c_gen.am" code_string varC = Amalgame_Compiler_CGen_LocalTypeGet(self, expr); #line 1869 "./src/generator/c_gen.am" if (code_string_equals(varC, "i64")) { return code_string_concat((code_string_concat("String_FromInt(", expr)), ")"); } #line 1870 "./src/generator/c_gen.am" if (code_string_equals(varC, "double")) { return code_string_concat((code_string_concat("String_FromFloat(", expr)), ")"); } #line 1871 "./src/generator/c_gen.am" if (code_string_equals(varC, "code_bool")) { return code_string_concat((code_string_concat("(", expr)), " ? \"true\" : \"false\")"); } #line 1872 "./src/generator/c_gen.am" if (String_Length(varC) > 0LL) { #line 1873 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", expr)), " ? ")), expr)), " : \"\")"); } #line 1876 "./src/generator/c_gen.am" return code_string_concat((code_string_concat("String_FromInt(", expr)), ")"); } static code_string Amalgame_Compiler_CGen_EscapeStringForC(Amalgame_Compiler_CGen* self, code_string raw) { #line 1883 "./src/generator/c_gen.am" code_string s = String_Replace(raw, "\\", "\\\\"); #line 1884 "./src/generator/c_gen.am" s = String_Replace(s, "\"", "\\\""); #line 1885 "./src/generator/c_gen.am" s = String_Replace(s, "\n", "\\n"); #line 1886 "./src/generator/c_gen.am" s = String_Replace(s, "\t", "\\t"); #line 1893 "./src/generator/c_gen.am" s = String_Replace(s, String_FromByte(13LL), "\\r"); #line 1895 "./src/generator/c_gen.am" s = String_Replace(s, String_FromByte(27LL), "\\x1b"); #line 1896 "./src/generator/c_gen.am" return s; } static void Amalgame_Compiler_CGen_EmitHeader(Amalgame_Compiler_CGen* self) { #line 1906 "./src/generator/c_gen.am" if (self->Embedded) { #line 1907 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#include \"_runtime.h\""); #line 1908 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); #line 1909 "./src/generator/c_gen.am" return; } #line 1911 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#include "); #line 1912 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#include "); #line 1913 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#include "); #line 1914 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#include \"_runtime.h\""); #line 1915 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#include \"Amalgame_String.h\""); #line 1916 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#include \"Amalgame_Collections.h\""); #line 1917 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#include \"Amalgame_IO.h\""); #line 1932 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#include \"Amalgame_Net.h\""); #line 1933 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#include \"Amalgame_Console.h\""); #line 1934 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#include \"Amalgame_Process.h\""); #line 1957 "./src/generator/c_gen.am" i64 pkgHdrN = AmalgameList_count(self->PkgHeaders); #line 1958 "./src/generator/c_gen.am" for (i64 ph = 0LL; ph < pkgHdrN; ph++) { #line 1964 "./src/generator/c_gen.am" if (self->ImportsFiltered) { #line 1965 "./src/generator/c_gen.am" code_string phNs = (code_string)AmalgameList_get(self->PkgHeaderNs, ph); #line 1966 "./src/generator/c_gen.am" if (!Amalgame_Compiler_CGen_NamespaceImported(self, phNs)) { #line 1967 "./src/generator/c_gen.am" continue; } } #line 1970 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("#include \"", (code_string)AmalgameList_get(self->PkgHeaders, ph))), "\"")); } #line 1972 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); } code_bool Amalgame_Compiler_CGen_NamespaceImported(Amalgame_Compiler_CGen* self, code_string ns) { #line 1985 "./src/generator/c_gen.am" i64 nsLen = String_Length(ns); #line 1986 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->ImportedNs); #line 1987 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 1988 "./src/generator/c_gen.am" code_string imp = (code_string)AmalgameList_get(self->ImportedNs, i); #line 1989 "./src/generator/c_gen.am" if (code_string_equals(imp, ns)) { return 1; } #line 1990 "./src/generator/c_gen.am" i64 impLen = String_Length(imp); #line 1991 "./src/generator/c_gen.am" if (impLen > nsLen) { #line 1993 "./src/generator/c_gen.am" if (String_StartsWith(imp, code_string_concat(ns, "."))) { return 1; } } else { #line 1996 "./src/generator/c_gen.am" if (String_StartsWith(ns, code_string_concat(imp, "."))) { return 1; } } } #line 1999 "./src/generator/c_gen.am" return 0; } void Amalgame_Compiler_CGen_SetImportedNamespaces(Amalgame_Compiler_CGen* self, AmalgameList* imports) { #line 2008 "./src/generator/c_gen.am" self->ImportedNs = imports; #line 2009 "./src/generator/c_gen.am" self->ImportsFiltered = 1; } void Amalgame_Compiler_CGen_SetEmbedded(Amalgame_Compiler_CGen* self, code_bool v) { #line 2012 "./src/generator/c_gen.am" self->Embedded = v; } static code_string Amalgame_Compiler_CGen_AllocFn(Amalgame_Compiler_CGen* self) { #line 2019 "./src/generator/c_gen.am" if (self->Embedded) { return "code_alloc"; } #line 2020 "./src/generator/c_gen.am" return "GC_MALLOC"; } void Amalgame_Compiler_CGen_EmitNetHeader(Amalgame_Compiler_CGen* self) { #line 2024 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#include \"Amalgame_Net.h\""); } void Amalgame_Compiler_CGen_RegisterPackages(Amalgame_Compiler_CGen* self, Amalgame_Compiler_PackageRegistry* reg) { #line 2044 "./src/generator/c_gen.am" self->PkgClasses = AmalgameList_new(); #line 2045 "./src/generator/c_gen.am" self->PkgFuncs = AmalgameList_new(); #line 2046 "./src/generator/c_gen.am" self->PkgFuncCTypes = AmalgameList_new(); #line 2047 "./src/generator/c_gen.am" self->PkgHeaders = AmalgameList_new(); #line 2048 "./src/generator/c_gen.am" self->PkgHeaderNs = AmalgameList_new(); #line 2049 "./src/generator/c_gen.am" self->PkgClassNs = AmalgameList_new(); #line 2050 "./src/generator/c_gen.am" self->PkgOpaqueTypes = AmalgameList_new(); #line 2051 "./src/generator/c_gen.am" i64 n = AmalgameList_count(reg->Packages); #line 2052 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2053 "./src/generator/c_gen.am" Amalgame_Compiler_LoadedPackage* p = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(reg->Packages, i); #line 2060 "./src/generator/c_gen.am" code_bool skipDup = 0; #line 2061 "./src/generator/c_gen.am" for (i64 k = 0LL; k < n; k++) { #line 2062 "./src/generator/c_gen.am" if (k == i) { continue; } #line 2063 "./src/generator/c_gen.am" Amalgame_Compiler_LoadedPackage* q = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(reg->Packages, k); #line 2064 "./src/generator/c_gen.am" if (!code_string_equals(q->Ns, p->Ns)) { continue; } #line 2065 "./src/generator/c_gen.am" i64 cmp = Amalgame_Compiler_PackageRegistry_CompareCmp(q->Tag, p->Tag); #line 2066 "./src/generator/c_gen.am" if (cmp > 0LL) { skipDup = 1; } else if ((cmp == 0LL) && (k < i)) { #line 2067 "./src/generator/c_gen.am" skipDup = 1; } } #line 2069 "./src/generator/c_gen.am" if (skipDup) { continue; } #line 2073 "./src/generator/c_gen.am" i64 pkgCn = AmalgameList_count(p->ClassNames); #line 2074 "./src/generator/c_gen.am" for (i64 pkgCi = 0LL; pkgCi < pkgCn; pkgCi++) { #line 2075 "./src/generator/c_gen.am" AmalgameList_add(self->PkgClasses, (void*)(intptr_t)((code_string)AmalgameList_get(p->ClassNames, pkgCi))); #line 2076 "./src/generator/c_gen.am" AmalgameList_add(self->PkgClassNs, (void*)(intptr_t)(p->Ns)); } #line 2078 "./src/generator/c_gen.am" AmalgameList_add(self->PkgHeaders, (void*)(intptr_t)(p->Header)); #line 2079 "./src/generator/c_gen.am" AmalgameList_add(self->PkgHeaderNs, (void*)(intptr_t)(p->Ns)); #line 2084 "./src/generator/c_gen.am" i64 fn = AmalgameList_count(p->FuncNames); #line 2085 "./src/generator/c_gen.am" for (i64 j = 0LL; j < fn; j++) { #line 2086 "./src/generator/c_gen.am" code_string fName = (code_string)AmalgameList_get(p->FuncNames, j); #line 2087 "./src/generator/c_gen.am" code_string cType = (code_string)AmalgameList_get(p->FuncRets, j); #line 2088 "./src/generator/c_gen.am" code_string mangled = Amalgame_Compiler_PackageRegistry_ManglePackageSymbol(p->Ns, fName); #line 2089 "./src/generator/c_gen.am" AmalgameList_add(self->PkgFuncs, (void*)(intptr_t)(mangled)); #line 2090 "./src/generator/c_gen.am" AmalgameList_add(self->PkgFuncCTypes, (void*)(intptr_t)(cType)); #line 2102 "./src/generator/c_gen.am" if (j < AmalgameList_count(p->FuncRetsRaw)) { #line 2103 "./src/generator/c_gen.am" code_string rawShape = (code_string)AmalgameList_get(p->FuncRetsRaw, j); #line 2104 "./src/generator/c_gen.am" if (String_Length(rawShape) > 0LL) { #line 2105 "./src/generator/c_gen.am" for (i64 pkgCk = 0LL; pkgCk < pkgCn; pkgCk++) { #line 2106 "./src/generator/c_gen.am" code_string mc = Amalgame_Compiler_CGen_PkgClassMangledPrefix(self, (code_string)AmalgameList_get(p->ClassNames, pkgCk)); #line 2107 "./src/generator/c_gen.am" if (String_Length(mc) > 0LL) { #line 2108 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodRetRawSet(self, mc, fName, rawShape); } } } } #line 2122 "./src/generator/c_gen.am" if (String_EndsWith(cType, "*")) { #line 2123 "./src/generator/c_gen.am" code_string amType = Amalgame_Compiler_PackageRegistry_AmalgameTypeFromC(cType); #line 2124 "./src/generator/c_gen.am" if (String_Length(amType) > 0LL) { #line 2127 "./src/generator/c_gen.am" code_bool seen = 0; #line 2128 "./src/generator/c_gen.am" i64 oc = AmalgameList_count(self->PkgOpaqueTypes); #line 2129 "./src/generator/c_gen.am" for (i64 oi = 0LL; oi < oc; oi++) { #line 2130 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->PkgOpaqueTypes, oi), amType)) { seen = 1; } } #line 2132 "./src/generator/c_gen.am" if (!seen) { #line 2133 "./src/generator/c_gen.am" AmalgameList_add(self->PkgOpaqueTypes, (void*)(intptr_t)(amType)); } } } } } } void Amalgame_Compiler_CGen_RegisterExternalProg(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog) { #line 2160 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_RegisterExternalProgPass1(self, prog); #line 2161 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_RegisterExternalProgPass2(self, prog); } void Amalgame_Compiler_CGen_RegisterExternalProgPass1(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog) { #line 2179 "./src/generator/c_gen.am" code_string ns = prog->Str; #line 2180 "./src/generator/c_gen.am" if (String_Length(ns) == 0LL) { return; } #line 2181 "./src/generator/c_gen.am" code_string nsPrefix = String_Replace(ns, ".", "_"); #line 2182 "./src/generator/c_gen.am" AmalgameList* kids = prog->Children; #line 2183 "./src/generator/c_gen.am" i64 n = AmalgameList_count(kids); #line 2193 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2194 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(kids, i); #line 2195 "./src/generator/c_gen.am" if (decl->Kind == Amalgame_Compiler_NodeKind_CLASS_DECL) { #line 2196 "./src/generator/c_gen.am" code_string mangled = code_string_concat((code_string_concat(nsPrefix, "_")), decl->Name); #line 2197 "./src/generator/c_gen.am" if (decl->Flag2) { #line 2201 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_RegisterIface(self, decl->Name, mangled, decl); #line 2202 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("struct ", mangled)), "_itab;")); #line 2203 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("typedef struct { const struct ", mangled)), "_itab* itab; void* data; } ")), mangled)), "; /* external iface */")); } else { #line 2206 "./src/generator/c_gen.am" AmalgameList_add(self->ExternalClasses, (void*)(intptr_t)(decl->Name)); #line 2207 "./src/generator/c_gen.am" AmalgameList_add(self->ExternalClassNsArr, (void*)(intptr_t)(nsPrefix)); #line 2208 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("typedef struct _", mangled)), " ")), mangled)), "; /* external */")); } } #line 2211 "./src/generator/c_gen.am" if (decl->Kind == Amalgame_Compiler_NodeKind_ENUM_DECL) { #line 2212 "./src/generator/c_gen.am" code_bool isAlg = 0; #line 2213 "./src/generator/c_gen.am" i64 vc = AmalgameList_count(decl->Children); #line 2214 "./src/generator/c_gen.am" for (i64 vi = 0LL; vi < vc; vi++) { #line 2215 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* vm = (Amalgame_Compiler_AstNode*)AmalgameList_get(decl->Children, vi); #line 2216 "./src/generator/c_gen.am" if (String_Length(vm->Str) > 0LL) { isAlg = 1; } } #line 2218 "./src/generator/c_gen.am" if (isAlg) { #line 2225 "./src/generator/c_gen.am" code_string mangled = code_string_concat((code_string_concat(nsPrefix, "_")), decl->Name); #line 2226 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("typedef struct _", mangled)), " ")), mangled)), "; /* external alg-enum fwd */")); } else { #line 2228 "./src/generator/c_gen.am" AmalgameList_add(self->ExternalEnums, (void*)(intptr_t)(decl->Name)); #line 2229 "./src/generator/c_gen.am" AmalgameList_add(self->ExternalEnumNsArr, (void*)(intptr_t)(nsPrefix)); #line 2230 "./src/generator/c_gen.am" code_string mangled = code_string_concat((code_string_concat(nsPrefix, "_")), decl->Name); #line 2233 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("typedef enum _", mangled)), " {")); #line 2234 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 2235 "./src/generator/c_gen.am" for (i64 vi = 0LL; vi < vc; vi++) { #line 2236 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* vm = (Amalgame_Compiler_AstNode*)AmalgameList_get(decl->Children, vi); #line 2237 "./src/generator/c_gen.am" code_string memberC = code_string_concat((code_string_concat(mangled, "_")), vm->Name); #line 2238 "./src/generator/c_gen.am" if (vi < (vc - 1LL)) { #line 2239 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(memberC, ",")); } else { #line 2241 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, memberC); } } #line 2244 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 2245 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("} ", mangled)), "; /* external */")); } } } } void Amalgame_Compiler_CGen_RegisterExternalProgPass2(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog) { #line 2258 "./src/generator/c_gen.am" code_string ns = prog->Str; #line 2259 "./src/generator/c_gen.am" if (String_Length(ns) == 0LL) { return; } #line 2260 "./src/generator/c_gen.am" code_string nsPrefix = String_Replace(ns, ".", "_"); #line 2261 "./src/generator/c_gen.am" AmalgameList* kids = prog->Children; #line 2262 "./src/generator/c_gen.am" i64 n = AmalgameList_count(kids); #line 2280 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2281 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(kids, i); #line 2282 "./src/generator/c_gen.am" if (decl->Kind != Amalgame_Compiler_NodeKind_CLASS_DECL) { continue; } #line 2283 "./src/generator/c_gen.am" code_string mangled = code_string_concat((code_string_concat(nsPrefix, "_")), decl->Name); #line 2286 "./src/generator/c_gen.am" if (decl->Flag2) { #line 2287 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("struct ", mangled)), "_itab {")); #line 2288 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 2289 "./src/generator/c_gen.am" i64 imc = AmalgameList_count(decl->Children); #line 2290 "./src/generator/c_gen.am" for (i64 imi = 0LL; imi < imc; imi++) { #line 2291 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* im = (Amalgame_Compiler_AstNode*)AmalgameList_get(decl->Children, imi); #line 2292 "./src/generator/c_gen.am" if (im->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 2293 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(Amalgame_Compiler_CGen_IfaceFnPtrField(self, im), ";")); } } #line 2296 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 2297 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "};"); #line 2298 "./src/generator/c_gen.am" continue; } #line 2300 "./src/generator/c_gen.am" AmalgameList* members = decl->Children; #line 2301 "./src/generator/c_gen.am" i64 mc = AmalgameList_count(members); #line 2305 "./src/generator/c_gen.am" for (i64 mi = 0LL; mi < mc; mi++) { #line 2306 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(members, mi); #line 2307 "./src/generator/c_gen.am" if (m->Kind == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 2308 "./src/generator/c_gen.am" code_string rawType = m->Str; #line 2309 "./src/generator/c_gen.am" code_string ftype = Amalgame_Compiler_CGen_TypeToC(self, rawType); #line 2310 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, mangled, m->Name, ftype); #line 2311 "./src/generator/c_gen.am" if (String_StartsWith(rawType, "List<")) { #line 2312 "./src/generator/c_gen.am" code_string inner = String_Substring(rawType, 5LL, String_Length(rawType) - 6LL); #line 2313 "./src/generator/c_gen.am" code_string elemC = Amalgame_Compiler_CGen_TypeToC(self, inner); #line 2314 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, mangled, m->Name, elemC); } #line 2316 "./src/generator/c_gen.am" if (String_StartsWith(rawType, "Map<") && String_EndsWith(rawType, ">")) { #line 2317 "./src/generator/c_gen.am" code_string mi2 = String_Substring(rawType, 4LL, String_Length(rawType) - 5LL); #line 2318 "./src/generator/c_gen.am" i64 mcomma = String_IndexOf(mi2, ","); #line 2319 "./src/generator/c_gen.am" if (mcomma > 0LL) { #line 2320 "./src/generator/c_gen.am" code_string vRaw = String_Substring(mi2, mcomma + 1LL, (String_Length(mi2) - mcomma) - 1LL); #line 2321 "./src/generator/c_gen.am" code_string vTrim = String_Trim(vRaw); #line 2322 "./src/generator/c_gen.am" if (String_Length(vTrim) > 0LL) { #line 2323 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, mangled, m->Name, Amalgame_Compiler_CGen_TypeToC(self, vTrim)); } } } #line 2331 "./src/generator/c_gen.am" if (String_StartsWith(rawType, "Closure<") && String_EndsWith(rawType, ">")) { #line 2332 "./src/generator/c_gen.am" code_string cinner = String_Substring(rawType, 8LL, String_Length(rawType) - 9LL); #line 2333 "./src/generator/c_gen.am" AmalgameList* cparts = Amalgame_Compiler_CGen_SplitTopLevelCommas(self, cinner); #line 2334 "./src/generator/c_gen.am" i64 cpc = AmalgameList_count(cparts); #line 2335 "./src/generator/c_gen.am" if (cpc >= 1LL) { #line 2336 "./src/generator/c_gen.am" code_string crawRet = String_Trim((code_string)AmalgameList_get(cparts, cpc - 1LL)); #line 2337 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, code_string_concat(mangled, "__closure_ret__"), m->Name, Amalgame_Compiler_CGen_TypeToC(self, crawRet)); } } } } #line 2347 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("struct _", mangled)), " {")); #line 2348 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 2351 "./src/generator/c_gen.am" code_string parentName = decl->Str; #line 2352 "./src/generator/c_gen.am" if (String_Length(parentName) > 0LL) { #line 2353 "./src/generator/c_gen.am" code_string parentMangled = Amalgame_Compiler_CGen_ExternalClassMangled(self, parentName); #line 2354 "./src/generator/c_gen.am" if (String_Length(parentMangled) > 0LL) { #line 2355 "./src/generator/c_gen.am" i64 pfc = AmalgameList_count(self->FieldNames); #line 2356 "./src/generator/c_gen.am" code_string pfPrefix = code_string_concat(parentMangled, "."); #line 2357 "./src/generator/c_gen.am" for (i64 pfi = 0LL; pfi < pfc; pfi++) { #line 2358 "./src/generator/c_gen.am" code_string pfkey = (code_string)AmalgameList_get(self->FieldNames, pfi); #line 2359 "./src/generator/c_gen.am" if (String_StartsWith(pfkey, pfPrefix)) { #line 2360 "./src/generator/c_gen.am" code_string pfname = String_Substring(pfkey, String_Length(pfPrefix), String_Length(pfkey) - String_Length(pfPrefix)); #line 2361 "./src/generator/c_gen.am" code_string pftype = (code_string)AmalgameList_get(self->FieldCTypes, pfi); #line 2362 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(pftype, " ")), pfname)), ";")); #line 2363 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, mangled, pfname, pftype); } } } } #line 2368 "./src/generator/c_gen.am" for (i64 mi = 0LL; mi < mc; mi++) { #line 2369 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(members, mi); #line 2370 "./src/generator/c_gen.am" if (m->Kind == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 2371 "./src/generator/c_gen.am" code_string ftype = Amalgame_Compiler_CGen_TypeToC(self, m->Str); #line 2372 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(ftype, " ")), m->Name)), ";")); } } #line 2375 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 2376 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "};"); } #line 2381 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2382 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(kids, i); #line 2383 "./src/generator/c_gen.am" if ((decl->Kind == Amalgame_Compiler_NodeKind_CLASS_DECL) && !decl->Flag2) { #line 2384 "./src/generator/c_gen.am" code_string mangled = code_string_concat((code_string_concat(nsPrefix, "_")), decl->Name); #line 2385 "./src/generator/c_gen.am" AmalgameList* members = decl->Children; #line 2386 "./src/generator/c_gen.am" i64 mc = AmalgameList_count(members); #line 2387 "./src/generator/c_gen.am" for (i64 mi = 0LL; mi < mc; mi++) { #line 2388 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(members, mi); #line 2389 "./src/generator/c_gen.am" if (m->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 2390 "./src/generator/c_gen.am" code_string sig = Amalgame_Compiler_CGen_ExternalMethodSig(self, m, mangled, decl->Name); #line 2391 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(sig, ";")); #line 2395 "./src/generator/c_gen.am" if (code_string_equals(m->Name, decl->Name)) { #line 2396 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_RegisterParamIfaces(self, code_string_concat(mangled, "_new"), m); } else { #line 2398 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_RegisterParamIfaces(self, code_string_concat((code_string_concat(mangled, "_")), m->Name), m); } } } #line 2405 "./src/generator/c_gen.am" code_string impl = decl->Str4; #line 2406 "./src/generator/c_gen.am" if (String_Length(impl) > 0LL) { #line 2407 "./src/generator/c_gen.am" AmalgameList* parts = Amalgame_Compiler_CGen_SplitTopLevelCommas(self, impl); #line 2408 "./src/generator/c_gen.am" i64 pcI = AmalgameList_count(parts); #line 2409 "./src/generator/c_gen.am" for (i64 pii = 0LL; pii < pcI; pii++) { #line 2410 "./src/generator/c_gen.am" code_string iface = String_Trim((code_string)AmalgameList_get(parts, pii)); #line 2411 "./src/generator/c_gen.am" i64 lt = String_IndexOf(iface, "<"); #line 2412 "./src/generator/c_gen.am" if (lt >= 0LL) { iface = String_Substring(iface, 0LL, lt); } #line 2413 "./src/generator/c_gen.am" code_string im2 = Amalgame_Compiler_CGen_IfaceMangledFor(self, iface); #line 2414 "./src/generator/c_gen.am" if (String_Length(im2) > 0LL) { #line 2415 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("extern const struct ", im2)), "_itab ")), Amalgame_Compiler_CGen_IfaceItabSym(self, mangled, im2))), ";")); } } } } } } static code_string Amalgame_Compiler_CGen_ExternalMethodSig(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string mangledClass, code_string shortClassName) { #line 2429 "./src/generator/c_gen.am" code_bool isCtor = code_string_equals(method->Name, shortClassName); #line 2430 "./src/generator/c_gen.am" code_string retTypeRaw = method->Str; #line 2431 "./src/generator/c_gen.am" code_string retType = ""; #line 2432 "./src/generator/c_gen.am" if (String_StartsWith(retTypeRaw, "(")) { #line 2433 "./src/generator/c_gen.am" retType = Amalgame_Compiler_CGen_TupleStructName(self, retTypeRaw); } else { #line 2435 "./src/generator/c_gen.am" retType = Amalgame_Compiler_CGen_TypeToC(self, retTypeRaw); } #line 2447 "./src/generator/c_gen.am" if (!isCtor) { #line 2448 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodRetSet(self, mangledClass, method->Name, retType); #line 2449 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodRetRawSet(self, mangledClass, method->Name, retTypeRaw); #line 2455 "./src/generator/c_gen.am" i64 mpc = AmalgameList_count(method->Params); #line 2456 "./src/generator/c_gen.am" if (mpc > 0LL) { #line 2457 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* lastP = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, mpc - 1LL); #line 2458 "./src/generator/c_gen.am" if (lastP->Flag) { #line 2459 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodVariadicSet(self, code_string_concat((code_string_concat(mangledClass, "_")), method->Name), mpc - 1LL); } } } else { #line 2472 "./src/generator/c_gen.am" i64 cpc = AmalgameList_count(method->Params); #line 2473 "./src/generator/c_gen.am" if (cpc > 0LL) { #line 2474 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* lastCp = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, cpc - 1LL); #line 2475 "./src/generator/c_gen.am" if (lastCp->Flag) { #line 2476 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodVariadicSet(self, code_string_concat(mangledClass, "_new"), cpc - 1LL); } } } #line 2480 "./src/generator/c_gen.am" code_string sig = ""; #line 2481 "./src/generator/c_gen.am" if (isCtor) { #line 2482 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat((code_string_concat(mangledClass, "* ")), mangledClass)), "_new(")); } else { #line 2484 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(retType, " ")), mangledClass)), "_")), method->Name)), "(")); } #line 2486 "./src/generator/c_gen.am" code_bool isStatic = method->Flag2; #line 2487 "./src/generator/c_gen.am" code_bool first = 1; #line 2488 "./src/generator/c_gen.am" if (!isStatic && !isCtor) { #line 2489 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat(sig, mangledClass)), "* self")); #line 2490 "./src/generator/c_gen.am" first = 0; } #line 2492 "./src/generator/c_gen.am" i64 pcount = AmalgameList_count(method->Params); #line 2493 "./src/generator/c_gen.am" for (i64 i = 0LL; i < pcount; i++) { #line 2494 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 2495 "./src/generator/c_gen.am" if (!first) { sig = (code_string_concat(sig, ", ")); } #line 2498 "./src/generator/c_gen.am" if (p->Flag) { #line 2499 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat(sig, "AmalgameList* ")), p->Name)); } else { #line 2501 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat((code_string_concat(sig, Amalgame_Compiler_CGen_TypeToC(self, p->Str))), " ")), p->Name)); } #line 2503 "./src/generator/c_gen.am" first = 0; } #line 2505 "./src/generator/c_gen.am" sig = (code_string_concat(sig, ")")); #line 2506 "./src/generator/c_gen.am" return sig; } code_string Amalgame_Compiler_CGen_ExternalClassMangled(Amalgame_Compiler_CGen* self, code_string tname) { #line 2513 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->ExternalClasses); #line 2514 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2515 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->ExternalClasses, i), tname)) { #line 2516 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string)AmalgameList_get(self->ExternalClassNsArr, i), "_")), tname); } } #line 2519 "./src/generator/c_gen.am" return ""; } code_string Amalgame_Compiler_CGen_ExternalEnumMangled(Amalgame_Compiler_CGen* self, code_string tname) { #line 2528 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->ExternalEnums); #line 2529 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2530 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->ExternalEnums, i), tname)) { #line 2531 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string)AmalgameList_get(self->ExternalEnumNsArr, i), "_")), tname); } } #line 2534 "./src/generator/c_gen.am" return ""; } static code_bool Amalgame_Compiler_CGen_IsExternalClass(Amalgame_Compiler_CGen* self, code_string tname) { #line 2541 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->ExternalClasses); #line 2542 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2543 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->ExternalClasses, i), tname)) { return 1; } } #line 2545 "./src/generator/c_gen.am" return 0; } static AmalgameList* Amalgame_Compiler_CGen_SplitTopLevelCommas(Amalgame_Compiler_CGen* self, code_string s) { #line 2568 "./src/generator/c_gen.am" AmalgameList* parts = AmalgameList_new(); #line 2569 "./src/generator/c_gen.am" i64 n = String_Length(s); #line 2570 "./src/generator/c_gen.am" i64 depth = 0LL; #line 2571 "./src/generator/c_gen.am" code_string cur = ""; #line 2572 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2573 "./src/generator/c_gen.am" code_string ch = String_Substring(s, i, 1LL); #line 2574 "./src/generator/c_gen.am" if (code_string_equals(ch, "<")) { depth = (depth + 1LL); cur = (code_string_concat(cur, ch)); } else if (code_string_equals(ch, ">")) { #line 2575 "./src/generator/c_gen.am" depth = (depth - 1LL); cur = (code_string_concat(cur, ch)); } else if ((code_string_equals(ch, ",")) && (depth == 0LL)) { #line 2577 "./src/generator/c_gen.am" AmalgameList_add(parts, (void*)(intptr_t)(cur)); #line 2578 "./src/generator/c_gen.am" cur = ""; } else { #line 2580 "./src/generator/c_gen.am" cur = (code_string_concat(cur, ch)); } } #line 2583 "./src/generator/c_gen.am" if (String_Length(cur) > 0LL) { AmalgameList_add(parts, (void*)(intptr_t)(cur)); } #line 2584 "./src/generator/c_gen.am" return parts; } static code_bool Amalgame_Compiler_CGen_IsLocalClass(Amalgame_Compiler_CGen* self, code_string tname) { #line 2588 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->LocalClasses); #line 2589 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2590 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->LocalClasses, i), tname)) { return 1; } } #line 2592 "./src/generator/c_gen.am" return 0; } static void Amalgame_Compiler_CGen_RegisterIface(Amalgame_Compiler_CGen* self, code_string shortName, code_string mangled, Amalgame_Compiler_AstNode* node) { #line 2607 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->IfaceMangledNames); #line 2608 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2609 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->IfaceMangledNames, i), mangled)) { return; } } #line 2611 "./src/generator/c_gen.am" AmalgameList_add(self->IfaceShortNames, (void*)(intptr_t)(shortName)); #line 2612 "./src/generator/c_gen.am" AmalgameList_add(self->IfaceMangledNames, (void*)(intptr_t)(mangled)); #line 2613 "./src/generator/c_gen.am" AmalgameList_add(self->IfaceNodes, (void*)(intptr_t)(node)); } void Amalgame_Compiler_CGen_PreNoteInterfaces(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* prog) { #line 2621 "./src/generator/c_gen.am" code_string ns = prog->Str; #line 2622 "./src/generator/c_gen.am" if (String_Length(ns) == 0LL) { return; } #line 2623 "./src/generator/c_gen.am" code_string nsPrefix = String_Replace(ns, ".", "_"); #line 2624 "./src/generator/c_gen.am" AmalgameList* kids = prog->Children; #line 2625 "./src/generator/c_gen.am" i64 n = AmalgameList_count(kids); #line 2626 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2627 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(kids, i); #line 2628 "./src/generator/c_gen.am" if ((decl->Kind == Amalgame_Compiler_NodeKind_CLASS_DECL) && decl->Flag2) { #line 2629 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_RegisterIface(self, decl->Name, code_string_concat((code_string_concat(nsPrefix, "_")), decl->Name), decl); } } } static code_bool Amalgame_Compiler_CGen_IsInterface(Amalgame_Compiler_CGen* self, code_string tname) { #line 2636 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->IfaceShortNames); #line 2637 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2638 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->IfaceShortNames, i), tname)) { return 1; } #line 2639 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->IfaceMangledNames, i), tname)) { return 1; } } #line 2641 "./src/generator/c_gen.am" return 0; } static code_string Amalgame_Compiler_CGen_IfaceMangledFor(Amalgame_Compiler_CGen* self, code_string tname) { #line 2648 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->IfaceShortNames); #line 2649 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2650 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->IfaceShortNames, i), tname)) { return (code_string)AmalgameList_get(self->IfaceMangledNames, i); } #line 2651 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->IfaceMangledNames, i), tname)) { return (code_string)AmalgameList_get(self->IfaceMangledNames, i); } } #line 2653 "./src/generator/c_gen.am" return ""; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_CGen_IfaceNodeFor(Amalgame_Compiler_CGen* self, code_string nameOrMangled) { #line 2659 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->IfaceShortNames); #line 2660 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2661 "./src/generator/c_gen.am" if ((code_string_equals((code_string)AmalgameList_get(self->IfaceShortNames, i), nameOrMangled)) || (code_string_equals((code_string)AmalgameList_get(self->IfaceMangledNames, i), nameOrMangled))) { #line 2663 "./src/generator/c_gen.am" return (Amalgame_Compiler_AstNode*)AmalgameList_get(self->IfaceNodes, i); } } #line 2666 "./src/generator/c_gen.am" return NULL; } static code_string Amalgame_Compiler_CGen_IfaceItabSym(Amalgame_Compiler_CGen* self, code_string classMangled, code_string ifaceMangled) { #line 2673 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(classMangled, "__as__")), ifaceMangled); } static code_string Amalgame_Compiler_CGen_IfaceFnPtrField(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* m) { #line 2679 "./src/generator/c_gen.am" code_string retC = Amalgame_Compiler_CGen_TypeToC(self, m->Str); #line 2680 "./src/generator/c_gen.am" code_string ptr = code_string_concat((code_string_concat((code_string_concat(retC, " (*")), m->Name)), ")(void* self"); #line 2681 "./src/generator/c_gen.am" i64 pc = AmalgameList_count(m->Params); #line 2682 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pc; pi++) { #line 2683 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(m->Params, pi); #line 2684 "./src/generator/c_gen.am" ptr = (code_string_concat((code_string_concat(ptr, ", ")), Amalgame_Compiler_CGen_TypeToC(self, p->Str))); } #line 2686 "./src/generator/c_gen.am" ptr = (code_string_concat(ptr, ")")); #line 2687 "./src/generator/c_gen.am" return ptr; } static code_string Amalgame_Compiler_CGen_IfaceFnPtrCast(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* m) { #line 2693 "./src/generator/c_gen.am" code_string retC = Amalgame_Compiler_CGen_TypeToC(self, m->Str); #line 2694 "./src/generator/c_gen.am" code_string cast = code_string_concat((code_string_concat("(", retC)), " (*)(void* self"); #line 2695 "./src/generator/c_gen.am" i64 pc = AmalgameList_count(m->Params); #line 2696 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pc; pi++) { #line 2697 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(m->Params, pi); #line 2698 "./src/generator/c_gen.am" cast = (code_string_concat((code_string_concat(cast, ", ")), Amalgame_Compiler_CGen_TypeToC(self, p->Str))); } #line 2700 "./src/generator/c_gen.am" cast = (code_string_concat(cast, "))")); #line 2701 "./src/generator/c_gen.am" return cast; } static void Amalgame_Compiler_CGen_RegisterParamIfaces(Amalgame_Compiler_CGen* self, code_string mangled, Amalgame_Compiler_AstNode* m) { #line 2708 "./src/generator/c_gen.am" i64 pc = AmalgameList_count(m->Params); #line 2709 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pc; pi++) { #line 2710 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(m->Params, pi); #line 2711 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsInterface(self, p->Str)) { #line 2712 "./src/generator/c_gen.am" AmalgameList_add(self->ParamIfaceKeys, (void*)(intptr_t)(code_string_concat((code_string_concat(mangled, "#")), String_FromInt(pi)))); #line 2713 "./src/generator/c_gen.am" AmalgameList_add(self->ParamIfaceVals, (void*)(intptr_t)(Amalgame_Compiler_CGen_IfaceMangledFor(self, p->Str))); } } } static code_string Amalgame_Compiler_CGen_CoerceArg(Amalgame_Compiler_CGen* self, code_string callee, i64 idx, Amalgame_Compiler_AstNode* argExpr) { #line 2724 "./src/generator/c_gen.am" code_string key = code_string_concat((code_string_concat(callee, "#")), String_FromInt(idx)); #line 2725 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->ParamIfaceKeys); #line 2726 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2727 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->ParamIfaceKeys, i), key)) { #line 2728 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_CoerceToIface(self, (code_string)AmalgameList_get(self->ParamIfaceVals, i), argExpr); } } #line 2731 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_EmitExprStr(self, argExpr); } static code_string Amalgame_Compiler_CGen_CoerceToIface(Amalgame_Compiler_CGen* self, code_string ifaceMangled, Amalgame_Compiler_AstNode* argExpr) { #line 2738 "./src/generator/c_gen.am" code_string argC = Amalgame_Compiler_CGen_EmitExprStr(self, argExpr); #line 2739 "./src/generator/c_gen.am" code_string argT = Amalgame_Compiler_CGen_InferTypeFromExpr(self, argExpr); #line 2740 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsInterface(self, argT)) { return argC; } #line 2741 "./src/generator/c_gen.am" code_string argClass = String_Replace(argT, "*", ""); #line 2742 "./src/generator/c_gen.am" code_string itab = Amalgame_Compiler_CGen_IfaceItabSym(self, argClass, ifaceMangled); #line 2743 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", ifaceMangled)), "){ &")), itab)), ", (void*)(")), argC)), ") }"); } static code_string Amalgame_Compiler_CGen_BoxIface(Amalgame_Compiler_CGen* self, code_string ifaceMangled, code_string fatExpr) { #line 2751 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("({ ", ifaceMangled)), "* __bx = (")), ifaceMangled)), "*) code_alloc(sizeof(")), ifaceMangled)), ")); *__bx = ")), fatExpr)), "; (void*) __bx; })"); } static code_string Amalgame_Compiler_CGen_ResolveListElemC(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* callee) { #line 2760 "./src/generator/c_gen.am" if (callee->Left == NULL) { return ""; } #line 2761 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind lkG = callee->Left->Kind; #line 2762 "./src/generator/c_gen.am" if ((lkG == Amalgame_Compiler_NodeKind_MEMBER) && (callee->Left->Left != NULL)) { #line 2763 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* lll = callee->Left->Left; #line 2764 "./src/generator/c_gen.am" if (lll->Kind == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 2765 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_ListElemGet(self, self->CurrentClass, callee->Left->Name); } #line 2767 "./src/generator/c_gen.am" if (lll->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 2768 "./src/generator/c_gen.am" code_string bare4 = String_Replace(Amalgame_Compiler_CGen_LocalTypeGet(self, lll->Name), "*", ""); #line 2769 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_ListElemGet(self, bare4, callee->Left->Name); } } #line 2772 "./src/generator/c_gen.am" if (lkG == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 2773 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_ListElemGet(self, "__local__", callee->Left->Name); } #line 2775 "./src/generator/c_gen.am" return ""; } static code_string Amalgame_Compiler_CGen_PkgClassMangledPrefix(Amalgame_Compiler_CGen* self, code_string tname) { #line 2779 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->PkgClasses); #line 2780 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 2781 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->PkgClasses, i), tname)) { #line 2782 "./src/generator/c_gen.am" code_string ns = (code_string)AmalgameList_get(self->PkgClassNs, i); #line 2783 "./src/generator/c_gen.am" code_string mangledNs = String_Replace(ns, ".", "_"); #line 2784 "./src/generator/c_gen.am" if (code_string_equals(mangledNs, tname)) { return mangledNs; } #line 2785 "./src/generator/c_gen.am" if (String_EndsWith(mangledNs, code_string_concat("_", tname))) { #line 2786 "./src/generator/c_gen.am" return mangledNs; } #line 2788 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(mangledNs, "_")), tname); } } #line 2791 "./src/generator/c_gen.am" return ""; } static code_string Amalgame_Compiler_CGen_ClassMangledFor(Amalgame_Compiler_CGen* self, code_string tname) { #line 2811 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsLocalClass(self, tname)) { #line 2812 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_SymName(self, tname); } #line 2814 "./src/generator/c_gen.am" code_string pkgMangled = Amalgame_Compiler_CGen_PkgClassMangledPrefix(self, tname); #line 2815 "./src/generator/c_gen.am" if (String_Length(pkgMangled) > 0LL) { #line 2816 "./src/generator/c_gen.am" return pkgMangled; } #line 2818 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_SymName(self, tname); } static void Amalgame_Compiler_CGen_EmitForwardDecl(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* decl) { #line 2822 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind k = decl->Kind; #line 2823 "./src/generator/c_gen.am" if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) { #line 2824 "./src/generator/c_gen.am" code_string name = Amalgame_Compiler_CGen_SymName(self, decl->Name); #line 2826 "./src/generator/c_gen.am" code_bool isAlg = 0; #line 2827 "./src/generator/c_gen.am" i64 vc = AmalgameList_count(decl->Children); #line 2828 "./src/generator/c_gen.am" for (i64 vi = 0LL; vi < vc; vi++) { #line 2829 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* vm = (Amalgame_Compiler_AstNode*)AmalgameList_get(decl->Children, vi); #line 2830 "./src/generator/c_gen.am" if (String_Length(vm->Str) > 0LL) { isAlg = 1; } } #line 2832 "./src/generator/c_gen.am" if (isAlg) { #line 2834 "./src/generator/c_gen.am" AmalgameList_add(self->EnumNames, (void*)(intptr_t)(code_string_concat("__alg__", name))); #line 2836 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("typedef struct _", name)), " ")), name)), "; /* alg-enum fwd */")); } else { #line 2839 "./src/generator/c_gen.am" AmalgameList_add(self->EnumNames, (void*)(intptr_t)(decl->Name)); #line 2840 "./src/generator/c_gen.am" AmalgameList_add(self->EnumNames, (void*)(intptr_t)(name)); #line 2841 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("typedef enum _", name)), " ")), name)), ";")); } } #line 2844 "./src/generator/c_gen.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { #line 2845 "./src/generator/c_gen.am" code_string name = Amalgame_Compiler_CGen_SymName(self, decl->Name); #line 2846 "./src/generator/c_gen.am" if (decl->Flag2) { #line 2852 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_RegisterIface(self, decl->Name, name, decl); #line 2853 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("struct ", name)), "_itab;")); #line 2854 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("typedef struct { const struct ", name)), "_itab* itab; void* data; } ")), name)), ";")); } else { #line 2857 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("typedef struct _", name)), " ")), name)), ";")); #line 2860 "./src/generator/c_gen.am" AmalgameList_add(self->LocalClasses, (void*)(intptr_t)(decl->Name)); } } #line 2863 "./src/generator/c_gen.am" if (k == Amalgame_Compiler_NodeKind_INLINE_C) { #line 2869 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "/* inline-C top-level */"); #line 2870 "./src/generator/c_gen.am" code_string body = decl->Str; #line 2871 "./src/generator/c_gen.am" if (String_Length(body) > 0LL) { #line 2872 "./src/generator/c_gen.am" AmalgameList* lines = String_Split(body, "\n"); #line 2873 "./src/generator/c_gen.am" i64 count = AmalgameList_count(lines); #line 2874 "./src/generator/c_gen.am" for (i64 i = 0LL; i < count; i++) { #line 2875 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, (code_string)AmalgameList_get(lines, i)); } } } } static void Amalgame_Compiler_CGen_EmitDecl(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* decl) { #line 2882 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind k = decl->Kind; #line 2883 "./src/generator/c_gen.am" if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) { Amalgame_Compiler_CGen_EmitEnum(self, decl); } #line 2884 "./src/generator/c_gen.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { Amalgame_Compiler_CGen_EmitClass(self, decl); } #line 2885 "./src/generator/c_gen.am" if (k == Amalgame_Compiler_NodeKind_INLINE_C_INCLUDE) { #line 2889 "./src/generator/c_gen.am" code_string arg = decl->Str; #line 2890 "./src/generator/c_gen.am" if ((String_Length(arg) > 0LL) && (code_string_equals(String_Substring(arg, 0LL, 1LL), "<"))) { #line 2891 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat("#include ", arg)); } else { #line 2893 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("#include \"", arg)), "\"")); } } #line 2896 "./src/generator/c_gen.am" if (k == Amalgame_Compiler_NodeKind_INLINE_C_LINK) { #line 2901 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("/* link: -l", decl->Str)), " */")); } } static void Amalgame_Compiler_CGen_EmitEnum(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* en) { #line 2906 "./src/generator/c_gen.am" code_string name = Amalgame_Compiler_CGen_SymName(self, en->Name); #line 2907 "./src/generator/c_gen.am" i64 count = AmalgameList_count(en->Children); #line 2910 "./src/generator/c_gen.am" code_bool isAlgebraic = 0; #line 2911 "./src/generator/c_gen.am" for (i64 i = 0LL; i < count; i++) { #line 2912 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* member = (Amalgame_Compiler_AstNode*)AmalgameList_get(en->Children, i); #line 2913 "./src/generator/c_gen.am" if (String_Length(member->Str) > 0LL) { isAlgebraic = 1; } } #line 2916 "./src/generator/c_gen.am" if (isAlgebraic) { #line 2919 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "typedef enum {"); #line 2920 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 2921 "./src/generator/c_gen.am" for (i64 i = 0LL; i < count; i++) { #line 2922 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* member = (Amalgame_Compiler_AstNode*)AmalgameList_get(en->Children, i); #line 2923 "./src/generator/c_gen.am" code_string mname = code_string_concat((code_string_concat(name, "_TAG_")), member->Name); #line 2924 "./src/generator/c_gen.am" if (i < (count - 1LL)) { #line 2925 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(mname, ",")); } else { #line 2927 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, mname); } } #line 2930 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 2931 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("} ", name)), "_Tag;")); #line 2932 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); #line 2935 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("struct _", name)), " {")); #line 2936 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 2937 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(name, "_Tag tag;")); #line 2938 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "union {"); #line 2939 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 2940 "./src/generator/c_gen.am" for (i64 i = 0LL; i < count; i++) { #line 2941 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* member = (Amalgame_Compiler_AstNode*)AmalgameList_get(en->Children, i); #line 2942 "./src/generator/c_gen.am" code_string payloads = member->Str; #line 2943 "./src/generator/c_gen.am" if (String_Length(payloads) > 0LL) { #line 2944 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "struct {"); #line 2945 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 2947 "./src/generator/c_gen.am" i64 pi = 0LL; #line 2948 "./src/generator/c_gen.am" code_string pcur = ""; #line 2949 "./src/generator/c_gen.am" i64 pci = 0LL; #line 2950 "./src/generator/c_gen.am" i64 plen = String_Length(payloads); #line 2951 "./src/generator/c_gen.am" while (pci <= plen) { #line 2952 "./src/generator/c_gen.am" code_string pch = ""; #line 2953 "./src/generator/c_gen.am" if (pci < plen) { pch = String_Substring(payloads, pci, 1LL); } #line 2954 "./src/generator/c_gen.am" if ((code_string_equals(pch, ",")) || (pci == plen)) { #line 2955 "./src/generator/c_gen.am" if (String_Length(pcur) > 0LL) { #line 2956 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(Amalgame_Compiler_CGen_TypeToC(self, pcur), " _")), String_FromInt(pi))), ";")); #line 2957 "./src/generator/c_gen.am" pi = (pi + 1LL); #line 2958 "./src/generator/c_gen.am" pcur = ""; } } else { #line 2960 "./src/generator/c_gen.am" pcur = (code_string_concat(pcur, pch)); } #line 2961 "./src/generator/c_gen.am" pci = (pci + 1LL); } #line 2963 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 2964 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("} ", member->Name)), ";")); } else { #line 2966 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("int ", member->Name)), "_dummy;")); } } #line 2969 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 2970 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "};"); #line 2971 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 2972 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "};"); #line 2973 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); #line 2976 "./src/generator/c_gen.am" for (i64 i = 0LL; i < count; i++) { #line 2977 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* member = (Amalgame_Compiler_AstNode*)AmalgameList_get(en->Children, i); #line 2978 "./src/generator/c_gen.am" code_string payloads = member->Str; #line 2979 "./src/generator/c_gen.am" code_string params = ""; #line 2980 "./src/generator/c_gen.am" code_string fields = ""; #line 2981 "./src/generator/c_gen.am" if (String_Length(payloads) > 0LL) { #line 2982 "./src/generator/c_gen.am" i64 pi2 = 0LL; #line 2983 "./src/generator/c_gen.am" code_string pcur2 = ""; #line 2984 "./src/generator/c_gen.am" i64 pci2 = 0LL; #line 2985 "./src/generator/c_gen.am" i64 plen2 = String_Length(payloads); #line 2986 "./src/generator/c_gen.am" while (pci2 <= plen2) { #line 2987 "./src/generator/c_gen.am" code_string pch2 = ""; #line 2988 "./src/generator/c_gen.am" if (pci2 < plen2) { pch2 = String_Substring(payloads, pci2, 1LL); } #line 2989 "./src/generator/c_gen.am" if ((code_string_equals(pch2, ",")) || (pci2 == plen2)) { #line 2990 "./src/generator/c_gen.am" if (String_Length(pcur2) > 0LL) { #line 2991 "./src/generator/c_gen.am" code_string ct = Amalgame_Compiler_CGen_TypeToC(self, pcur2); #line 2992 "./src/generator/c_gen.am" code_string pname = code_string_concat("_", String_FromInt(pi2)); #line 2993 "./src/generator/c_gen.am" if (pi2 > 0LL) { params = (code_string_concat(params, ", ")); fields = (code_string_concat(fields, ", ")); } #line 2994 "./src/generator/c_gen.am" params = (code_string_concat((code_string_concat((code_string_concat(params, ct)), " ")), pname)); #line 2995 "./src/generator/c_gen.am" fields = (code_string_concat(fields, pname)); #line 2996 "./src/generator/c_gen.am" pi2 = (pi2 + 1LL); #line 2997 "./src/generator/c_gen.am" pcur2 = ""; } } else { #line 2999 "./src/generator/c_gen.am" pcur2 = (code_string_concat(pcur2, pch2)); } #line 3000 "./src/generator/c_gen.am" pci2 = (pci2 + 1LL); } } #line 3003 "./src/generator/c_gen.am" code_string ctorSig = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("static inline ", name)), " ")), name)), "_")), member->Name)), "(")), params)), ")"); #line 3004 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(ctorSig, " {")); #line 3005 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3006 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(name, " __v;")); #line 3007 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("__v.tag = ", name)), "_TAG_")), member->Name)), ";")); #line 3008 "./src/generator/c_gen.am" if (String_Length(fields) > 0LL) { #line 3010 "./src/generator/c_gen.am" i64 pi3 = 0LL; #line 3011 "./src/generator/c_gen.am" code_string pcur3 = ""; #line 3012 "./src/generator/c_gen.am" i64 pci3 = 0LL; #line 3013 "./src/generator/c_gen.am" code_string payloads3 = member->Str; #line 3014 "./src/generator/c_gen.am" i64 plen3 = String_Length(payloads3); #line 3015 "./src/generator/c_gen.am" while (pci3 <= plen3) { #line 3016 "./src/generator/c_gen.am" code_string pch3 = ""; #line 3017 "./src/generator/c_gen.am" if (pci3 < plen3) { pch3 = String_Substring(payloads3, pci3, 1LL); } #line 3018 "./src/generator/c_gen.am" if ((code_string_equals(pch3, ",")) || (pci3 == plen3)) { #line 3019 "./src/generator/c_gen.am" if (pi3 >= 0LL) { #line 3020 "./src/generator/c_gen.am" code_string fidx = String_FromInt(pi3); #line 3021 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("__v.", member->Name)), "._")), fidx)), " = _")), fidx)), ";")); #line 3022 "./src/generator/c_gen.am" pi3 = (pi3 + 1LL); } #line 3024 "./src/generator/c_gen.am" pcur3 = ""; } else { #line 3025 "./src/generator/c_gen.am" pcur3 = (code_string_concat(pcur3, pch3)); } #line 3026 "./src/generator/c_gen.am" pci3 = (pci3 + 1LL); } } #line 3029 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "return __v;"); #line 3030 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3031 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 3032 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); } #line 3036 "./src/generator/c_gen.am" AmalgameList_add(self->EnumNames, (void*)(intptr_t)(code_string_concat("__alg__", name))); } else { #line 3039 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("enum _", name)), " {")); #line 3040 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3041 "./src/generator/c_gen.am" for (i64 i = 0LL; i < count; i++) { #line 3042 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* member = (Amalgame_Compiler_AstNode*)AmalgameList_get(en->Children, i); #line 3043 "./src/generator/c_gen.am" code_string mname = code_string_concat((code_string_concat(name, "_")), member->Name); #line 3044 "./src/generator/c_gen.am" if (i < (count - 1LL)) { #line 3045 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(mname, ",")); } else { #line 3047 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, mname); } } #line 3050 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3051 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "};"); #line 3052 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); } } static void Amalgame_Compiler_CGen_EmitClass(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* cls) { #line 3057 "./src/generator/c_gen.am" code_string name = Amalgame_Compiler_CGen_SymName(self, cls->Name); #line 3058 "./src/generator/c_gen.am" i64 members = AmalgameList_count(cls->Children); #line 3064 "./src/generator/c_gen.am" if (cls->Flag2) { #line 3065 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("struct ", name)), "_itab {")); #line 3066 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3067 "./src/generator/c_gen.am" for (i64 i = 0LL; i < members; i++) { #line 3068 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* im = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, i); #line 3069 "./src/generator/c_gen.am" if (im->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 3070 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(Amalgame_Compiler_CGen_IfaceFnPtrField(self, im), ";")); } } #line 3073 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3074 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "};"); #line 3075 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); #line 3076 "./src/generator/c_gen.am" return; } #line 3080 "./src/generator/c_gen.am" self->CurrentClass = name; #line 3083 "./src/generator/c_gen.am" for (i64 i = 0LL; i < members; i++) { #line 3084 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, i); #line 3085 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 3086 "./src/generator/c_gen.am" if (mk == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 3087 "./src/generator/c_gen.am" code_string rawType = m->Str; #line 3088 "./src/generator/c_gen.am" code_string ftype = Amalgame_Compiler_CGen_TypeToC(self, rawType); #line 3089 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, name, m->Name, ftype); #line 3091 "./src/generator/c_gen.am" if (String_StartsWith(rawType, "List<")) { #line 3093 "./src/generator/c_gen.am" code_string inner = String_Substring(rawType, 5LL, String_Length(rawType) - 6LL); #line 3094 "./src/generator/c_gen.am" code_string elemC = Amalgame_Compiler_CGen_TypeToC(self, inner); #line 3095 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, name, m->Name, elemC); } #line 3100 "./src/generator/c_gen.am" if (String_StartsWith(rawType, "Map<") && String_EndsWith(rawType, ">")) { #line 3101 "./src/generator/c_gen.am" code_string mi = String_Substring(rawType, 4LL, String_Length(rawType) - 5LL); #line 3102 "./src/generator/c_gen.am" i64 mc = String_IndexOf(mi, ","); #line 3103 "./src/generator/c_gen.am" if (mc > 0LL) { #line 3104 "./src/generator/c_gen.am" code_string vRaw = String_Substring(mi, mc + 1LL, (String_Length(mi) - mc) - 1LL); #line 3105 "./src/generator/c_gen.am" code_string vTrim = String_Trim(vRaw); #line 3106 "./src/generator/c_gen.am" if (String_Length(vTrim) > 0LL) { #line 3107 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, name, m->Name, Amalgame_Compiler_CGen_TypeToC(self, vTrim)); } } } #line 3118 "./src/generator/c_gen.am" if (String_StartsWith(rawType, "Closure<") && String_EndsWith(rawType, ">")) { #line 3119 "./src/generator/c_gen.am" code_string cinner = String_Substring(rawType, 8LL, String_Length(rawType) - 9LL); #line 3120 "./src/generator/c_gen.am" AmalgameList* cparts = Amalgame_Compiler_CGen_SplitTopLevelCommas(self, cinner); #line 3121 "./src/generator/c_gen.am" i64 cpc = AmalgameList_count(cparts); #line 3122 "./src/generator/c_gen.am" if (cpc >= 1LL) { #line 3123 "./src/generator/c_gen.am" code_string crawRet = String_Trim((code_string)AmalgameList_get(cparts, cpc - 1LL)); #line 3124 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, code_string_concat(name, "__closure_ret__"), m->Name, Amalgame_Compiler_CGen_TypeToC(self, crawRet)); } } } } #line 3131 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("struct _", name)), " {")); #line 3132 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3134 "./src/generator/c_gen.am" code_string parentName = cls->Str; #line 3135 "./src/generator/c_gen.am" if (String_Length(parentName) > 0LL) { #line 3136 "./src/generator/c_gen.am" code_string parentC = Amalgame_Compiler_CGen_SymName(self, parentName); #line 3138 "./src/generator/c_gen.am" i64 pfc = AmalgameList_count(self->FieldNames); #line 3139 "./src/generator/c_gen.am" code_string pfPrefix = code_string_concat(parentC, "."); #line 3140 "./src/generator/c_gen.am" for (i64 pfi = 0LL; pfi < pfc; pfi++) { #line 3141 "./src/generator/c_gen.am" code_string pfkey = (code_string)AmalgameList_get(self->FieldNames, pfi); #line 3142 "./src/generator/c_gen.am" if (String_StartsWith(pfkey, pfPrefix)) { #line 3143 "./src/generator/c_gen.am" code_string pfname = String_Substring(pfkey, String_Length(pfPrefix), String_Length(pfkey) - String_Length(pfPrefix)); #line 3144 "./src/generator/c_gen.am" code_string pftype = (code_string)AmalgameList_get(self->FieldCTypes, pfi); #line 3145 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(pftype, " ")), pfname)), ";")); #line 3147 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_FieldTypeSet(self, name, pfname, pftype); } } } #line 3151 "./src/generator/c_gen.am" for (i64 i = 0LL; i < members; i++) { #line 3152 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, i); #line 3153 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 3154 "./src/generator/c_gen.am" if (mk == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 3155 "./src/generator/c_gen.am" code_string ftype = Amalgame_Compiler_CGen_TypeToC(self, m->Str); #line 3156 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(ftype, " ")), m->Name)), ";")); } } #line 3159 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3160 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "};"); #line 3161 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); #line 3164 "./src/generator/c_gen.am" for (i64 i = 0LL; i < members; i++) { #line 3165 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, i); #line 3166 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 3167 "./src/generator/c_gen.am" if (mk == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 3168 "./src/generator/c_gen.am" if ((!code_string_equals(m->Name, cls->Name)) && m->Flag3) { #line 3171 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitAsyncForwards(self, m, name); } else if (!code_string_equals(m->Name, cls->Name)) { #line 3173 "./src/generator/c_gen.am" code_string sig = Amalgame_Compiler_CGen_MethodSig(self, m, name); #line 3174 "./src/generator/c_gen.am" code_bool isPublic = m->Flag; #line 3179 "./src/generator/c_gen.am" code_string retC = Amalgame_Compiler_CGen_TypeToC(self, m->Str); #line 3180 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodRetSet(self, name, m->Name, retC); #line 3181 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodRetRawSet(self, name, m->Name, m->Str); #line 3187 "./src/generator/c_gen.am" i64 mpc = AmalgameList_count(m->Params); #line 3188 "./src/generator/c_gen.am" if (mpc > 0LL) { #line 3189 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* lastP = (Amalgame_Compiler_AstNode*)AmalgameList_get(m->Params, mpc - 1LL); #line 3190 "./src/generator/c_gen.am" if (lastP->Flag) { #line 3191 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodVariadicSet(self, code_string_concat((code_string_concat(name, "_")), m->Name), mpc - 1LL); } } #line 3195 "./src/generator/c_gen.am" code_string attrs = ""; #line 3196 "./src/generator/c_gen.am" code_string decos = m->Str2; #line 3197 "./src/generator/c_gen.am" if (String_Length(decos) > 0LL) { #line 3198 "./src/generator/c_gen.am" if (String_Contains(code_string_concat((code_string_concat(",", decos)), ","), ",deprecated,")) { #line 3199 "./src/generator/c_gen.am" attrs = " __attribute__((deprecated))"; } } #line 3202 "./src/generator/c_gen.am" if (isPublic) { #line 3203 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat(sig, attrs)), ";")); } else { #line 3205 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat("static ", sig)), attrs)), ";")); } } } } #line 3210 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); #line 3214 "./src/generator/c_gen.am" code_bool ctorFound = 0; #line 3215 "./src/generator/c_gen.am" for (i64 i = 0LL; i < members; i++) { #line 3216 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, i); #line 3217 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 3218 "./src/generator/c_gen.am" if (mk == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 3219 "./src/generator/c_gen.am" if (code_string_equals(m->Name, cls->Name)) { #line 3220 "./src/generator/c_gen.am" ctorFound = 1; #line 3222 "./src/generator/c_gen.am" code_string ctorSig = code_string_concat((code_string_concat((code_string_concat(name, "* ")), name)), "_new("); #line 3223 "./src/generator/c_gen.am" i64 pcount = AmalgameList_count(m->Params); #line 3224 "./src/generator/c_gen.am" code_bool first = 1; #line 3225 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pcount; pi++) { #line 3226 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(m->Params, pi); #line 3227 "./src/generator/c_gen.am" if (!first) { ctorSig = (code_string_concat(ctorSig, ", ")); } #line 3230 "./src/generator/c_gen.am" if (p->Flag) { #line 3231 "./src/generator/c_gen.am" ctorSig = (code_string_concat((code_string_concat(ctorSig, "AmalgameList* ")), p->Name)); } else { #line 3233 "./src/generator/c_gen.am" ctorSig = (code_string_concat((code_string_concat((code_string_concat(ctorSig, Amalgame_Compiler_CGen_TypeToC(self, p->Str))), " ")), p->Name)); } #line 3235 "./src/generator/c_gen.am" first = 0; } #line 3237 "./src/generator/c_gen.am" ctorSig = (code_string_concat(ctorSig, ")")); #line 3238 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(ctorSig, " {")); #line 3239 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3240 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(name, "* self = (")), name)), "*) ")), Amalgame_Compiler_CGen_AllocFn(self))), "(sizeof(")), name)), "));")); #line 3242 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeClear(self); #line 3243 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, "self", code_string_concat(name, "*")); #line 3244 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pcount; pi++) { #line 3245 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(m->Params, pi); #line 3246 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, p->Name, Amalgame_Compiler_CGen_TypeToC(self, p->Str)); } #line 3248 "./src/generator/c_gen.am" if (m->Body != NULL) { #line 3249 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitBlock(self, m->Body); } else { #line 3257 "./src/generator/c_gen.am" for (i64 pi = 0LL; pi < pcount; pi++) { #line 3258 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(m->Params, pi); #line 3260 "./src/generator/c_gen.am" code_bool hasField = 0; #line 3261 "./src/generator/c_gen.am" for (i64 fi = 0LL; fi < members; fi++) { #line 3262 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* f = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, fi); #line 3263 "./src/generator/c_gen.am" if ((f->Kind == Amalgame_Compiler_NodeKind_VAR_DECL) && (code_string_equals(f->Name, p->Name))) { #line 3264 "./src/generator/c_gen.am" hasField = 1; } } #line 3267 "./src/generator/c_gen.am" if (hasField) { #line 3268 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("self->", p->Name)), " = ")), p->Name)), ";")); } } } #line 3272 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeClear(self); #line 3273 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "return self;"); #line 3274 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3275 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 3276 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); } } } #line 3281 "./src/generator/c_gen.am" if (!ctorFound) { #line 3282 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(name, "* ")), name)), "_new() {")); #line 3283 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3284 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(name, "* self = (")), name)), "*) ")), Amalgame_Compiler_CGen_AllocFn(self))), "(sizeof(")), name)), "));")); #line 3285 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "return self;"); #line 3286 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3287 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 3288 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); } #line 3292 "./src/generator/c_gen.am" for (i64 j = 0LL; j < members; j++) { #line 3293 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* m2 = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, j); #line 3294 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind mk2 = m2->Kind; #line 3295 "./src/generator/c_gen.am" if (mk2 == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 3296 "./src/generator/c_gen.am" if ((!code_string_equals(m2->Name, cls->Name)) && m2->Flag3) { #line 3298 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitAsyncMethod(self, m2, name); } else if (!code_string_equals(m2->Name, cls->Name)) { #line 3300 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitMethod(self, m2, name); } } } #line 3310 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitClassItabs(self, cls, name); } static void Amalgame_Compiler_CGen_EmitClassItabs(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* cls, code_string name) { #line 3316 "./src/generator/c_gen.am" code_string impl = cls->Str4; #line 3317 "./src/generator/c_gen.am" if (String_Length(impl) == 0LL) { return; } #line 3318 "./src/generator/c_gen.am" AmalgameList* parts = Amalgame_Compiler_CGen_SplitTopLevelCommas(self, impl); #line 3319 "./src/generator/c_gen.am" i64 pc = AmalgameList_count(parts); #line 3320 "./src/generator/c_gen.am" for (i64 ii = 0LL; ii < pc; ii++) { #line 3321 "./src/generator/c_gen.am" code_string iface = String_Trim((code_string)AmalgameList_get(parts, ii)); #line 3323 "./src/generator/c_gen.am" i64 lt = String_IndexOf(iface, "<"); #line 3324 "./src/generator/c_gen.am" if (lt >= 0LL) { iface = String_Substring(iface, 0LL, lt); } #line 3325 "./src/generator/c_gen.am" if (String_Length(iface) == 0LL) { continue; } #line 3326 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* inode = Amalgame_Compiler_CGen_IfaceNodeFor(self, iface); #line 3327 "./src/generator/c_gen.am" if (inode == NULL) { continue; } #line 3328 "./src/generator/c_gen.am" code_string imangled = Amalgame_Compiler_CGen_IfaceMangledFor(self, iface); #line 3329 "./src/generator/c_gen.am" code_string sym = Amalgame_Compiler_CGen_IfaceItabSym(self, name, imangled); #line 3330 "./src/generator/c_gen.am" code_string line = code_string_concat((code_string_concat((code_string_concat((code_string_concat("const struct ", imangled)), "_itab ")), sym)), " = { "); #line 3331 "./src/generator/c_gen.am" i64 mc = AmalgameList_count(inode->Children); #line 3332 "./src/generator/c_gen.am" code_bool first = 1; #line 3333 "./src/generator/c_gen.am" for (i64 mi = 0LL; mi < mc; mi++) { #line 3334 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(inode->Children, mi); #line 3335 "./src/generator/c_gen.am" if (m->Kind != Amalgame_Compiler_NodeKind_METHOD_DECL) { continue; } #line 3336 "./src/generator/c_gen.am" if (!first) { line = (code_string_concat(line, ", ")); } #line 3337 "./src/generator/c_gen.am" line = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(line, Amalgame_Compiler_CGen_IfaceFnPtrCast(self, m))), " ")), name)), "_")), m->Name)); #line 3338 "./src/generator/c_gen.am" first = 0; } #line 3340 "./src/generator/c_gen.am" line = (code_string_concat(line, " };")); #line 3341 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, line); } #line 3343 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); } static code_string Amalgame_Compiler_CGen_TupleStructName(Amalgame_Compiler_CGen* self, code_string tupleType) { #line 3349 "./src/generator/c_gen.am" code_string inner = String_Substring(tupleType, 1LL, String_Length(tupleType) - 2LL); #line 3350 "./src/generator/c_gen.am" code_string parts = String_Replace(inner, " ", ""); #line 3351 "./src/generator/c_gen.am" code_string result = ""; #line 3352 "./src/generator/c_gen.am" i64 count = 0LL; #line 3353 "./src/generator/c_gen.am" i64 i2 = 0LL; #line 3354 "./src/generator/c_gen.am" i64 len2 = String_Length(parts); #line 3355 "./src/generator/c_gen.am" code_string cur = ""; #line 3356 "./src/generator/c_gen.am" while (i2 <= len2) { #line 3357 "./src/generator/c_gen.am" code_string ch = ""; #line 3358 "./src/generator/c_gen.am" if (i2 < len2) { ch = String_Substring(parts, i2, 1LL); } #line 3359 "./src/generator/c_gen.am" if ((code_string_equals(ch, ",")) || (i2 == len2)) { #line 3360 "./src/generator/c_gen.am" if (String_Length(cur) > 0LL) { #line 3361 "./src/generator/c_gen.am" count = (count + 1LL); #line 3362 "./src/generator/c_gen.am" result = (code_string_concat((code_string_concat(result, "_")), Amalgame_Compiler_CGen_TypeToC(self, cur))); #line 3363 "./src/generator/c_gen.am" cur = ""; } } else { #line 3366 "./src/generator/c_gen.am" cur = (code_string_concat(cur, ch)); } #line 3368 "./src/generator/c_gen.am" i2 = (i2 + 1LL); } #line 3370 "./src/generator/c_gen.am" return code_string_concat((code_string_concat("Tuple", String_FromInt(count))), result); } static void Amalgame_Compiler_CGen_EnsureTupleStruct(Amalgame_Compiler_CGen* self, code_string tupleType) { #line 3375 "./src/generator/c_gen.am" code_string sname = Amalgame_Compiler_CGen_TupleStructName(self, tupleType); #line 3377 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->EnumNames); #line 3378 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 3379 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->EnumNames, i), (code_string_concat("__tuple__", sname)))) { return; } } #line 3381 "./src/generator/c_gen.am" AmalgameList_add(self->EnumNames, (void*)(intptr_t)(code_string_concat("__tuple__", sname))); #line 3383 "./src/generator/c_gen.am" code_string inner = String_Substring(tupleType, 1LL, String_Length(tupleType) - 2LL); #line 3384 "./src/generator/c_gen.am" code_string parts = String_Replace(inner, " ", ""); #line 3385 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "typedef struct {"); #line 3386 "./src/generator/c_gen.am" i64 idx = 0LL; #line 3387 "./src/generator/c_gen.am" code_string cur = ""; #line 3388 "./src/generator/c_gen.am" i64 i2 = 0LL; #line 3389 "./src/generator/c_gen.am" i64 len2 = String_Length(parts); #line 3390 "./src/generator/c_gen.am" while (i2 <= len2) { #line 3391 "./src/generator/c_gen.am" code_string ch = ""; #line 3392 "./src/generator/c_gen.am" if (i2 < len2) { ch = String_Substring(parts, i2, 1LL); } #line 3393 "./src/generator/c_gen.am" if ((code_string_equals(ch, ",")) || (i2 == len2)) { #line 3394 "./src/generator/c_gen.am" if (String_Length(cur) > 0LL) { #line 3395 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat(" ", Amalgame_Compiler_CGen_TypeToC(self, cur))), " _")), String_FromInt(idx))), ";")); #line 3396 "./src/generator/c_gen.am" idx = (idx + 1LL); #line 3397 "./src/generator/c_gen.am" cur = ""; } } else { #line 3399 "./src/generator/c_gen.am" cur = (code_string_concat(cur, ch)); } #line 3400 "./src/generator/c_gen.am" i2 = (i2 + 1LL); } #line 3402 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("} ", sname)), ";")); } static code_string Amalgame_Compiler_CGen_MethodSig(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string className) { #line 3406 "./src/generator/c_gen.am" code_string retTypeRaw = method->Str; #line 3407 "./src/generator/c_gen.am" code_string retType = ""; #line 3409 "./src/generator/c_gen.am" if (String_StartsWith(retTypeRaw, "(")) { #line 3410 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EnsureTupleStruct(self, retTypeRaw); #line 3411 "./src/generator/c_gen.am" retType = Amalgame_Compiler_CGen_TupleStructName(self, retTypeRaw); } else { #line 3413 "./src/generator/c_gen.am" retType = Amalgame_Compiler_CGen_TypeToC(self, retTypeRaw); } #line 3415 "./src/generator/c_gen.am" code_bool isStatic = method->Flag2; #line 3416 "./src/generator/c_gen.am" code_string sig = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(retType, " ")), className)), "_")), method->Name)), "("); #line 3417 "./src/generator/c_gen.am" code_bool first = 1; #line 3418 "./src/generator/c_gen.am" if (!isStatic) { #line 3419 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat(sig, className)), "* self")); #line 3420 "./src/generator/c_gen.am" first = 0; } #line 3422 "./src/generator/c_gen.am" i64 pcount = AmalgameList_count(method->Params); #line 3423 "./src/generator/c_gen.am" for (i64 i = 0LL; i < pcount; i++) { #line 3424 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 3425 "./src/generator/c_gen.am" if (!first) { sig = (code_string_concat(sig, ", ")); } #line 3428 "./src/generator/c_gen.am" if (p->Flag) { #line 3429 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat(sig, "AmalgameList* ")), p->Name)); } else { #line 3431 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat((code_string_concat(sig, Amalgame_Compiler_CGen_TypeToC(self, p->Str))), " ")), p->Name)); } #line 3433 "./src/generator/c_gen.am" first = 0; } #line 3435 "./src/generator/c_gen.am" sig = (code_string_concat(sig, ")")); #line 3436 "./src/generator/c_gen.am" return sig; } static code_string Amalgame_Compiler_CGen_AsyncEnvName(Amalgame_Compiler_CGen* self, code_string mangledClass, code_string mname) { #line 3454 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat("AsyncEnv_", mangledClass)), "_")), mname); } static code_string Amalgame_Compiler_CGen_AsyncImplSig(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string className) { #line 3461 "./src/generator/c_gen.am" code_string retTypeRaw = method->Str; #line 3462 "./src/generator/c_gen.am" code_string retType = ""; #line 3463 "./src/generator/c_gen.am" if (String_StartsWith(retTypeRaw, "(")) { #line 3464 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EnsureTupleStruct(self, retTypeRaw); #line 3465 "./src/generator/c_gen.am" retType = Amalgame_Compiler_CGen_TupleStructName(self, retTypeRaw); } else { #line 3467 "./src/generator/c_gen.am" retType = Amalgame_Compiler_CGen_TypeToC(self, retTypeRaw); } #line 3469 "./src/generator/c_gen.am" if (code_string_equals(retType, "void")) { retType = "void"; } #line 3470 "./src/generator/c_gen.am" code_string sig = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(retType, " ")), className)), "_")), method->Name)), "__impl("); #line 3471 "./src/generator/c_gen.am" code_bool first = 1; #line 3472 "./src/generator/c_gen.am" if (!method->Flag2) { #line 3473 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat(sig, className)), "* self")); #line 3474 "./src/generator/c_gen.am" first = 0; } #line 3476 "./src/generator/c_gen.am" i64 pcount = AmalgameList_count(method->Params); #line 3477 "./src/generator/c_gen.am" for (i64 i = 0LL; i < pcount; i++) { #line 3478 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 3479 "./src/generator/c_gen.am" if (!first) { sig = (code_string_concat(sig, ", ")); } #line 3480 "./src/generator/c_gen.am" if (p->Flag) { #line 3481 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat(sig, "AmalgameList* ")), p->Name)); } else { #line 3483 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat((code_string_concat(sig, Amalgame_Compiler_CGen_TypeToC(self, p->Str))), " ")), p->Name)); } #line 3485 "./src/generator/c_gen.am" first = 0; } #line 3487 "./src/generator/c_gen.am" sig = (code_string_concat(sig, ")")); #line 3488 "./src/generator/c_gen.am" return sig; } static code_string Amalgame_Compiler_CGen_AsyncWrapperSig(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string className) { #line 3494 "./src/generator/c_gen.am" code_string sig = code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameAsyncChannel* ", className)), "_")), method->Name)), "("); #line 3495 "./src/generator/c_gen.am" code_bool first = 1; #line 3496 "./src/generator/c_gen.am" if (!method->Flag2) { #line 3497 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat(sig, className)), "* self")); #line 3498 "./src/generator/c_gen.am" first = 0; } #line 3500 "./src/generator/c_gen.am" i64 pcount = AmalgameList_count(method->Params); #line 3501 "./src/generator/c_gen.am" for (i64 i = 0LL; i < pcount; i++) { #line 3502 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 3503 "./src/generator/c_gen.am" if (!first) { sig = (code_string_concat(sig, ", ")); } #line 3504 "./src/generator/c_gen.am" if (p->Flag) { #line 3505 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat(sig, "AmalgameList* ")), p->Name)); } else { #line 3507 "./src/generator/c_gen.am" sig = (code_string_concat((code_string_concat((code_string_concat(sig, Amalgame_Compiler_CGen_TypeToC(self, p->Str))), " ")), p->Name)); } #line 3509 "./src/generator/c_gen.am" first = 0; } #line 3511 "./src/generator/c_gen.am" sig = (code_string_concat(sig, ")")); #line 3512 "./src/generator/c_gen.am" return sig; } static code_string Amalgame_Compiler_CGen_AsyncRetCType(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method) { #line 3518 "./src/generator/c_gen.am" code_string retTypeRaw = method->Str; #line 3519 "./src/generator/c_gen.am" if (String_StartsWith(retTypeRaw, "(")) { #line 3520 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_TupleStructName(self, retTypeRaw); } #line 3522 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_TypeToC(self, retTypeRaw); } static void Amalgame_Compiler_CGen_EmitAsyncForwards(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string mangledClass) { #line 3530 "./src/generator/c_gen.am" code_string mname = method->Name; #line 3531 "./src/generator/c_gen.am" code_string envName = Amalgame_Compiler_CGen_AsyncEnvName(self, mangledClass, mname); #line 3532 "./src/generator/c_gen.am" code_string retC = Amalgame_Compiler_CGen_AsyncRetCType(self, method); #line 3538 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#ifndef AMALGAME_ASYNC_H"); #line 3539 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#error \"async/await requires: import Amalgame.Async (amc package add async)\""); #line 3540 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "#endif"); #line 3542 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("typedef struct ", envName)), " {")); #line 3543 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3544 "./src/generator/c_gen.am" if (!method->Flag2) { #line 3545 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(mangledClass, "* self;")); } #line 3547 "./src/generator/c_gen.am" i64 pcount = AmalgameList_count(method->Params); #line 3548 "./src/generator/c_gen.am" for (i64 i = 0LL; i < pcount; i++) { #line 3549 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 3550 "./src/generator/c_gen.am" if (p->Flag) { #line 3551 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("AmalgameList* ", p->Name)), ";")); } else { #line 3553 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(Amalgame_Compiler_CGen_TypeToC(self, p->Str), " ")), p->Name)), ";")); } } #line 3556 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "AmalgameAsyncChannel* __ch;"); #line 3557 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3558 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("} ", envName)), ";")); #line 3560 "./src/generator/c_gen.am" code_bool isPublic = method->Flag; #line 3561 "./src/generator/c_gen.am" code_string implPrefix = "static "; #line 3562 "./src/generator/c_gen.am" if (isPublic) { implPrefix = ""; } #line 3563 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat(implPrefix, Amalgame_Compiler_CGen_AsyncImplSig(self, method, mangledClass))), ";")); #line 3564 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("static void* ", mangledClass)), "_")), mname)), "__fiber(void* __envRaw, void* __arg);")); #line 3565 "./src/generator/c_gen.am" if (isPublic) { #line 3566 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(Amalgame_Compiler_CGen_AsyncWrapperSig(self, method, mangledClass), ";")); } else { #line 3568 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("static ", Amalgame_Compiler_CGen_AsyncWrapperSig(self, method, mangledClass))), ";")); } #line 3573 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodRetSet(self, mangledClass, mname, "AmalgameAsyncChannel*"); #line 3574 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodRetRawSet(self, mangledClass, mname, "AmalgameAsyncChannel*"); #line 3575 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, "__async_ret__", code_string_concat((code_string_concat(mangledClass, "_")), mname), retC); } static void Amalgame_Compiler_CGen_EmitAsyncMethod(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string mangledClass) { #line 3581 "./src/generator/c_gen.am" code_string mname = method->Name; #line 3582 "./src/generator/c_gen.am" code_string envName = Amalgame_Compiler_CGen_AsyncEnvName(self, mangledClass, mname); #line 3583 "./src/generator/c_gen.am" code_string retC = Amalgame_Compiler_CGen_AsyncRetCType(self, method); #line 3584 "./src/generator/c_gen.am" code_bool isVoid = (code_string_equals(retC, "void")) || (String_Length(retC) == 0LL); #line 3585 "./src/generator/c_gen.am" code_bool isPublic = method->Flag; #line 3586 "./src/generator/c_gen.am" code_string implPrefix = "static "; #line 3587 "./src/generator/c_gen.am" if (isPublic) { implPrefix = ""; } #line 3590 "./src/generator/c_gen.am" if (String_StartsWith(method->Str, "(")) { #line 3591 "./src/generator/c_gen.am" self->CurrentRetType = Amalgame_Compiler_CGen_TupleStructName(self, method->Str); } else { #line 3593 "./src/generator/c_gen.am" self->CurrentRetType = ""; } #line 3595 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat(implPrefix, Amalgame_Compiler_CGen_AsyncImplSig(self, method, mangledClass))), " {")); #line 3596 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3597 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeClear(self); #line 3598 "./src/generator/c_gen.am" if (!method->Flag2) { #line 3599 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, "self", code_string_concat(mangledClass, "*")); } #line 3601 "./src/generator/c_gen.am" i64 pcount = AmalgameList_count(method->Params); #line 3602 "./src/generator/c_gen.am" for (i64 i = 0LL; i < pcount; i++) { #line 3603 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 3604 "./src/generator/c_gen.am" if (p->Flag) { #line 3605 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, p->Name, "AmalgameList*"); #line 3606 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_TrackGenericLocal(self, p->Name, code_string_concat((code_string_concat("List<", p->Str)), ">")); } else { #line 3608 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, p->Name, Amalgame_Compiler_CGen_TypeToC(self, p->Str)); #line 3609 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_TrackGenericLocal(self, p->Name, p->Str); } } #line 3612 "./src/generator/c_gen.am" if (method->Body != NULL) { #line 3613 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitBlock(self, method->Body); } #line 3615 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeClear(self); #line 3616 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3617 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 3618 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); #line 3621 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("static void* ", mangledClass)), "_")), mname)), "__fiber(void* __envRaw, void* __arg) {")); #line 3622 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3623 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "(void)__arg;"); #line 3624 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(envName, "* __e = (")), envName)), "*)__envRaw;")); #line 3625 "./src/generator/c_gen.am" code_string callArgs = ""; #line 3626 "./src/generator/c_gen.am" code_bool firstA = 1; #line 3627 "./src/generator/c_gen.am" if (!method->Flag2) { #line 3628 "./src/generator/c_gen.am" callArgs = "__e->self"; #line 3629 "./src/generator/c_gen.am" firstA = 0; } #line 3631 "./src/generator/c_gen.am" for (i64 i = 0LL; i < pcount; i++) { #line 3632 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 3633 "./src/generator/c_gen.am" if (!firstA) { callArgs = (code_string_concat(callArgs, ", ")); } #line 3634 "./src/generator/c_gen.am" callArgs = (code_string_concat((code_string_concat(callArgs, "__e->")), p->Name)); #line 3635 "./src/generator/c_gen.am" firstA = 0; } #line 3637 "./src/generator/c_gen.am" code_string implCall = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(mangledClass, "_")), mname)), "__impl(")), callArgs)), ")"); #line 3638 "./src/generator/c_gen.am" if (isVoid) { #line 3639 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(implCall, ";")); #line 3640 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "Amalgame_Async_ChannelSend(__e->__ch, 0);"); } else { #line 3642 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(retC, " __r = ")), implCall)), ";")); #line 3643 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("Amalgame_Async_ChannelSend(__e->__ch, ", Amalgame_Compiler_CGen_BoxAsVoidI64(self, "__r"))), ");")); } #line 3645 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "return (void*)0;"); #line 3646 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3647 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 3648 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); #line 3651 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat(implPrefix, Amalgame_Compiler_CGen_AsyncWrapperSig(self, method, mangledClass))), " {")); #line 3652 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3653 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "AmalgameAsyncChannel* __ch = Amalgame_Async_ChannelNew(1);"); #line 3654 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(envName, "* __e = (")), envName)), "*)code_alloc(sizeof(")), envName)), "));")); #line 3655 "./src/generator/c_gen.am" if (!method->Flag2) { #line 3656 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "__e->self = self;"); } #line 3658 "./src/generator/c_gen.am" for (i64 i = 0LL; i < pcount; i++) { #line 3659 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 3660 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("__e->", p->Name)), " = ")), p->Name)), ";")); } #line 3662 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "__e->__ch = __ch;"); #line 3663 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("Amalgame_Async_FiberSpawn(AmalgameClosure_new((void*)", mangledClass)), "_")), mname)), "__fiber, __e), 0);")); #line 3664 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "return __ch;"); #line 3665 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3666 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 3667 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); } static code_string Amalgame_Compiler_CGen_BoxAsVoidI64(Amalgame_Compiler_CGen* self, code_string expr) { #line 3673 "./src/generator/c_gen.am" return code_string_concat((code_string_concat("(i64)(intptr_t)(", expr)), ")"); } static code_string Amalgame_Compiler_CGen_ResolveAwaitRetC(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* operand) { #line 3683 "./src/generator/c_gen.am" if (operand == NULL) { return ""; } #line 3684 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind k = operand->Kind; #line 3685 "./src/generator/c_gen.am" if (k == Amalgame_Compiler_NodeKind_CALL) { #line 3686 "./src/generator/c_gen.am" code_string cs = Amalgame_Compiler_CGen_EmitCalleeStr(self, operand->Left); #line 3687 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_ListElemGet(self, "__async_ret__", cs); } #line 3689 "./src/generator/c_gen.am" if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 3690 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_ListElemGet(self, "__async_future__", operand->Name); } #line 3692 "./src/generator/c_gen.am" return ""; } static void Amalgame_Compiler_CGen_EmitMethod(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* method, code_string className) { #line 3696 "./src/generator/c_gen.am" code_string sig = Amalgame_Compiler_CGen_MethodSig(self, method, className); #line 3697 "./src/generator/c_gen.am" code_bool isPublic = method->Flag; #line 3698 "./src/generator/c_gen.am" code_string prefix = ""; #line 3699 "./src/generator/c_gen.am" if (!isPublic) { prefix = "static "; } #line 3701 "./src/generator/c_gen.am" code_string decos = method->Str2; #line 3702 "./src/generator/c_gen.am" if (String_Length(decos) > 0LL) { #line 3703 "./src/generator/c_gen.am" if (String_Contains(code_string_concat((code_string_concat(",", decos)), ","), ",inline,")) { #line 3704 "./src/generator/c_gen.am" prefix = (code_string_concat(prefix, "inline ")); } } #line 3708 "./src/generator/c_gen.am" if (String_StartsWith(method->Str, "(")) { #line 3709 "./src/generator/c_gen.am" self->CurrentRetType = Amalgame_Compiler_CGen_TupleStructName(self, method->Str); #line 3711 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodRetSet(self, className, method->Name, method->Str); #line 3712 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_MethodRetRawSet(self, className, method->Name, method->Str); } else { #line 3714 "./src/generator/c_gen.am" self->CurrentRetType = ""; } #line 3716 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat(prefix, sig)), " {")); #line 3717 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3719 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeClear(self); #line 3721 "./src/generator/c_gen.am" code_bool isStatic = method->Flag2; #line 3722 "./src/generator/c_gen.am" if (!isStatic) { #line 3723 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, "self", code_string_concat(className, "*")); } #line 3733 "./src/generator/c_gen.am" i64 pcount = AmalgameList_count(method->Params); #line 3734 "./src/generator/c_gen.am" for (i64 i = 0LL; i < pcount; i++) { #line 3735 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 3739 "./src/generator/c_gen.am" if (p->Flag) { #line 3740 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, p->Name, "AmalgameList*"); #line 3741 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_TrackGenericLocal(self, p->Name, code_string_concat((code_string_concat("List<", p->Str)), ">")); } else { #line 3743 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, p->Name, Amalgame_Compiler_CGen_TypeToC(self, p->Str)); #line 3744 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_TrackGenericLocal(self, p->Name, p->Str); } } #line 3747 "./src/generator/c_gen.am" if (method->Body != NULL) { #line 3748 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitBlock(self, method->Body); } #line 3750 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeClear(self); #line 3751 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3752 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 3753 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitBlank(self->Out); } static code_string Amalgame_Compiler_CGen_EmitIfBranch(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* block) { #line 3761 "./src/generator/c_gen.am" if (block == NULL) { return "0"; } #line 3762 "./src/generator/c_gen.am" if (block->Kind == Amalgame_Compiler_NodeKind_BLOCK) { #line 3763 "./src/generator/c_gen.am" AmalgameList* kids = block->Children; #line 3764 "./src/generator/c_gen.am" if (AmalgameList_count(kids) > 0LL) { #line 3765 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(kids, 0LL)); } #line 3767 "./src/generator/c_gen.am" return "0"; } #line 3769 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_EmitExprStr(self, block); } static void Amalgame_Compiler_CGen_EmitMatch(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt) { #line 3773 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* subject = stmt->Left; #line 3774 "./src/generator/c_gen.am" code_string subjectStr = Amalgame_Compiler_CGen_EmitExprStr(self, subject); #line 3776 "./src/generator/c_gen.am" code_string subjectType = ""; #line 3777 "./src/generator/c_gen.am" if ((subject != NULL) && (subject->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 3778 "./src/generator/c_gen.am" subjectType = Amalgame_Compiler_CGen_LocalTypeGet(self, subject->Name); } #line 3781 "./src/generator/c_gen.am" code_bool isAlg = 0; #line 3782 "./src/generator/c_gen.am" if (String_Length(subjectType) > 0LL) { #line 3783 "./src/generator/c_gen.am" code_string algKey2 = code_string_concat("__alg__", subjectType); #line 3784 "./src/generator/c_gen.am" i64 enCount3 = AmalgameList_count(self->EnumNames); #line 3785 "./src/generator/c_gen.am" for (i64 eni3 = 0LL; eni3 < enCount3; eni3++) { #line 3786 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->EnumNames, eni3), algKey2)) { isAlg = 1; } } } #line 3789 "./src/generator/c_gen.am" i64 armCount = AmalgameList_count(stmt->Children); #line 3790 "./src/generator/c_gen.am" if (isAlg) { #line 3792 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("switch (", subjectStr)), ".tag) {")); } else { #line 3795 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("{ /* match ", subjectStr)), " */")); } #line 3797 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3798 "./src/generator/c_gen.am" code_bool firstArm = 1; #line 3799 "./src/generator/c_gen.am" code_bool needsClose = 0; #line 3800 "./src/generator/c_gen.am" for (i64 i = 0LL; i < armCount; i++) { #line 3801 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* arm = (Amalgame_Compiler_AstNode*)AmalgameList_get(stmt->Children, i); #line 3802 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* pat = arm->Left; #line 3803 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* body = arm->Right; #line 3804 "./src/generator/c_gen.am" if (pat == NULL) { continue; } #line 3805 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind pk = pat->Kind; #line 3807 "./src/generator/c_gen.am" if ((pk == Amalgame_Compiler_NodeKind_IDENTIFIER) && (code_string_equals(pat->Name, "_"))) { #line 3808 "./src/generator/c_gen.am" if (isAlg) { #line 3809 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "default: {"); #line 3810 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3811 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitMatchBody(self, body); #line 3812 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "break;"); #line 3813 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3814 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 3815 "./src/generator/c_gen.am" needsClose = 0; } else { #line 3818 "./src/generator/c_gen.am" code_string elsePrefix = (firstArm ? "" : "} else "); #line 3819 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(elsePrefix, "{")); #line 3820 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3821 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitMatchBody(self, body); #line 3822 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3823 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 3824 "./src/generator/c_gen.am" needsClose = 0; } #line 3826 "./src/generator/c_gen.am" firstArm = 0; } else { #line 3828 "./src/generator/c_gen.am" if (isAlg && (pk == Amalgame_Compiler_NodeKind_CALL)) { #line 3830 "./src/generator/c_gen.am" code_string variantName = pat->Name; #line 3831 "./src/generator/c_gen.am" code_string tagConst = code_string_concat((code_string_concat(subjectType, "_TAG_")), variantName); #line 3832 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("case ", tagConst)), ": {")); #line 3833 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3835 "./src/generator/c_gen.am" i64 capCount = AmalgameList_count(pat->Args); #line 3836 "./src/generator/c_gen.am" for (i64 ci = 0LL; ci < capCount; ci++) { #line 3837 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* capNode = (Amalgame_Compiler_AstNode*)AmalgameList_get(pat->Args, ci); #line 3838 "./src/generator/c_gen.am" code_string capName = capNode->Name; #line 3839 "./src/generator/c_gen.am" code_string fidx = String_FromInt(ci); #line 3840 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("__auto_type ", capName)), " = ")), subjectStr)), ".")), variantName)), "._")), fidx)), ";")); #line 3841 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, capName, "i64"); } #line 3843 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitMatchBody(self, body); #line 3844 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "break;"); #line 3845 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3846 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 3847 "./src/generator/c_gen.am" needsClose = 0; } else { #line 3851 "./src/generator/c_gen.am" code_string elsePrefix = (firstArm ? "" : "} else "); #line 3852 "./src/generator/c_gen.am" code_bool isBinder = (pk == Amalgame_Compiler_NodeKind_IDENTIFIER) && (!code_string_equals(pat->Name, "_")); #line 3853 "./src/generator/c_gen.am" code_string cond = ""; #line 3854 "./src/generator/c_gen.am" if ((pk == Amalgame_Compiler_NodeKind_BINARY) && (code_string_equals(pat->Str, ".."))) { #line 3855 "./src/generator/c_gen.am" code_string lo = Amalgame_Compiler_CGen_EmitExprStr(self, pat->Left); #line 3856 "./src/generator/c_gen.am" code_string hi = Amalgame_Compiler_CGen_EmitExprStr(self, pat->Right); #line 3857 "./src/generator/c_gen.am" cond = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(subjectStr, " >= ")), lo)), " && ")), subjectStr)), " <= ")), hi)); } else if (pk == Amalgame_Compiler_NodeKind_LITERAL_STRING) { #line 3859 "./src/generator/c_gen.am" code_string patStr = Amalgame_Compiler_CGen_EmitExprStr(self, pat); #line 3860 "./src/generator/c_gen.am" cond = (code_string_concat((code_string_concat((code_string_concat((code_string_concat("strcmp(", subjectStr)), ", ")), patStr)), ") == 0")); } else if (isBinder) { #line 3864 "./src/generator/c_gen.am" cond = "1"; } else { #line 3866 "./src/generator/c_gen.am" code_string patStr = Amalgame_Compiler_CGen_EmitExprStr(self, pat); #line 3867 "./src/generator/c_gen.am" cond = (code_string_concat((code_string_concat(subjectStr, " == ")), patStr)); } #line 3869 "./src/generator/c_gen.am" if (arm->Cond != NULL) { #line 3872 "./src/generator/c_gen.am" if (isBinder) { #line 3873 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, pat->Name, "i64"); } #line 3875 "./src/generator/c_gen.am" code_string guardStr = Amalgame_Compiler_CGen_EmitExprStr(self, arm->Cond); #line 3876 "./src/generator/c_gen.am" if (isBinder) { #line 3880 "./src/generator/c_gen.am" cond = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("(({ __auto_type ", pat->Name)), " = ")), subjectStr)), "; ")), guardStr)), "; }))")); } else { #line 3882 "./src/generator/c_gen.am" cond = (code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", cond)), ") && (")), guardStr)), ")")); } } #line 3885 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat(elsePrefix, "if (")), cond)), ") {")); #line 3886 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3889 "./src/generator/c_gen.am" if (isBinder) { #line 3890 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("__auto_type ", pat->Name)), " = ")), subjectStr)), ";")); #line 3891 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, pat->Name, "i64"); } #line 3893 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitMatchBody(self, body); #line 3894 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3895 "./src/generator/c_gen.am" needsClose = 1; } #line 3897 "./src/generator/c_gen.am" firstArm = 0; } } #line 3901 "./src/generator/c_gen.am" if (needsClose) { #line 3902 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); } #line 3904 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3905 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); } static void Amalgame_Compiler_CGen_EmitMatchBody(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* body) { #line 3909 "./src/generator/c_gen.am" if (body == NULL) { return; } #line 3910 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind bk = body->Kind; #line 3911 "./src/generator/c_gen.am" if (bk == Amalgame_Compiler_NodeKind_BLOCK) { #line 3912 "./src/generator/c_gen.am" i64 stmts = AmalgameList_count(body->Children); #line 3913 "./src/generator/c_gen.am" for (i64 si = 0LL; si < stmts; si++) { #line 3914 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitStmt(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(body->Children, si)); } } else if (((bk == Amalgame_Compiler_NodeKind_RETURN_STMT) || (bk == Amalgame_Compiler_NodeKind_BREAK_STMT)) || (bk == Amalgame_Compiler_NodeKind_CONTINUE_STMT)) { #line 3919 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitStmt(self, body); } else { #line 3922 "./src/generator/c_gen.am" code_string exprStr = Amalgame_Compiler_CGen_EmitExprStr(self, body); #line 3923 "./src/generator/c_gen.am" if ((String_Length(exprStr) > 0LL) && (!code_string_equals(exprStr, "_unknown_"))) { #line 3924 "./src/generator/c_gen.am" if ((bk == Amalgame_Compiler_NodeKind_CALL) || (bk == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 3926 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(exprStr, ";")); } else { #line 3928 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("return ", exprStr)), ";")); } } } } static void Amalgame_Compiler_CGen_EmitIf(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt) { #line 3935 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("if (", Amalgame_Compiler_CGen_EmitExprStr(self, stmt->Cond))), ") {")); #line 3936 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3937 "./src/generator/c_gen.am" if (stmt->Body != NULL) { Amalgame_Compiler_CGen_EmitBlock(self, stmt->Body); } #line 3938 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3939 "./src/generator/c_gen.am" if (stmt->Else != NULL) { #line 3940 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind elseKind = stmt->Else->Kind; #line 3941 "./src/generator/c_gen.am" if (elseKind == Amalgame_Compiler_NodeKind_IF_STMT) { #line 3943 "./src/generator/c_gen.am" code_string innerCond = Amalgame_Compiler_CGen_EmitExprStr(self, stmt->Else->Cond); #line 3944 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("} else if (", innerCond)), ") {")); #line 3945 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3946 "./src/generator/c_gen.am" if (stmt->Else->Body != NULL) { Amalgame_Compiler_CGen_EmitBlock(self, stmt->Else->Body); } #line 3947 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3949 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitIfTail(self, stmt->Else); } else { #line 3951 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "} else {"); #line 3952 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3953 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitBlock(self, stmt->Else); #line 3954 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3955 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); } } else { #line 3958 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); } } static void Amalgame_Compiler_CGen_EmitIfTail(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt) { #line 3964 "./src/generator/c_gen.am" if (stmt->Else == NULL) { #line 3965 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 3966 "./src/generator/c_gen.am" return; } #line 3968 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind elseKind = stmt->Else->Kind; #line 3969 "./src/generator/c_gen.am" if (elseKind == Amalgame_Compiler_NodeKind_IF_STMT) { #line 3970 "./src/generator/c_gen.am" code_string innerCond = Amalgame_Compiler_CGen_EmitExprStr(self, stmt->Else->Cond); #line 3971 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("} else if (", innerCond)), ") {")); #line 3972 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3973 "./src/generator/c_gen.am" if (stmt->Else->Body != NULL) { Amalgame_Compiler_CGen_EmitBlock(self, stmt->Else->Body); } #line 3974 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3975 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitIfTail(self, stmt->Else); } else { #line 3977 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "} else {"); #line 3978 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 3979 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitBlock(self, stmt->Else); #line 3980 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 3981 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); } } static void Amalgame_Compiler_CGen_EmitBlock(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* block) { #line 3986 "./src/generator/c_gen.am" i64 count = AmalgameList_count(block->Children); #line 3987 "./src/generator/c_gen.am" for (i64 i = 0LL; i < count; i++) { #line 3988 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* stmt = (Amalgame_Compiler_AstNode*)AmalgameList_get(block->Children, i); #line 3989 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitStmt(self, stmt); } } static void Amalgame_Compiler_CGen_EmitLineDirective(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt) { #line 4000 "./src/generator/c_gen.am" if (stmt->Line <= 0LL) { return; } #line 4001 "./src/generator/c_gen.am" if (String_Length(self->CurrentSource) == 0LL) { return; } #line 4002 "./src/generator/c_gen.am" if (stmt->Line == self->LastLineEmitted) { return; } #line 4007 "./src/generator/c_gen.am" code_string escaped = String_Replace(self->CurrentSource, "\\", "\\\\"); #line 4008 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("#line ", String_FromInt(stmt->Line))), " \"")), escaped)), "\"")); #line 4009 "./src/generator/c_gen.am" self->LastLineEmitted = stmt->Line; } static void Amalgame_Compiler_CGen_EmitStmt(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* stmt) { #line 4013 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitLineDirective(self, stmt); #line 4014 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind k = stmt->Kind; #line 4015 "./src/generator/c_gen.am" { /* match k */ if (k == Amalgame_Compiler_NodeKind_BLOCK) { #line 4023 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "{"); #line 4024 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 4025 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitBlock(self, stmt); #line 4026 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 4027 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 4028 "./src/generator/c_gen.am" return; } else if (k == Amalgame_Compiler_NodeKind_TRY_STMT) { #line 4044 "./src/generator/c_gen.am" code_string suffix = String_FromInt(stmt->Line); #line 4045 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "{"); #line 4046 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 4047 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("jmp_buf _am_prev_env_", suffix)), ";")); #line 4048 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("memcpy(&_am_prev_env_", suffix)), ", &_am_ex.env, sizeof(jmp_buf));")); #line 4049 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("int _am_caught_", suffix)), " = setjmp(_am_ex.env);")); #line 4050 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("if (_am_caught_", suffix)), " == 0) {")); #line 4051 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 4052 "./src/generator/c_gen.am" if (stmt->Body != NULL) { Amalgame_Compiler_CGen_EmitBlock(self, stmt->Body); } #line 4053 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "_am_ex.active = 0;"); #line 4054 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 4055 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "} else {"); #line 4056 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 4057 "./src/generator/c_gen.am" if (String_Length(stmt->Name) > 0LL) { #line 4058 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("void* ", stmt->Name)), " = _am_ex.value;")); #line 4059 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, stmt->Name, "void*"); } #line 4061 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "_am_ex.active = 0;"); #line 4062 "./src/generator/c_gen.am" if (stmt->Else != NULL) { Amalgame_Compiler_CGen_EmitBlock(self, stmt->Else); } #line 4063 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 4064 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 4065 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("memcpy(&_am_ex.env, &_am_prev_env_", suffix)), ", sizeof(jmp_buf));")); #line 4066 "./src/generator/c_gen.am" if (stmt->Cond != NULL) { Amalgame_Compiler_CGen_EmitBlock(self, stmt->Cond); } #line 4067 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 4068 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 4069 "./src/generator/c_gen.am" return; } else if (k == Amalgame_Compiler_NodeKind_INLINE_C) { #line 4076 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "{ /* inline-C */"); #line 4077 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 4078 "./src/generator/c_gen.am" code_string body = stmt->Str; #line 4079 "./src/generator/c_gen.am" if (String_Length(body) > 0LL) { #line 4080 "./src/generator/c_gen.am" AmalgameList* lines = String_Split(body, "\n"); #line 4081 "./src/generator/c_gen.am" i64 count = AmalgameList_count(lines); #line 4082 "./src/generator/c_gen.am" for (i64 i = 0LL; i < count; i++) { #line 4083 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, (code_string)AmalgameList_get(lines, i)); } } #line 4086 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 4087 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 4088 "./src/generator/c_gen.am" return; } else if (k == Amalgame_Compiler_NodeKind_THROW_STMT) { #line 4094 "./src/generator/c_gen.am" if (stmt->Left == NULL) { #line 4095 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "_am_throw(NULL, \"Error\", \"\");"); #line 4096 "./src/generator/c_gen.am" return; } #line 4098 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* v = stmt->Left; #line 4099 "./src/generator/c_gen.am" if (v->Kind == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 4100 "./src/generator/c_gen.am" code_string typeName = v->Name; #line 4101 "./src/generator/c_gen.am" code_string argsStr = ""; #line 4102 "./src/generator/c_gen.am" i64 ac = AmalgameList_count(v->Args); #line 4103 "./src/generator/c_gen.am" for (i64 ai = 0LL; ai < ac; ai++) { #line 4104 "./src/generator/c_gen.am" if (ai > 0LL) { argsStr = (code_string_concat(argsStr, ", ")); } #line 4105 "./src/generator/c_gen.am" argsStr = (code_string_concat(argsStr, Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(v->Args, ai)))); } #line 4107 "./src/generator/c_gen.am" code_string msgStr = "\"\""; #line 4108 "./src/generator/c_gen.am" if (ac > 0LL) { #line 4109 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* firstArg = (Amalgame_Compiler_AstNode*)AmalgameList_get(v->Args, 0LL); #line 4110 "./src/generator/c_gen.am" if (firstArg->Kind == Amalgame_Compiler_NodeKind_LITERAL_STRING) { #line 4111 "./src/generator/c_gen.am" msgStr = Amalgame_Compiler_CGen_EmitExprStr(self, firstArg); } } #line 4114 "./src/generator/c_gen.am" code_string symName = Amalgame_Compiler_CGen_SymName(self, typeName); #line 4115 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("_am_throw((void*)(", symName)), "_new(")), argsStr)), ")), \"")), typeName)), "\", ")), msgStr)), ");")); #line 4116 "./src/generator/c_gen.am" return; } #line 4118 "./src/generator/c_gen.am" code_string valStr = Amalgame_Compiler_CGen_EmitExprStr(self, v); #line 4119 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("_am_throw((void*)", valStr)), ", \"Error\", \"\");")); #line 4120 "./src/generator/c_gen.am" return; } else if (k == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 4124 "./src/generator/c_gen.am" if (code_string_equals(stmt->Str, "__tuple_destructure__")) { #line 4125 "./src/generator/c_gen.am" code_string rhs = Amalgame_Compiler_CGen_EmitExprStr(self, stmt->Left); #line 4126 "./src/generator/c_gen.am" code_string tmpName = code_string_concat("__tup_", String_FromInt(stmt->Line)); #line 4127 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("__auto_type ", tmpName)), " = ")), rhs)), ";")); #line 4129 "./src/generator/c_gen.am" code_string tupleRetType = ""; #line 4130 "./src/generator/c_gen.am" if ((stmt->Left != NULL) && (stmt->Left->Kind == Amalgame_Compiler_NodeKind_CALL)) { #line 4131 "./src/generator/c_gen.am" code_string calleeStr2 = Amalgame_Compiler_CGen_EmitCalleeStr(self, stmt->Left->Left); #line 4133 "./src/generator/c_gen.am" i64 lastUs = String_LastIndexOf(calleeStr2, "_"); #line 4134 "./src/generator/c_gen.am" if (lastUs > 0LL) { #line 4135 "./src/generator/c_gen.am" code_string cls2 = String_Substring(calleeStr2, 0LL, lastUs); #line 4136 "./src/generator/c_gen.am" code_string mth2 = String_Substring(calleeStr2, lastUs + 1LL, (String_Length(calleeStr2) - lastUs) - 1LL); #line 4137 "./src/generator/c_gen.am" tupleRetType = Amalgame_Compiler_CGen_MethodRetGet(self, cls2, mth2); } } #line 4140 "./src/generator/c_gen.am" i64 nc = AmalgameList_count(stmt->Children); #line 4141 "./src/generator/c_gen.am" for (i64 i = 0LL; i < nc; i++) { #line 4142 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* vnode = (Amalgame_Compiler_AstNode*)AmalgameList_get(stmt->Children, i); #line 4143 "./src/generator/c_gen.am" code_string vname = vnode->Name; #line 4144 "./src/generator/c_gen.am" code_string idxStr = String_FromInt(i); #line 4145 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("__auto_type ", vname)), " = ")), tmpName)), "._")), idxStr)), ";")); #line 4147 "./src/generator/c_gen.am" code_string elemType = "void*"; #line 4148 "./src/generator/c_gen.am" if ((String_Length(tupleRetType) > 2LL) && String_StartsWith(tupleRetType, "(")) { #line 4149 "./src/generator/c_gen.am" code_string inner2 = String_Substring(tupleRetType, 1LL, String_Length(tupleRetType) - 2LL); #line 4151 "./src/generator/c_gen.am" i64 ei = 0LL; #line 4152 "./src/generator/c_gen.am" code_string cur2 = ""; #line 4153 "./src/generator/c_gen.am" i64 ci2 = 0LL; #line 4154 "./src/generator/c_gen.am" i64 ilen = String_Length(inner2); #line 4155 "./src/generator/c_gen.am" while (ci2 <= ilen) { #line 4156 "./src/generator/c_gen.am" code_string ch2 = ""; #line 4157 "./src/generator/c_gen.am" if (ci2 < ilen) { ch2 = String_Substring(inner2, ci2, 1LL); } #line 4158 "./src/generator/c_gen.am" if ((code_string_equals(ch2, ",")) || (ci2 == ilen)) { #line 4159 "./src/generator/c_gen.am" if ((ei == i) && (String_Length(cur2) > 0LL)) { #line 4160 "./src/generator/c_gen.am" elemType = Amalgame_Compiler_CGen_TypeToC(self, cur2); } #line 4162 "./src/generator/c_gen.am" ei = (ei + 1LL); #line 4163 "./src/generator/c_gen.am" cur2 = ""; } else { #line 4164 "./src/generator/c_gen.am" cur2 = (code_string_concat(cur2, ch2)); } #line 4165 "./src/generator/c_gen.am" ci2 = (ci2 + 1LL); } } #line 4168 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, vname, elemType); } #line 4170 "./src/generator/c_gen.am" return; } #line 4177 "./src/generator/c_gen.am" if (((stmt->Left != NULL) && (stmt->Left->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL)) && (code_string_equals(stmt->Left->Name, "__lambda__"))) { #line 4178 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* lam = stmt->Left; #line 4179 "./src/generator/c_gen.am" code_string id = lam->Str2; #line 4180 "./src/generator/c_gen.am" code_string envName = code_string_concat("LamEnv_", id); #line 4181 "./src/generator/c_gen.am" code_string fnName = code_string_concat((code_string_concat("lam_", id)), "_fn"); #line 4182 "./src/generator/c_gen.am" code_string envVar = code_string_concat("__env_", id); #line 4193 "./src/generator/c_gen.am" code_string typedRet = ""; #line 4194 "./src/generator/c_gen.am" if (String_StartsWith(stmt->Str, "Closure<") && String_EndsWith(stmt->Str, ">")) { #line 4195 "./src/generator/c_gen.am" code_string inner = String_Substring(stmt->Str, 8LL, String_Length(stmt->Str) - 9LL); #line 4196 "./src/generator/c_gen.am" AmalgameList* parts = Amalgame_Compiler_CGen_SplitTopLevelCommas(self, inner); #line 4197 "./src/generator/c_gen.am" i64 pc = AmalgameList_count(parts); #line 4198 "./src/generator/c_gen.am" i64 pn = AmalgameList_count(lam->Params); #line 4199 "./src/generator/c_gen.am" if (pc >= 1LL) { #line 4201 "./src/generator/c_gen.am" typedRet = String_Trim((code_string)AmalgameList_get(parts, pc - 1LL)); #line 4206 "./src/generator/c_gen.am" i64 argCount = pc - 1LL; #line 4207 "./src/generator/c_gen.am" i64 toPatch = argCount; #line 4208 "./src/generator/c_gen.am" if (toPatch > pn) { toPatch = pn; } #line 4209 "./src/generator/c_gen.am" for (i64 ai = 0LL; ai < toPatch; ai++) { #line 4210 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(lam->Params, ai); #line 4211 "./src/generator/c_gen.am" if ((String_Length(p->Str) == 0LL) || (code_string_equals(p->Str, "?"))) { #line 4212 "./src/generator/c_gen.am" p->Str = String_Trim((code_string)AmalgameList_get(parts, ai)); } } } } #line 4217 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(envName, "* ")), envVar)), " = (")), envName)), "*) code_alloc(sizeof(")), envName)), "));")); #line 4218 "./src/generator/c_gen.am" i64 cn = AmalgameList_count(lam->Args); #line 4219 "./src/generator/c_gen.am" for (i64 i = 0LL; i < cn; i++) { #line 4220 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* cap = (Amalgame_Compiler_AstNode*)AmalgameList_get(lam->Args, i); #line 4221 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(envVar, "->_")), cap->Name)), " = ")), cap->Name)), ";")); } #line 4223 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameClosure* ", stmt->Name)), " = AmalgameClosure_new((void*)")), fnName)), ", ")), envVar)), ");")); #line 4224 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, stmt->Name, "AmalgameClosure*"); #line 4231 "./src/generator/c_gen.am" if (String_Length(typedRet) > 0LL) { #line 4232 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, "__closure_ret__", stmt->Name, Amalgame_Compiler_CGen_TypeToC(self, typedRet)); } else if (lam->Left != NULL) { #line 4234 "./src/generator/c_gen.am" code_string retC = Amalgame_Compiler_CGen_InferTypeFromExpr(self, lam->Left); #line 4235 "./src/generator/c_gen.am" if (String_Length(retC) > 0LL) { #line 4236 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, "__closure_ret__", stmt->Name, retC); } } #line 4239 "./src/generator/c_gen.am" return; } #line 4241 "./src/generator/c_gen.am" code_string t = Amalgame_Compiler_CGen_TypeToC(self, stmt->Str); #line 4243 "./src/generator/c_gen.am" if ((String_Length(t) == 0LL) || (code_string_equals(t, "void"))) { #line 4244 "./src/generator/c_gen.am" t = Amalgame_Compiler_CGen_InferTypeFromExpr(self, stmt->Left); } #line 4247 "./src/generator/c_gen.am" if (String_Length(t) == 0LL) { t = "void*"; } #line 4249 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, stmt->Name, t); #line 4257 "./src/generator/c_gen.am" if (String_Length(stmt->Str) > 0LL) { #line 4258 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_TrackGenericLocal(self, stmt->Name, stmt->Str); } #line 4260 "./src/generator/c_gen.am" if ((stmt->Left != NULL) && (stmt->Left->Kind == Amalgame_Compiler_NodeKind_NEW_EXPR)) { #line 4261 "./src/generator/c_gen.am" if (String_Length(stmt->Left->Str2) > 0LL) { #line 4262 "./src/generator/c_gen.am" code_string synth = code_string_concat((code_string_concat((code_string_concat(stmt->Left->Name, "<")), stmt->Left->Str2)), ">"); #line 4263 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_TrackGenericLocal(self, stmt->Name, synth); } } #line 4271 "./src/generator/c_gen.am" if ((stmt->Left != NULL) && (stmt->Left->Kind == Amalgame_Compiler_NodeKind_CALL)) { #line 4272 "./src/generator/c_gen.am" code_string af_cs = Amalgame_Compiler_CGen_EmitCalleeStr(self, stmt->Left->Left); #line 4273 "./src/generator/c_gen.am" code_string af_ret = Amalgame_Compiler_CGen_ListElemGet(self, "__async_ret__", af_cs); #line 4274 "./src/generator/c_gen.am" if (String_Length(af_ret) > 0LL) { #line 4275 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, "__async_future__", stmt->Name, af_ret); } } #line 4278 "./src/generator/c_gen.am" if ((stmt->Left != NULL) && (stmt->Left->Kind == Amalgame_Compiler_NodeKind_CALL)) { #line 4291 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* callee = stmt->Left->Left; #line 4292 "./src/generator/c_gen.am" if ((callee != NULL) && (callee->Kind == Amalgame_Compiler_NodeKind_MEMBER)) { #line 4293 "./src/generator/c_gen.am" if ((callee->Left != NULL) && (callee->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 4294 "./src/generator/c_gen.am" code_string recvName = callee->Left->Name; #line 4295 "./src/generator/c_gen.am" code_string retRaw = Amalgame_Compiler_CGen_MethodRetRawGet(self, recvName, callee->Name); #line 4296 "./src/generator/c_gen.am" if (String_Length(retRaw) == 0LL) { #line 4297 "./src/generator/c_gen.am" code_string extMangled = Amalgame_Compiler_CGen_ExternalClassMangled(self, recvName); #line 4298 "./src/generator/c_gen.am" if (String_Length(extMangled) > 0LL) { #line 4299 "./src/generator/c_gen.am" retRaw = Amalgame_Compiler_CGen_MethodRetRawGet(self, extMangled, callee->Name); } } #line 4302 "./src/generator/c_gen.am" if (String_Length(retRaw) == 0LL) { #line 4303 "./src/generator/c_gen.am" code_string recvType = Amalgame_Compiler_CGen_LocalTypeGet(self, recvName); #line 4304 "./src/generator/c_gen.am" if (String_Length(recvType) > 0LL) { #line 4305 "./src/generator/c_gen.am" code_string bareT = String_Replace(recvType, "*", ""); #line 4306 "./src/generator/c_gen.am" if (String_Length(bareT) > 0LL) { #line 4307 "./src/generator/c_gen.am" retRaw = Amalgame_Compiler_CGen_MethodRetRawGet(self, bareT, callee->Name); } } } #line 4319 "./src/generator/c_gen.am" if ((String_Length(retRaw) == 0LL) && (code_string_equals(callee->Name, "Get"))) { #line 4320 "./src/generator/c_gen.am" retRaw = Amalgame_Compiler_CGen_RecoverChainedListElemRaw(self, callee->Left); } #line 4322 "./src/generator/c_gen.am" if (String_Length(retRaw) > 0LL) { #line 4323 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_TrackGenericLocal(self, stmt->Name, retRaw); } } #line 4334 "./src/generator/c_gen.am" code_string mname = callee->Name; #line 4335 "./src/generator/c_gen.am" if (code_string_equals(mname, "Filter")) { #line 4336 "./src/generator/c_gen.am" if ((callee->Left != NULL) && (callee->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 4337 "./src/generator/c_gen.am" code_string recvName = callee->Left->Name; #line 4338 "./src/generator/c_gen.am" code_string recvElem = Amalgame_Compiler_CGen_ListElemGet(self, "__local__", recvName); #line 4339 "./src/generator/c_gen.am" if (String_Length(recvElem) > 0LL) { #line 4340 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_ListElemSet(self, "__local__", stmt->Name, recvElem); } } } else if (code_string_equals(mname, "Map")) { #line 4344 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_TrackMapResultElem(self, stmt); } } } #line 4349 "./src/generator/c_gen.am" code_string rhs = Amalgame_Compiler_CGen_EmitExprStr(self, stmt->Left); #line 4350 "./src/generator/c_gen.am" code_string decl = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(t, " ")), stmt->Name)), " = ")), rhs)), ";"); #line 4352 "./src/generator/c_gen.am" if (code_string_equals(t, "void*")) { #line 4355 "./src/generator/c_gen.am" if (((String_StartsWith(rhs, "(") && !String_StartsWith(rhs, "(void*)")) && !String_StartsWith(rhs, "({")) && !String_Contains(rhs, "?")) { #line 4357 "./src/generator/c_gen.am" i64 closeP = String_IndexOf(rhs, ")"); #line 4358 "./src/generator/c_gen.am" if (closeP > 1LL) { #line 4359 "./src/generator/c_gen.am" code_string castT = String_Substring(rhs, 1LL, closeP - 1LL); #line 4360 "./src/generator/c_gen.am" if (String_Length(castT) > 0LL) { #line 4361 "./src/generator/c_gen.am" t = castT; #line 4362 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, stmt->Name, t); #line 4363 "./src/generator/c_gen.am" decl = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(t, " ")), stmt->Name)), " = ")), rhs)), ";")); } } } } #line 4368 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, decl); } else if (k == Amalgame_Compiler_NodeKind_RETURN_STMT) { #line 4371 "./src/generator/c_gen.am" if (stmt->Left == NULL) { #line 4372 "./src/generator/c_gen.am" if (self->InLambdaBody) { #line 4374 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("return ", Amalgame_Compiler_CGen_BoxAsVoid(self, "0"))), ";")); } else { #line 4376 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "return;"); } } else { #line 4379 "./src/generator/c_gen.am" code_string retExpr = Amalgame_Compiler_CGen_EmitExprStr(self, stmt->Left); #line 4380 "./src/generator/c_gen.am" if (code_string_equals(retExpr, "_unknown_")) { #line 4381 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "return;"); } else if (self->InLambdaBody) { #line 4385 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("return ", Amalgame_Compiler_CGen_BoxAsVoid(self, retExpr))), ";")); } else if (String_StartsWith(retExpr, "{") && (String_Length(self->CurrentRetType) > 0LL)) { #line 4388 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("return (", self->CurrentRetType)), ")")), retExpr)), ";")); } else { #line 4390 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("return ", retExpr)), ";")); } } } else if (k == Amalgame_Compiler_NodeKind_IF_STMT) { #line 4396 "./src/generator/c_gen.am" if (code_string_equals(stmt->Name, "__match__")) { #line 4397 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitMatch(self, stmt); #line 4398 "./src/generator/c_gen.am" return; } #line 4400 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_EmitIf(self, stmt); } else if (k == Amalgame_Compiler_NodeKind_WHILE_STMT) { #line 4403 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat("while (", Amalgame_Compiler_CGen_EmitExprStr(self, stmt->Cond))), ") {")); #line 4404 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 4405 "./src/generator/c_gen.am" if (stmt->Body != NULL) { Amalgame_Compiler_CGen_EmitBlock(self, stmt->Body); } #line 4406 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 4407 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); } else if (k == Amalgame_Compiler_NodeKind_FOR_IN_STMT) { #line 4410 "./src/generator/c_gen.am" code_string vn = stmt->Name; #line 4412 "./src/generator/c_gen.am" if (stmt->Left != NULL) { #line 4413 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind iterKind = stmt->Left->Kind; #line 4414 "./src/generator/c_gen.am" if (iterKind == Amalgame_Compiler_NodeKind_BINARY) { #line 4415 "./src/generator/c_gen.am" code_string iterOp = stmt->Left->Str; #line 4416 "./src/generator/c_gen.am" if (code_string_equals(iterOp, "..")) { #line 4418 "./src/generator/c_gen.am" code_string startExpr = Amalgame_Compiler_CGen_EmitExprStr(self, stmt->Left->Left); #line 4419 "./src/generator/c_gen.am" code_string endExpr = Amalgame_Compiler_CGen_EmitExprStr(self, stmt->Left->Right); #line 4420 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("for (i64 ", vn)), " = ")), startExpr)), "; ")), vn)), " < ")), endExpr)), "; ")), vn)), "++) {")); #line 4421 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, vn, "i64"); #line 4422 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 4423 "./src/generator/c_gen.am" if (stmt->Body != NULL) { Amalgame_Compiler_CGen_EmitBlock(self, stmt->Body); } #line 4424 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 4425 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 4426 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, vn, ""); #line 4427 "./src/generator/c_gen.am" return; } } } #line 4443 "./src/generator/c_gen.am" code_string elemC = ""; #line 4444 "./src/generator/c_gen.am" if (stmt->Left != NULL) { #line 4445 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind ilk = stmt->Left->Kind; #line 4446 "./src/generator/c_gen.am" if (ilk == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 4447 "./src/generator/c_gen.am" elemC = Amalgame_Compiler_CGen_ListElemGet(self, "__local__", stmt->Left->Name); } else if (((ilk == Amalgame_Compiler_NodeKind_MEMBER) && (stmt->Left->Left != NULL)) && (stmt->Left->Left->Kind == Amalgame_Compiler_NodeKind_THIS_EXPR)) { #line 4449 "./src/generator/c_gen.am" elemC = Amalgame_Compiler_CGen_ListElemGet(self, self->CurrentClass, stmt->Left->Name); } } #line 4452 "./src/generator/c_gen.am" if (String_Length(elemC) == 0LL) { elemC = "void*"; } #line 4453 "./src/generator/c_gen.am" code_string iter = Amalgame_Compiler_CGen_EmitExprStr(self, stmt->Left); #line 4454 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "{"); #line 4455 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 4456 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList* __it_", vn)), " = ")), iter)), ";")); #line 4457 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("i64 __len_", vn)), " = AmalgameList_size(__it_")), vn)), ");")); #line 4458 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("for (i64 __idx_", vn)), " = 0; __idx_")), vn)), " < __len_")), vn)), "; __idx_")), vn)), "++) {")); #line 4459 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Indent_(self->Out); #line 4460 "./src/generator/c_gen.am" code_string rawElem = code_string_concat((code_string_concat((code_string_concat((code_string_concat("__it_", vn)), "->data[__idx_")), vn)), "]"); #line 4461 "./src/generator/c_gen.am" if (code_string_equals(elemC, "void*")) { #line 4462 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat("void* ", vn)), " = ")), rawElem)), ";")); } else if (Amalgame_Compiler_CGen_IsCPointerType(self, elemC)) { #line 4464 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(elemC, " ")), vn)), " = (")), elemC)), ")")), rawElem)), ";")); } else { #line 4467 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(elemC, " ")), vn)), " = ")), Amalgame_Compiler_CGen_UnboxScalar(self, elemC, rawElem))), ";")); } #line 4469 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, vn, elemC); #line 4470 "./src/generator/c_gen.am" if (stmt->Body != NULL) { Amalgame_Compiler_CGen_EmitBlock(self, stmt->Body); } #line 4471 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 4472 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 4473 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_Dedent(self->Out); #line 4474 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "}"); #line 4475 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, vn, ""); } else if (k == Amalgame_Compiler_NodeKind_BREAK_STMT) { #line 4478 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "break;"); } else if (k == Amalgame_Compiler_NodeKind_CONTINUE_STMT) { #line 4481 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, "continue;"); } else if (k == Amalgame_Compiler_NodeKind_BINARY) { #line 4484 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(Amalgame_Compiler_CGen_EmitExprStr(self, stmt), ";")); } else if (k == Amalgame_Compiler_NodeKind_CALL) { #line 4487 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(Amalgame_Compiler_CGen_EmitExprStr(self, stmt), ";")); } else if (k == Amalgame_Compiler_NodeKind_MEMBER) { #line 4490 "./src/generator/c_gen.am" Amalgame_Compiler_Emitter_EmitLine(self->Out, code_string_concat(Amalgame_Compiler_CGen_EmitExprStr(self, stmt), ";")); } else { } } } static code_string Amalgame_Compiler_CGen_EmitExprStr(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* expr) { #line 4499 "./src/generator/c_gen.am" if (expr == NULL) { return "NULL"; } #line 4500 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind k = expr->Kind; #line 4501 "./src/generator/c_gen.am" { /* match k */ if ((k == Amalgame_Compiler_NodeKind_METHOD_DECL) && (code_string_equals(expr->Name, "__lambda__"))) { #line 4516 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_EmitLambdaAsClosure(self, expr); } else if ((k == Amalgame_Compiler_NodeKind_CALL) && (code_string_equals(expr->Name, "__tuple_literal__"))) { #line 4522 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(expr->Args); #line 4523 "./src/generator/c_gen.am" code_string result = "{"; #line 4524 "./src/generator/c_gen.am" for (i64 i = 0LL; i < argc; i++) { #line 4525 "./src/generator/c_gen.am" if (i > 0LL) { result = (code_string_concat(result, ", ")); } #line 4526 "./src/generator/c_gen.am" result = (code_string_concat(result, Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i)))); } #line 4528 "./src/generator/c_gen.am" result = (code_string_concat(result, "}")); #line 4529 "./src/generator/c_gen.am" return result; } else if (k == Amalgame_Compiler_NodeKind_IF_STMT) { #line 4533 "./src/generator/c_gen.am" if (code_string_equals(expr->Name, "__match__")) { #line 4534 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_EmitMatchExpr(self, expr); } #line 4536 "./src/generator/c_gen.am" code_string condStr = Amalgame_Compiler_CGen_EmitExprStr(self, expr->Cond); #line 4537 "./src/generator/c_gen.am" code_string thenStr = Amalgame_Compiler_CGen_EmitIfBranch(self, expr->Body); #line 4538 "./src/generator/c_gen.am" code_string elseStr = Amalgame_Compiler_CGen_EmitIfBranch(self, expr->Else); #line 4539 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", condStr)), " ? ")), thenStr)), " : ")), elseStr)), ")"); } else if (k == Amalgame_Compiler_NodeKind_LITERAL_INT) { #line 4547 "./src/generator/c_gen.am" return code_string_concat(expr->Str, "LL"); } else if (k == Amalgame_Compiler_NodeKind_LITERAL_FLOAT) { #line 4548 "./src/generator/c_gen.am" return expr->Str; } else if (k == Amalgame_Compiler_NodeKind_LITERAL_STRING) { #line 4550 "./src/generator/c_gen.am" code_string raw = expr->Str; #line 4551 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_EmitInterpolatedString(self, raw); } else if (k == Amalgame_Compiler_NodeKind_LITERAL_BOOL) { #line 4554 "./src/generator/c_gen.am" if (expr->Flag) { return "1"; } #line 4555 "./src/generator/c_gen.am" return "0"; } else if (k == Amalgame_Compiler_NodeKind_LITERAL_NULL) { #line 4557 "./src/generator/c_gen.am" return "NULL"; } else if (k == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 4558 "./src/generator/c_gen.am" return "self"; } else if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 4568 "./src/generator/c_gen.am" code_string name = expr->Name; #line 4569 "./src/generator/c_gen.am" if (String_Length(self->CurrentClass) > 0LL) { #line 4570 "./src/generator/c_gen.am" code_string asLocal = Amalgame_Compiler_CGen_LocalTypeGet(self, name); #line 4571 "./src/generator/c_gen.am" if (String_Length(asLocal) == 0LL) { #line 4572 "./src/generator/c_gen.am" code_string asField = Amalgame_Compiler_CGen_FieldTypeGet(self, self->CurrentClass, name); #line 4573 "./src/generator/c_gen.am" if ((String_Length(asField) > 0LL) && (!code_string_equals(asField, "?"))) { #line 4574 "./src/generator/c_gen.am" return code_string_concat("self->", name); } } } #line 4578 "./src/generator/c_gen.am" return name; } else if (k == Amalgame_Compiler_NodeKind_MEMBER) { #line 4584 "./src/generator/c_gen.am" if (expr->Flag) { #line 4585 "./src/generator/c_gen.am" code_string target = Amalgame_Compiler_CGen_EmitExprStr(self, expr->Left); #line 4586 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", target)), " ? ")), target)), "->")), expr->Name)), " : NULL)"); } #line 4588 "./src/generator/c_gen.am" if (expr->Left != NULL) { #line 4589 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind lk = expr->Left->Kind; #line 4590 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 4591 "./src/generator/c_gen.am" return code_string_concat("self->", expr->Name); } #line 4593 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 4594 "./src/generator/c_gen.am" code_string tname = expr->Left->Name; #line 4595 "./src/generator/c_gen.am" code_string firstChar = String_Substring(tname, 0LL, 1LL); #line 4596 "./src/generator/c_gen.am" code_bool isUpper = code_string_equals(firstChar, String_ToUpper(firstChar)); #line 4597 "./src/generator/c_gen.am" if (isUpper) { #line 4604 "./src/generator/c_gen.am" code_string externalEnumMangled = Amalgame_Compiler_CGen_ExternalEnumMangled(self, tname); #line 4605 "./src/generator/c_gen.am" if (String_Length(externalEnumMangled) > 0LL) { #line 4606 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(externalEnumMangled, "_")), expr->Name); } #line 4609 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(Amalgame_Compiler_CGen_SymName(self, tname), "_")), expr->Name); } #line 4611 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(tname, "->")), expr->Name); } } #line 4614 "./src/generator/c_gen.am" code_string target = Amalgame_Compiler_CGen_EmitExprStr(self, expr->Left); #line 4615 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(target, "->")), expr->Name); } else if (k == Amalgame_Compiler_NodeKind_BINARY) { #line 4618 "./src/generator/c_gen.am" code_string left = Amalgame_Compiler_CGen_EmitExprStr(self, expr->Left); #line 4619 "./src/generator/c_gen.am" code_string op = expr->Str; #line 4620 "./src/generator/c_gen.am" code_string right = Amalgame_Compiler_CGen_EmitExprStr(self, expr->Right); #line 4628 "./src/generator/c_gen.am" if ((expr->Left != NULL) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_BINARY)) { #line 4629 "./src/generator/c_gen.am" left = (code_string_concat((code_string_concat("(", left)), ")")); } #line 4631 "./src/generator/c_gen.am" if ((expr->Right != NULL) && (expr->Right->Kind == Amalgame_Compiler_NodeKind_BINARY)) { #line 4632 "./src/generator/c_gen.am" right = (code_string_concat((code_string_concat("(", right)), ")")); } #line 4634 "./src/generator/c_gen.am" if ((code_string_equals(op, "==")) || (code_string_equals(op, "!="))) { #line 4636 "./src/generator/c_gen.am" code_string ltype = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Left); #line 4637 "./src/generator/c_gen.am" code_bool useStrEq = 0; #line 4638 "./src/generator/c_gen.am" if (code_string_equals(ltype, "code_string")) { useStrEq = 1; } #line 4640 "./src/generator/c_gen.am" if (String_Length(ltype) == 0LL) { #line 4641 "./src/generator/c_gen.am" if (expr->Left != NULL) { #line 4642 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind lk2 = expr->Left->Kind; #line 4643 "./src/generator/c_gen.am" if (lk2 == Amalgame_Compiler_NodeKind_LITERAL_STRING) { useStrEq = 1; } #line 4645 "./src/generator/c_gen.am" if (lk2 == Amalgame_Compiler_NodeKind_CALL) { #line 4646 "./src/generator/c_gen.am" if (expr->Left->Left != NULL) { #line 4647 "./src/generator/c_gen.am" code_string calleeStr = Amalgame_Compiler_CGen_EmitCalleeStr(self, expr->Left->Left); #line 4648 "./src/generator/c_gen.am" if (String_StartsWith(calleeStr, "String_") || String_EndsWith(calleeStr, "_CharAt")) { #line 4649 "./src/generator/c_gen.am" useStrEq = 1; } } } #line 4654 "./src/generator/c_gen.am" if (lk2 == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 4655 "./src/generator/c_gen.am" code_string lt2 = Amalgame_Compiler_CGen_LocalTypeGet(self, expr->Left->Name); #line 4656 "./src/generator/c_gen.am" if (code_string_equals(lt2, "code_string")) { useStrEq = 1; } } #line 4659 "./src/generator/c_gen.am" if (lk2 == Amalgame_Compiler_NodeKind_MEMBER) { #line 4660 "./src/generator/c_gen.am" code_string ft = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Left); #line 4661 "./src/generator/c_gen.am" if (code_string_equals(ft, "code_string")) { useStrEq = 1; } } } } #line 4666 "./src/generator/c_gen.am" if (!useStrEq) { #line 4667 "./src/generator/c_gen.am" if (expr->Right != NULL) { #line 4668 "./src/generator/c_gen.am" if (expr->Right->Kind == Amalgame_Compiler_NodeKind_LITERAL_STRING) { useStrEq = 1; } } } #line 4671 "./src/generator/c_gen.am" if (useStrEq) { #line 4672 "./src/generator/c_gen.am" if (code_string_equals(op, "==")) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("code_string_equals(", left)), ", ")), right)), ")"); } #line 4673 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("!code_string_equals(", left)), ", ")), right)), ")"); } #line 4676 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat(left, " ")), op)), " ")), right); } #line 4679 "./src/generator/c_gen.am" if (code_string_equals(op, "+")) { #line 4680 "./src/generator/c_gen.am" code_string ltype2 = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Left); #line 4681 "./src/generator/c_gen.am" code_bool useConcat = 0; #line 4682 "./src/generator/c_gen.am" if (code_string_equals(ltype2, "code_string")) { useConcat = 1; } #line 4683 "./src/generator/c_gen.am" if (!useConcat) { #line 4684 "./src/generator/c_gen.am" if (expr->Left != NULL) { #line 4685 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind lk3 = expr->Left->Kind; #line 4686 "./src/generator/c_gen.am" if (lk3 == Amalgame_Compiler_NodeKind_LITERAL_STRING) { useConcat = 1; } #line 4687 "./src/generator/c_gen.am" if (lk3 == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 4688 "./src/generator/c_gen.am" code_string lt3 = Amalgame_Compiler_CGen_LocalTypeGet(self, expr->Left->Name); #line 4689 "./src/generator/c_gen.am" if (code_string_equals(lt3, "code_string")) { useConcat = 1; } } #line 4699 "./src/generator/c_gen.am" if (lk3 == Amalgame_Compiler_NodeKind_CALL) { #line 4700 "./src/generator/c_gen.am" code_string ltype3 = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Left); #line 4701 "./src/generator/c_gen.am" if (code_string_equals(ltype3, "code_string")) { useConcat = 1; } #line 4702 "./src/generator/c_gen.am" if (expr->Left->Left != NULL) { #line 4703 "./src/generator/c_gen.am" code_string calleeL = Amalgame_Compiler_CGen_EmitCalleeStr(self, expr->Left->Left); #line 4704 "./src/generator/c_gen.am" if (code_string_equals(calleeL, "code_string_concat")) { #line 4705 "./src/generator/c_gen.am" useConcat = 1; } } } } } #line 4711 "./src/generator/c_gen.am" if (!useConcat) { #line 4712 "./src/generator/c_gen.am" if (expr->Right != NULL) { #line 4713 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind rk3 = expr->Right->Kind; #line 4714 "./src/generator/c_gen.am" if (rk3 == Amalgame_Compiler_NodeKind_LITERAL_STRING) { useConcat = 1; } #line 4715 "./src/generator/c_gen.am" if (rk3 == Amalgame_Compiler_NodeKind_CALL) { #line 4721 "./src/generator/c_gen.am" code_string rtype3 = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Right); #line 4722 "./src/generator/c_gen.am" if (code_string_equals(rtype3, "code_string")) { useConcat = 1; } #line 4723 "./src/generator/c_gen.am" if (expr->Right->Left != NULL) { #line 4724 "./src/generator/c_gen.am" code_string calleeR = Amalgame_Compiler_CGen_EmitCalleeStr(self, expr->Right->Left); #line 4725 "./src/generator/c_gen.am" if (code_string_equals(calleeR, "code_string_concat")) { #line 4726 "./src/generator/c_gen.am" useConcat = 1; } } } } } #line 4732 "./src/generator/c_gen.am" if (useConcat) { #line 4733 "./src/generator/c_gen.am" code_string lcast = left; #line 4734 "./src/generator/c_gen.am" code_string rcast = right; #line 4735 "./src/generator/c_gen.am" code_string ltype4 = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Left); #line 4736 "./src/generator/c_gen.am" code_string rtype4 = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Right); #line 4737 "./src/generator/c_gen.am" if (code_string_equals(ltype4, "void*")) { lcast = (code_string_concat((code_string_concat("(code_string)(", left)), ")")); } #line 4738 "./src/generator/c_gen.am" if (code_string_equals(rtype4, "void*")) { rcast = (code_string_concat((code_string_concat("(code_string)(", right)), ")")); } #line 4739 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("code_string_concat(", lcast)), ", ")), rcast)), ")"); } } #line 4742 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat(left, " ")), op)), " ")), right); } else if (k == Amalgame_Compiler_NodeKind_UNARY) { #line 4750 "./src/generator/c_gen.am" if (code_string_equals(expr->Str, "await")) { #line 4751 "./src/generator/c_gen.am" code_string futExpr = Amalgame_Compiler_CGen_EmitExprStr(self, expr->Left); #line 4752 "./src/generator/c_gen.am" code_string retC = Amalgame_Compiler_CGen_ResolveAwaitRetC(self, expr->Left); #line 4760 "./src/generator/c_gen.am" code_string recv = "Amalgame_Async_ChannelReceive(__af)"; #line 4761 "./src/generator/c_gen.am" if (!(((String_Length(retC) == 0LL) || (code_string_equals(retC, "void"))) || (code_string_equals(retC, "i64")))) { #line 4762 "./src/generator/c_gen.am" recv = Amalgame_Compiler_CGen_UnboxScalar(self, retC, "Amalgame_Async_ChannelReceive(__af)"); } #line 4764 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("({ AmalgameAsyncChannel* __af = (", futExpr)), "); ")), "if (Amalgame_Async_FiberCurrentId() == 0) { Amalgame_Async_SchedulerRun(); } ")), recv)), "; })"); } #line 4768 "./src/generator/c_gen.am" code_string operand = Amalgame_Compiler_CGen_EmitExprStr(self, expr->Left); #line 4771 "./src/generator/c_gen.am" if (expr->Left != NULL) { #line 4772 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind lk = expr->Left->Kind; #line 4773 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_BINARY) { return code_string_concat((code_string_concat((code_string_concat(expr->Str, "(")), operand)), ")"); } } #line 4775 "./src/generator/c_gen.am" return code_string_concat(expr->Str, operand); } else if (k == Amalgame_Compiler_NodeKind_CALL) { #line 4794 "./src/generator/c_gen.am" if ((expr->Left != NULL) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER)) { #line 4795 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* mem = expr->Left; #line 4796 "./src/generator/c_gen.am" if ((mem->Left != NULL) && (!code_string_equals(mem->Name, ""))) { #line 4797 "./src/generator/c_gen.am" code_string recvCls = ""; #line 4798 "./src/generator/c_gen.am" code_string recvExpr = ""; #line 4799 "./src/generator/c_gen.am" if (mem->Left->Kind == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 4800 "./src/generator/c_gen.am" recvCls = self->CurrentClass; #line 4801 "./src/generator/c_gen.am" recvExpr = "self"; } else if (mem->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 4807 "./src/generator/c_gen.am" code_string localType = Amalgame_Compiler_CGen_LocalTypeGet(self, mem->Left->Name); #line 4808 "./src/generator/c_gen.am" recvCls = String_Replace(localType, "*", ""); #line 4809 "./src/generator/c_gen.am" recvExpr = mem->Left->Name; } else if (mem->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER) { #line 4816 "./src/generator/c_gen.am" code_string nestedCls = Amalgame_Compiler_CGen_ResolveReceiverClass(self, mem->Left); #line 4817 "./src/generator/c_gen.am" if (String_Length(nestedCls) > 0LL) { #line 4818 "./src/generator/c_gen.am" recvCls = nestedCls; #line 4819 "./src/generator/c_gen.am" recvExpr = Amalgame_Compiler_CGen_EmitExprStr(self, mem->Left); } } #line 4822 "./src/generator/c_gen.am" if (String_Length(recvCls) > 0LL) { #line 4823 "./src/generator/c_gen.am" code_string ft = Amalgame_Compiler_CGen_FieldTypeGet(self, recvCls, mem->Name); #line 4824 "./src/generator/c_gen.am" if (code_string_equals(ft, "AmalgameClosure*")) { #line 4825 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(expr->Args); #line 4826 "./src/generator/c_gen.am" code_string calleeName = code_string_concat((code_string_concat(recvExpr, "->")), mem->Name); #line 4832 "./src/generator/c_gen.am" code_string retC0 = Amalgame_Compiler_CGen_ListElemGet(self, code_string_concat(recvCls, "__closure_ret__"), mem->Name); #line 4833 "./src/generator/c_gen.am" code_string retC = retC0; #line 4834 "./src/generator/c_gen.am" if (String_Length(retC) == 0LL) { retC = "i64"; } #line 4835 "./src/generator/c_gen.am" if (argc == 1LL) { #line 4836 "./src/generator/c_gen.am" code_string arg0 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 0LL)); #line 4837 "./src/generator/c_gen.am" code_string callC = code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameClosure_call1(", calleeName)), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg0))), ")"); #line 4838 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsCPointerType(self, retC)) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("((", retC)), ")")), callC)), ")"); } #line 4839 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_UnboxScalar(self, retC, callC); } #line 4841 "./src/generator/c_gen.am" if (argc == 2LL) { #line 4842 "./src/generator/c_gen.am" code_string arg0 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 0LL)); #line 4843 "./src/generator/c_gen.am" code_string arg1 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 1LL)); #line 4844 "./src/generator/c_gen.am" code_string callC = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameClosure_call2(", calleeName)), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg0))), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg1))), ")"); #line 4845 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsCPointerType(self, retC)) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("((", retC)), ")")), callC)), ")"); } #line 4846 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_UnboxScalar(self, retC, callC); } #line 4848 "./src/generator/c_gen.am" if (argc == 3LL) { #line 4849 "./src/generator/c_gen.am" code_string arg0 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 0LL)); #line 4850 "./src/generator/c_gen.am" code_string arg1 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 1LL)); #line 4851 "./src/generator/c_gen.am" code_string arg2 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 2LL)); #line 4852 "./src/generator/c_gen.am" code_string callC = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameClosure_call3(", calleeName)), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg0))), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg1))), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg2))), ")"); #line 4853 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsCPointerType(self, retC)) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("((", retC)), ")")), callC)), ")"); } #line 4854 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_UnboxScalar(self, retC, callC); } } } } } #line 4865 "./src/generator/c_gen.am" if ((expr->Left != NULL) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 4866 "./src/generator/c_gen.am" code_string calleeName = expr->Left->Name; #line 4867 "./src/generator/c_gen.am" code_string calleeType = Amalgame_Compiler_CGen_LocalTypeGet(self, calleeName); #line 4868 "./src/generator/c_gen.am" if (code_string_equals(calleeType, "AmalgameClosure*")) { #line 4869 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(expr->Args); #line 4879 "./src/generator/c_gen.am" code_string retC0 = Amalgame_Compiler_CGen_ListElemGet(self, "__closure_ret__", calleeName); #line 4880 "./src/generator/c_gen.am" code_string retC = retC0; #line 4881 "./src/generator/c_gen.am" if (String_Length(retC) == 0LL) { retC = "i64"; } #line 4882 "./src/generator/c_gen.am" if (argc == 1LL) { #line 4883 "./src/generator/c_gen.am" code_string arg0 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 0LL)); #line 4884 "./src/generator/c_gen.am" code_string callC = code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameClosure_call1(", calleeName)), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg0))), ")"); #line 4885 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsCPointerType(self, retC)) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("((", retC)), ")")), callC)), ")"); } #line 4886 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_UnboxScalar(self, retC, callC); } #line 4888 "./src/generator/c_gen.am" if (argc == 2LL) { #line 4889 "./src/generator/c_gen.am" code_string arg0 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 0LL)); #line 4890 "./src/generator/c_gen.am" code_string arg1 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 1LL)); #line 4891 "./src/generator/c_gen.am" code_string callC = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameClosure_call2(", calleeName)), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg0))), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg1))), ")"); #line 4892 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsCPointerType(self, retC)) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("((", retC)), ")")), callC)), ")"); } #line 4893 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_UnboxScalar(self, retC, callC); } #line 4895 "./src/generator/c_gen.am" if (argc == 3LL) { #line 4896 "./src/generator/c_gen.am" code_string arg0 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 0LL)); #line 4897 "./src/generator/c_gen.am" code_string arg1 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 1LL)); #line 4898 "./src/generator/c_gen.am" code_string arg2 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 2LL)); #line 4899 "./src/generator/c_gen.am" code_string callC = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameClosure_call3(", calleeName)), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg0))), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg1))), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg2))), ")"); #line 4900 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsCPointerType(self, retC)) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("((", retC)), ")")), callC)), ")"); } #line 4901 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_UnboxScalar(self, retC, callC); } } } #line 4906 "./src/generator/c_gen.am" code_string listCall = Amalgame_Compiler_CGen_TryEmitListCall(self, expr); #line 4907 "./src/generator/c_gen.am" if (String_Length(listCall) > 0LL) { return listCall; } #line 4909 "./src/generator/c_gen.am" code_bool isSelfCall = 0; #line 4910 "./src/generator/c_gen.am" code_string selfExpr = "self"; #line 4911 "./src/generator/c_gen.am" if (expr->Left != NULL) { #line 4912 "./src/generator/c_gen.am" if (expr->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER) { #line 4913 "./src/generator/c_gen.am" if (expr->Left->Left != NULL) { #line 4914 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* ll = expr->Left->Left; #line 4916 "./src/generator/c_gen.am" if (ll->Kind == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 4917 "./src/generator/c_gen.am" isSelfCall = 1; #line 4918 "./src/generator/c_gen.am" selfExpr = "self"; } #line 4922 "./src/generator/c_gen.am" if (ll->Kind == Amalgame_Compiler_NodeKind_MEMBER) { #line 4923 "./src/generator/c_gen.am" if (ll->Left != NULL) { #line 4924 "./src/generator/c_gen.am" if (ll->Left->Kind == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 4925 "./src/generator/c_gen.am" isSelfCall = 1; #line 4926 "./src/generator/c_gen.am" selfExpr = (code_string_concat("self->", ll->Name)); } #line 4931 "./src/generator/c_gen.am" if (ll->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 4932 "./src/generator/c_gen.am" code_string vt = Amalgame_Compiler_CGen_LocalTypeGet(self, ll->Left->Name); #line 4933 "./src/generator/c_gen.am" code_string vbare = String_Replace(vt, "*", ""); #line 4934 "./src/generator/c_gen.am" if ((String_Length(vbare) > 0LL) && !Amalgame_Compiler_CGen_IsEnum(self, vbare)) { #line 4935 "./src/generator/c_gen.am" isSelfCall = 1; #line 4936 "./src/generator/c_gen.am" selfExpr = (code_string_concat((code_string_concat(ll->Left->Name, "->")), ll->Name)); } } #line 4944 "./src/generator/c_gen.am" if (ll->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER) { #line 4945 "./src/generator/c_gen.am" code_string deepCls = Amalgame_Compiler_CGen_ResolveReceiverClass(self, ll); #line 4946 "./src/generator/c_gen.am" if ((String_Length(deepCls) > 0LL) && !Amalgame_Compiler_CGen_IsEnum(self, deepCls)) { #line 4947 "./src/generator/c_gen.am" isSelfCall = 1; #line 4948 "./src/generator/c_gen.am" selfExpr = Amalgame_Compiler_CGen_EmitExprStr(self, ll); } } } } #line 4954 "./src/generator/c_gen.am" if (ll->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 4955 "./src/generator/c_gen.am" code_string vt = Amalgame_Compiler_CGen_LocalTypeGet(self, ll->Name); #line 4956 "./src/generator/c_gen.am" code_string bare = String_Replace(vt, "*", ""); #line 4957 "./src/generator/c_gen.am" if ((String_Length(bare) > 0LL) && !Amalgame_Compiler_CGen_IsEnum(self, bare)) { #line 4958 "./src/generator/c_gen.am" isSelfCall = 1; #line 4959 "./src/generator/c_gen.am" selfExpr = ll->Name; } } #line 4967 "./src/generator/c_gen.am" if (ll->Kind == Amalgame_Compiler_NodeKind_CALL) { #line 4968 "./src/generator/c_gen.am" code_string rt = Amalgame_Compiler_CGen_InferTypeFromExpr(self, ll); #line 4969 "./src/generator/c_gen.am" code_string rbare = String_Replace(rt, "*", ""); #line 4970 "./src/generator/c_gen.am" if ((String_Length(rbare) > 0LL) && !Amalgame_Compiler_CGen_IsEnum(self, rbare)) { #line 4971 "./src/generator/c_gen.am" isSelfCall = 1; #line 4972 "./src/generator/c_gen.am" selfExpr = Amalgame_Compiler_CGen_EmitExprStr(self, ll); } } #line 4980 "./src/generator/c_gen.am" if (ll->Kind == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 4981 "./src/generator/c_gen.am" isSelfCall = 1; #line 4982 "./src/generator/c_gen.am" selfExpr = Amalgame_Compiler_CGen_EmitExprStr(self, ll); } #line 4986 "./src/generator/c_gen.am" if (ll->Kind == Amalgame_Compiler_NodeKind_LITERAL_STRING) { #line 4987 "./src/generator/c_gen.am" isSelfCall = 1; #line 4988 "./src/generator/c_gen.am" selfExpr = Amalgame_Compiler_CGen_EmitExprStr(self, ll); } } } } #line 4997 "./src/generator/c_gen.am" if (((expr->Left != NULL) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER)) && (expr->Left->Left != NULL)) { #line 4998 "./src/generator/c_gen.am" code_string recvT0 = Amalgame_Compiler_CGen_InferTypeFromExpr(self, expr->Left->Left); #line 4999 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsInterface(self, recvT0)) { #line 5000 "./src/generator/c_gen.am" code_string recvC = Amalgame_Compiler_CGen_EmitExprStr(self, expr->Left->Left); #line 5001 "./src/generator/c_gen.am" code_string mname = expr->Left->Name; #line 5002 "./src/generator/c_gen.am" code_string icallee = code_string_concat((code_string_concat(recvC, ".itab->")), mname); #line 5003 "./src/generator/c_gen.am" code_string ic = code_string_concat((code_string_concat((code_string_concat(icallee, "(")), recvC)), ".data"); #line 5004 "./src/generator/c_gen.am" i64 argcI = AmalgameList_count(expr->Args); #line 5005 "./src/generator/c_gen.am" for (i64 ai = 0LL; ai < argcI; ai++) { #line 5006 "./src/generator/c_gen.am" ic = (code_string_concat((code_string_concat(ic, ", ")), Amalgame_Compiler_CGen_CoerceArg(self, icallee, ai, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, ai)))); } #line 5008 "./src/generator/c_gen.am" ic = (code_string_concat(ic, ")")); #line 5009 "./src/generator/c_gen.am" return ic; } } #line 5012 "./src/generator/c_gen.am" code_string callee = Amalgame_Compiler_CGen_EmitCalleeStr(self, expr->Left); #line 5013 "./src/generator/c_gen.am" code_string callStr = code_string_concat(callee, "("); #line 5014 "./src/generator/c_gen.am" code_bool first = 1; #line 5015 "./src/generator/c_gen.am" if (isSelfCall) { #line 5016 "./src/generator/c_gen.am" callStr = (code_string_concat(callStr, selfExpr)); #line 5017 "./src/generator/c_gen.am" first = 0; } #line 5019 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(expr->Args); #line 5024 "./src/generator/c_gen.am" i64 fixedArity = Amalgame_Compiler_CGen_MethodVariadicGet(self, callee); #line 5025 "./src/generator/c_gen.am" if (fixedArity >= 0LL) { #line 5026 "./src/generator/c_gen.am" for (i64 i = 0LL; i < argc; i++) { #line 5027 "./src/generator/c_gen.am" if (i < fixedArity) { #line 5028 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* arg = (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i); #line 5029 "./src/generator/c_gen.am" if (!first) { callStr = (code_string_concat(callStr, ", ")); } #line 5030 "./src/generator/c_gen.am" callStr = (code_string_concat(callStr, Amalgame_Compiler_CGen_EmitExprStr(self, arg))); #line 5031 "./src/generator/c_gen.am" first = 0; } } #line 5034 "./src/generator/c_gen.am" if (!first) { callStr = (code_string_concat(callStr, ", ")); } #line 5035 "./src/generator/c_gen.am" callStr = (code_string_concat(callStr, Amalgame_Compiler_CGen_EmitVariadicTail(self, expr, fixedArity))); #line 5036 "./src/generator/c_gen.am" first = 0; } else { #line 5038 "./src/generator/c_gen.am" for (i64 i = 0LL; i < argc; i++) { #line 5039 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* arg = (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i); #line 5040 "./src/generator/c_gen.am" if (!first) { callStr = (code_string_concat(callStr, ", ")); } #line 5041 "./src/generator/c_gen.am" callStr = (code_string_concat(callStr, Amalgame_Compiler_CGen_CoerceArg(self, callee, i, arg))); #line 5042 "./src/generator/c_gen.am" first = 0; } } #line 5045 "./src/generator/c_gen.am" callStr = (code_string_concat(callStr, ")")); #line 5048 "./src/generator/c_gen.am" if (((expr->Left != NULL) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER)) && expr->Left->Flag) { #line 5049 "./src/generator/c_gen.am" code_string recv = Amalgame_Compiler_CGen_EmitExprStr(self, expr->Left->Left); #line 5050 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", recv)), " ? ")), callStr)), " : NULL)"); } #line 5052 "./src/generator/c_gen.am" return callStr; } else if (k == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 5055 "./src/generator/c_gen.am" code_string tname = expr->Name; #line 5056 "./src/generator/c_gen.am" code_string newCall = ""; #line 5057 "./src/generator/c_gen.am" if (String_StartsWith(tname, "List<") || (code_string_equals(tname, "List"))) { #line 5058 "./src/generator/c_gen.am" newCall = "AmalgameList_new()"; } else { #line 5060 "./src/generator/c_gen.am" if (String_StartsWith(tname, "Map<") || (code_string_equals(tname, "Map"))) { #line 5061 "./src/generator/c_gen.am" newCall = "AmalgameMap_new()"; } else { #line 5063 "./src/generator/c_gen.am" if (String_StartsWith(tname, "Set<") || (code_string_equals(tname, "Set"))) { #line 5064 "./src/generator/c_gen.am" newCall = "AmalgameSet_new()"; } else if (code_string_equals(tname, "WebSocket")) { #line 5073 "./src/generator/c_gen.am" newCall = (code_string_concat(tname, "_new(")); #line 5074 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(expr->Args); #line 5075 "./src/generator/c_gen.am" for (i64 i = 0LL; i < argc; i++) { #line 5076 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* arg = (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i); #line 5077 "./src/generator/c_gen.am" if (i > 0LL) { newCall = (code_string_concat(newCall, ", ")); } #line 5078 "./src/generator/c_gen.am" newCall = (code_string_concat(newCall, Amalgame_Compiler_CGen_EmitExprStr(self, arg))); } #line 5080 "./src/generator/c_gen.am" newCall = (code_string_concat(newCall, ")")); #line 5081 "./src/generator/c_gen.am" return newCall; } else { #line 5089 "./src/generator/c_gen.am" code_string externalMangled = Amalgame_Compiler_CGen_ExternalClassMangled(self, tname); #line 5090 "./src/generator/c_gen.am" code_string ctorPrefix = ""; #line 5091 "./src/generator/c_gen.am" if (String_Length(externalMangled) > 0LL) { #line 5092 "./src/generator/c_gen.am" ctorPrefix = externalMangled; } else { #line 5094 "./src/generator/c_gen.am" ctorPrefix = Amalgame_Compiler_CGen_ClassMangledFor(self, tname); } #line 5096 "./src/generator/c_gen.am" newCall = (code_string_concat(ctorPrefix, "_new(")); #line 5103 "./src/generator/c_gen.am" i64 ctorArity = Amalgame_Compiler_CGen_MethodVariadicGet(self, code_string_concat(ctorPrefix, "_new")); #line 5104 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(expr->Args); #line 5105 "./src/generator/c_gen.am" if (ctorArity >= 0LL) { #line 5106 "./src/generator/c_gen.am" code_bool cfirst = 1; #line 5107 "./src/generator/c_gen.am" for (i64 i = 0LL; i < argc; i++) { #line 5108 "./src/generator/c_gen.am" if (i < ctorArity) { #line 5109 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* arg = (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i); #line 5110 "./src/generator/c_gen.am" if (!cfirst) { newCall = (code_string_concat(newCall, ", ")); } #line 5111 "./src/generator/c_gen.am" newCall = (code_string_concat(newCall, Amalgame_Compiler_CGen_EmitExprStr(self, arg))); #line 5112 "./src/generator/c_gen.am" cfirst = 0; } } #line 5115 "./src/generator/c_gen.am" if (!cfirst) { newCall = (code_string_concat(newCall, ", ")); } #line 5116 "./src/generator/c_gen.am" newCall = (code_string_concat(newCall, Amalgame_Compiler_CGen_EmitVariadicTail(self, expr, ctorArity))); } else { #line 5118 "./src/generator/c_gen.am" for (i64 i = 0LL; i < argc; i++) { #line 5119 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* arg = (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i); #line 5120 "./src/generator/c_gen.am" if (i > 0LL) { newCall = (code_string_concat(newCall, ", ")); } #line 5121 "./src/generator/c_gen.am" newCall = (code_string_concat(newCall, Amalgame_Compiler_CGen_CoerceArg(self, code_string_concat(ctorPrefix, "_new"), i, arg))); } } #line 5124 "./src/generator/c_gen.am" newCall = (code_string_concat(newCall, ")")); } } } #line 5128 "./src/generator/c_gen.am" return newCall; } else if (k == Amalgame_Compiler_NodeKind_INDEX_EXPR) { #line 5131 "./src/generator/c_gen.am" code_string base = Amalgame_Compiler_CGen_EmitExprStr(self, expr->Left); #line 5132 "./src/generator/c_gen.am" code_string idx = Amalgame_Compiler_CGen_EmitExprStr(self, expr->Right); #line 5133 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat(base, "[")), idx)), "]"); } else if (k == Amalgame_Compiler_NodeKind_LIST_COMP) { #line 5136 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_EmitListComp(self, expr); } else if (k == Amalgame_Compiler_NodeKind_LIST_LITERAL) { #line 5139 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_EmitListLiteral(self, expr); } else { } } #line 5143 "./src/generator/c_gen.am" return "/* unknown expr */"; } static code_string Amalgame_Compiler_CGen_EmitListLiteral(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* n) { #line 5153 "./src/generator/c_gen.am" code_string s = "({ AmalgameList* __ll = AmalgameList_new(); "; #line 5154 "./src/generator/c_gen.am" i64 nc = AmalgameList_count(n->Children); #line 5155 "./src/generator/c_gen.am" for (i64 i = 0LL; i < nc; i++) { #line 5156 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* child = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, i); #line 5162 "./src/generator/c_gen.am" if ((child->Kind == Amalgame_Compiler_NodeKind_UNARY) && (code_string_equals(child->Str, "..."))) { #line 5163 "./src/generator/c_gen.am" code_string src = Amalgame_Compiler_CGen_EmitExprStr(self, child->Left); #line 5164 "./src/generator/c_gen.am" code_string idx = String_FromInt(i); #line 5165 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "{ AmalgameList* __sp_")), idx)), " = ")), src)), "; ")); #line 5166 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "i64 __spn_")), idx)), " = AmalgameList_size(__sp_")), idx)), "); ")); #line 5167 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "for (i64 __spi_")), idx)), " = 0; __spi_")), idx)), " < __spn_")), idx)), "; __spi_")), idx)), "++) { ")); #line 5168 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "AmalgameList_add(__ll, __sp_")), idx)), "->data[__spi_")), idx)), "]); ")); #line 5169 "./src/generator/c_gen.am" s = (code_string_concat(s, "} } ")); #line 5170 "./src/generator/c_gen.am" continue; } #line 5172 "./src/generator/c_gen.am" code_string elem = Amalgame_Compiler_CGen_EmitExprStr(self, child); #line 5173 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "AmalgameList_add(__ll, ")), Amalgame_Compiler_CGen_BoxAsVoid(self, elem))), "); ")); } #line 5175 "./src/generator/c_gen.am" s = (code_string_concat(s, "__ll; })")); #line 5176 "./src/generator/c_gen.am" return s; } static code_string Amalgame_Compiler_CGen_EmitVariadicTail(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* call, i64 fixedArity) { #line 5187 "./src/generator/c_gen.am" code_string s = "({ AmalgameList* __va = AmalgameList_new(); "; #line 5188 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(call->Args); #line 5189 "./src/generator/c_gen.am" for (i64 i = fixedArity; i < argc; i++) { #line 5190 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* arg = (Amalgame_Compiler_AstNode*)AmalgameList_get(call->Args, i); #line 5191 "./src/generator/c_gen.am" if ((arg->Kind == Amalgame_Compiler_NodeKind_UNARY) && (code_string_equals(arg->Str, "..."))) { #line 5192 "./src/generator/c_gen.am" code_string src = Amalgame_Compiler_CGen_EmitExprStr(self, arg->Left); #line 5193 "./src/generator/c_gen.am" code_string idx = String_FromInt(i); #line 5194 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "{ AmalgameList* __va_sp_")), idx)), " = ")), src)), "; ")); #line 5195 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "i64 __va_spn_")), idx)), " = AmalgameList_size(__va_sp_")), idx)), "); ")); #line 5196 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "for (i64 __va_spi_")), idx)), " = 0; __va_spi_")), idx)), " < __va_spn_")), idx)), "; __va_spi_")), idx)), "++) { ")); #line 5197 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "AmalgameList_add(__va, __va_sp_")), idx)), "->data[__va_spi_")), idx)), "]); ")); #line 5198 "./src/generator/c_gen.am" s = (code_string_concat(s, "} } ")); #line 5199 "./src/generator/c_gen.am" continue; } #line 5201 "./src/generator/c_gen.am" code_string elem = Amalgame_Compiler_CGen_EmitExprStr(self, arg); #line 5202 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "AmalgameList_add(__va, ")), Amalgame_Compiler_CGen_BoxAsVoid(self, elem))), "); ")); } #line 5204 "./src/generator/c_gen.am" s = (code_string_concat(s, "__va; })")); #line 5205 "./src/generator/c_gen.am" return s; } static code_string Amalgame_Compiler_CGen_EmitMatchExpr(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* n) { #line 5220 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* subject = n->Left; #line 5221 "./src/generator/c_gen.am" if (subject == NULL) { return "/* match-expr: missing subject */"; } #line 5222 "./src/generator/c_gen.am" code_string subjectStr = Amalgame_Compiler_CGen_EmitExprStr(self, subject); #line 5223 "./src/generator/c_gen.am" i64 armCount = AmalgameList_count(n->Children); #line 5224 "./src/generator/c_gen.am" if (armCount == 0LL) { return "/* match-expr: no arms */"; } #line 5227 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* firstArm = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, 0LL); #line 5228 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* firstBody = firstArm->Right; #line 5229 "./src/generator/c_gen.am" code_string resultType = Amalgame_Compiler_CGen_InferTypeFromExpr(self, firstBody); #line 5230 "./src/generator/c_gen.am" if (String_Length(resultType) == 0LL) { resultType = "i64"; } #line 5231 "./src/generator/c_gen.am" code_string s = code_string_concat((code_string_concat("({ ", resultType)), " __mr; "); #line 5232 "./src/generator/c_gen.am" code_bool firstArmFlag = 1; #line 5233 "./src/generator/c_gen.am" for (i64 i = 0LL; i < armCount; i++) { #line 5234 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* arm = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, i); #line 5235 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* pat = arm->Left; #line 5236 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* body = arm->Right; #line 5237 "./src/generator/c_gen.am" if ((pat == NULL) || (body == NULL)) { continue; } #line 5238 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind pk = pat->Kind; #line 5239 "./src/generator/c_gen.am" code_string bodyStr = Amalgame_Compiler_CGen_EmitExprStr(self, body); #line 5241 "./src/generator/c_gen.am" if ((pk == Amalgame_Compiler_NodeKind_IDENTIFIER) && (code_string_equals(pat->Name, "_"))) { #line 5242 "./src/generator/c_gen.am" code_string prefix = (firstArmFlag ? "" : " else "); #line 5243 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, prefix)), "{ __mr = (")), bodyStr)), "); }")); #line 5244 "./src/generator/c_gen.am" firstArmFlag = 0; #line 5245 "./src/generator/c_gen.am" continue; } #line 5248 "./src/generator/c_gen.am" code_string cond = ""; #line 5249 "./src/generator/c_gen.am" if ((pk == Amalgame_Compiler_NodeKind_BINARY) && (code_string_equals(pat->Str, ".."))) { #line 5250 "./src/generator/c_gen.am" code_string lo = Amalgame_Compiler_CGen_EmitExprStr(self, pat->Left); #line 5251 "./src/generator/c_gen.am" code_string hi = Amalgame_Compiler_CGen_EmitExprStr(self, pat->Right); #line 5252 "./src/generator/c_gen.am" cond = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(subjectStr, " >= ")), lo)), " && ")), subjectStr)), " <= ")), hi)); } else if (pk == Amalgame_Compiler_NodeKind_LITERAL_STRING) { #line 5254 "./src/generator/c_gen.am" code_string patStr = Amalgame_Compiler_CGen_EmitExprStr(self, pat); #line 5255 "./src/generator/c_gen.am" cond = (code_string_concat((code_string_concat((code_string_concat((code_string_concat("strcmp(", subjectStr)), ", ")), patStr)), ") == 0")); } else { #line 5257 "./src/generator/c_gen.am" code_string patStr = Amalgame_Compiler_CGen_EmitExprStr(self, pat); #line 5258 "./src/generator/c_gen.am" cond = (code_string_concat((code_string_concat(subjectStr, " == ")), patStr)); } #line 5260 "./src/generator/c_gen.am" code_string prefix = (firstArmFlag ? "" : " else "); #line 5261 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, prefix)), "if (")), cond)), ") { __mr = (")), bodyStr)), "); }")); #line 5262 "./src/generator/c_gen.am" firstArmFlag = 0; } #line 5264 "./src/generator/c_gen.am" s = (code_string_concat(s, " __mr; })")); #line 5265 "./src/generator/c_gen.am" return s; } static code_string Amalgame_Compiler_CGen_EmitListComp(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* n) { #line 5278 "./src/generator/c_gen.am" code_string vn = n->Str; #line 5279 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* iter = n->Right; #line 5280 "./src/generator/c_gen.am" code_bool isRange = 0; #line 5281 "./src/generator/c_gen.am" if (((iter != NULL) && (iter->Kind == Amalgame_Compiler_NodeKind_BINARY)) && (code_string_equals(iter->Str, ".."))) { #line 5282 "./src/generator/c_gen.am" isRange = 1; } #line 5286 "./src/generator/c_gen.am" code_string loopHeader = ""; #line 5287 "./src/generator/c_gen.am" if (isRange) { #line 5288 "./src/generator/c_gen.am" code_string startStr = Amalgame_Compiler_CGen_EmitExprStr(self, iter->Left); #line 5289 "./src/generator/c_gen.am" code_string endStr = Amalgame_Compiler_CGen_EmitExprStr(self, iter->Right); #line 5290 "./src/generator/c_gen.am" loopHeader = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("for (i64 ", vn)), " = ")), startStr)), "; ")), vn)), " < ")), endStr)), "; ")), vn)), "++) { ")); #line 5291 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, vn, "i64"); } else { #line 5293 "./src/generator/c_gen.am" code_string iterStr = Amalgame_Compiler_CGen_EmitExprStr(self, iter); #line 5294 "./src/generator/c_gen.am" loopHeader = (code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList* __it_", vn)), " = ")), iterStr)), "; ")); #line 5295 "./src/generator/c_gen.am" loopHeader = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(loopHeader, "i64 __n_")), vn)), " = AmalgameList_size(__it_")), vn)), "); ")); #line 5296 "./src/generator/c_gen.am" loopHeader = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(loopHeader, "for (i64 __i_")), vn)), " = 0; __i_")), vn)), " < __n_")), vn)), "; __i_")), vn)), "++) { ")); #line 5297 "./src/generator/c_gen.am" loopHeader = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(loopHeader, "void* ")), vn)), " = __it_")), vn)), "->data[__i_")), vn)), "]; ")); #line 5298 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, vn, "void*"); } #line 5301 "./src/generator/c_gen.am" code_string projStr = Amalgame_Compiler_CGen_EmitExprStr(self, n->Left); #line 5302 "./src/generator/c_gen.am" code_string guardStr = ""; #line 5303 "./src/generator/c_gen.am" if (n->Cond != NULL) { #line 5304 "./src/generator/c_gen.am" guardStr = (code_string_concat((code_string_concat("if (", Amalgame_Compiler_CGen_EmitExprStr(self, n->Cond))), ") ")); } #line 5306 "./src/generator/c_gen.am" Amalgame_Compiler_CGen_LocalTypeSet(self, vn, ""); #line 5307 "./src/generator/c_gen.am" code_string s = code_string_concat((code_string_concat("({ AmalgameList* __lc_", vn)), " = AmalgameList_new(); "); #line 5308 "./src/generator/c_gen.am" s = (code_string_concat(s, loopHeader)); #line 5309 "./src/generator/c_gen.am" s = (code_string_concat(s, guardStr)); #line 5310 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "AmalgameList_add(__lc_")), vn)), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, projStr))), "); ")); #line 5311 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "} __lc_")), vn)), "; })")); #line 5312 "./src/generator/c_gen.am" return s; } static code_string Amalgame_Compiler_CGen_TryEmitListCall(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* callExpr) { #line 5325 "./src/generator/c_gen.am" if (callExpr->Left == NULL) { return ""; } #line 5326 "./src/generator/c_gen.am" if (callExpr->Left->Kind != Amalgame_Compiler_NodeKind_MEMBER) { return ""; } #line 5327 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* callee = callExpr->Left; #line 5328 "./src/generator/c_gen.am" code_string mname = callee->Name; #line 5337 "./src/generator/c_gen.am" code_string rxExpr = ""; #line 5338 "./src/generator/c_gen.am" code_string rxType = ""; #line 5339 "./src/generator/c_gen.am" code_string rxElem = ""; #line 5340 "./src/generator/c_gen.am" if (callee->Left != NULL) { #line 5341 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind rk = callee->Left->Kind; #line 5342 "./src/generator/c_gen.am" if (rk == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 5343 "./src/generator/c_gen.am" rxExpr = callee->Left->Name; #line 5344 "./src/generator/c_gen.am" rxType = Amalgame_Compiler_CGen_LocalTypeGet(self, rxExpr); #line 5345 "./src/generator/c_gen.am" rxElem = (code_string_concat("__local_map__.", rxExpr)); } #line 5347 "./src/generator/c_gen.am" if ((rk == Amalgame_Compiler_NodeKind_MEMBER) && (callee->Left->Left != NULL)) { #line 5348 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind pk = callee->Left->Left->Kind; #line 5349 "./src/generator/c_gen.am" if (pk == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 5350 "./src/generator/c_gen.am" code_string fn = callee->Left->Name; #line 5351 "./src/generator/c_gen.am" rxExpr = (code_string_concat("self->", fn)); #line 5352 "./src/generator/c_gen.am" rxType = Amalgame_Compiler_CGen_FieldTypeGet(self, self->CurrentClass, fn); #line 5353 "./src/generator/c_gen.am" rxElem = (code_string_concat((code_string_concat(self->CurrentClass, ".")), fn)); } #line 5355 "./src/generator/c_gen.am" if (pk == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 5356 "./src/generator/c_gen.am" code_string vn = callee->Left->Left->Name; #line 5357 "./src/generator/c_gen.am" code_string vt = Amalgame_Compiler_CGen_LocalTypeGet(self, vn); #line 5358 "./src/generator/c_gen.am" code_string bn = String_Replace(vt, "*", ""); #line 5359 "./src/generator/c_gen.am" code_string fn = callee->Left->Name; #line 5360 "./src/generator/c_gen.am" if (String_Length(bn) > 0LL) { #line 5361 "./src/generator/c_gen.am" rxExpr = (code_string_concat((code_string_concat(vn, "->")), fn)); #line 5362 "./src/generator/c_gen.am" rxType = Amalgame_Compiler_CGen_FieldTypeGet(self, bn, fn); #line 5363 "./src/generator/c_gen.am" rxElem = (code_string_concat((code_string_concat(bn, ".")), fn)); } } } } #line 5379 "./src/generator/c_gen.am" if (((String_Length(rxExpr) == 0LL) && (callee->Left != NULL)) && (callee->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER)) { #line 5380 "./src/generator/c_gen.am" code_string deepT = Amalgame_Compiler_CGen_InferTypeFromExpr(self, callee->Left); #line 5381 "./src/generator/c_gen.am" if (((code_string_equals(deepT, "AmalgameMap*")) || (code_string_equals(deepT, "AmalgameSet*"))) || (code_string_equals(deepT, "AmalgameList*"))) { #line 5382 "./src/generator/c_gen.am" rxExpr = Amalgame_Compiler_CGen_EmitExprStr(self, callee->Left); #line 5383 "./src/generator/c_gen.am" rxType = deepT; } } #line 5389 "./src/generator/c_gen.am" if ((code_string_equals(mname, "Keys")) || (code_string_equals(mname, "Values"))) { #line 5390 "./src/generator/c_gen.am" if (code_string_equals(rxType, "AmalgameMap*")) { #line 5391 "./src/generator/c_gen.am" if (code_string_equals(mname, "Keys")) { return code_string_concat((code_string_concat("AmalgameMap_keys(", rxExpr)), ")"); } #line 5392 "./src/generator/c_gen.am" if (code_string_equals(mname, "Values")) { return code_string_concat((code_string_concat("AmalgameMap_values(", rxExpr)), ")"); } } } #line 5395 "./src/generator/c_gen.am" if (((((code_string_equals(mname, "Set")) || (code_string_equals(mname, "Has"))) || (code_string_equals(mname, "Size"))) || (code_string_equals(mname, "Remove"))) || (code_string_equals(mname, "Get"))) { #line 5396 "./src/generator/c_gen.am" if (code_string_equals(rxType, "AmalgameMap*")) { #line 5397 "./src/generator/c_gen.am" AmalgameList* args = callExpr->Args; #line 5398 "./src/generator/c_gen.am" i64 ac = AmalgameList_count(args); #line 5399 "./src/generator/c_gen.am" if ((code_string_equals(mname, "Set")) && (ac >= 2LL)) { #line 5400 "./src/generator/c_gen.am" code_string k2 = Amalgame_Compiler_CGen_EmitExprStr(self, (void*)AmalgameList_get(args, 0LL)); #line 5401 "./src/generator/c_gen.am" code_string v2 = Amalgame_Compiler_CGen_EmitExprStr(self, (void*)AmalgameList_get(args, 1LL)); #line 5402 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameMap_set(", rxExpr)), ", ")), k2)), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, v2))), ")"); } #line 5404 "./src/generator/c_gen.am" if ((code_string_equals(mname, "Has")) && (ac >= 1LL)) { #line 5405 "./src/generator/c_gen.am" code_string k2 = Amalgame_Compiler_CGen_EmitExprStr(self, (void*)AmalgameList_get(args, 0LL)); #line 5406 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameMap_has(", rxExpr)), ", ")), k2)), ")"); } #line 5408 "./src/generator/c_gen.am" if (code_string_equals(mname, "Size")) { return code_string_concat((code_string_concat("AmalgameMap_size(", rxExpr)), ")"); } #line 5409 "./src/generator/c_gen.am" if ((code_string_equals(mname, "Remove")) && (ac >= 1LL)) { #line 5410 "./src/generator/c_gen.am" code_string k2 = Amalgame_Compiler_CGen_EmitExprStr(self, (void*)AmalgameList_get(args, 0LL)); #line 5411 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameMap_remove(", rxExpr)), ", ")), k2)), ")"); } #line 5413 "./src/generator/c_gen.am" if ((code_string_equals(mname, "Get")) && (ac >= 1LL)) { #line 5414 "./src/generator/c_gen.am" code_string k2 = Amalgame_Compiler_CGen_EmitExprStr(self, (void*)AmalgameList_get(args, 0LL)); #line 5419 "./src/generator/c_gen.am" code_string castT = ""; #line 5420 "./src/generator/c_gen.am" i64 dotPos = String_IndexOf(rxElem, "."); #line 5421 "./src/generator/c_gen.am" if (dotPos > 0LL) { #line 5422 "./src/generator/c_gen.am" code_string nsPart = String_Substring(rxElem, 0LL, dotPos); #line 5423 "./src/generator/c_gen.am" code_string kPart = String_Substring(rxElem, dotPos + 1LL, (String_Length(rxElem) - dotPos) - 1LL); #line 5424 "./src/generator/c_gen.am" castT = Amalgame_Compiler_CGen_ListElemGet(self, nsPart, kPart); } #line 5426 "./src/generator/c_gen.am" if (String_Length(castT) == 0LL) { castT = "void*"; } #line 5427 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", castT)), ")AmalgameMap_get(")), rxExpr)), ", ")), k2)), ")"); } } } #line 5432 "./src/generator/c_gen.am" if ((code_string_equals(mname, "Contains")) || (code_string_equals(mname, "Size"))) { #line 5433 "./src/generator/c_gen.am" if (code_string_equals(rxType, "AmalgameSet*")) { #line 5434 "./src/generator/c_gen.am" AmalgameList* args = callExpr->Args; #line 5435 "./src/generator/c_gen.am" i64 ac = AmalgameList_count(args); #line 5436 "./src/generator/c_gen.am" if ((code_string_equals(mname, "Contains")) && (ac >= 1LL)) { #line 5437 "./src/generator/c_gen.am" code_string v2 = Amalgame_Compiler_CGen_EmitExprStr(self, (void*)AmalgameList_get(args, 0LL)); #line 5438 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameSet_contains(", rxExpr)), ", ")), v2)), ")"); } #line 5440 "./src/generator/c_gen.am" if (code_string_equals(mname, "Size")) { return code_string_concat((code_string_concat("AmalgameSet_size(", rxExpr)), ")"); } } } #line 5443 "./src/generator/c_gen.am" if ((code_string_equals(mname, "Add")) || (code_string_equals(mname, "Remove"))) { #line 5444 "./src/generator/c_gen.am" if (code_string_equals(rxType, "AmalgameSet*")) { #line 5445 "./src/generator/c_gen.am" AmalgameList* args = callExpr->Args; #line 5446 "./src/generator/c_gen.am" i64 ac = AmalgameList_count(args); #line 5447 "./src/generator/c_gen.am" if (ac >= 1LL) { #line 5448 "./src/generator/c_gen.am" code_string v2 = Amalgame_Compiler_CGen_EmitExprStr(self, (void*)AmalgameList_get(args, 0LL)); #line 5449 "./src/generator/c_gen.am" if (code_string_equals(mname, "Add")) { return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameSet_add(", rxExpr)), ", ")), v2)), ")"); } #line 5450 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameSet_remove(", rxExpr)), ", ")), v2)), ")"); } } } #line 5455 "./src/generator/c_gen.am" if ((((((((((((((((!code_string_equals(mname, "Add")) && (!code_string_equals(mname, "Set"))) && (!code_string_equals(mname, "Count"))) && (!code_string_equals(mname, "Get"))) && (!code_string_equals(mname, "IsEmpty"))) && (!code_string_equals(mname, "Remove"))) && (!code_string_equals(mname, "RemoveAt"))) && (!code_string_equals(mname, "Clear"))) && (!code_string_equals(mname, "Reserve"))) && (!code_string_equals(mname, "Filter"))) && (!code_string_equals(mname, "Map"))) && (!code_string_equals(mname, "Reduce"))) && (!code_string_equals(mname, "ForEach"))) && (!code_string_equals(mname, "Any"))) && (!code_string_equals(mname, "All"))) && (!code_string_equals(mname, "CountIf"))) { return ""; } #line 5458 "./src/generator/c_gen.am" code_string listExpr = ""; #line 5459 "./src/generator/c_gen.am" code_string listCType = ""; #line 5461 "./src/generator/c_gen.am" if (callee->Left != NULL) { #line 5462 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind lk = callee->Left->Kind; #line 5465 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 5466 "./src/generator/c_gen.am" code_string vname = callee->Left->Name; #line 5467 "./src/generator/c_gen.am" code_string vtype = Amalgame_Compiler_CGen_LocalTypeGet(self, vname); #line 5468 "./src/generator/c_gen.am" if (code_string_equals(vtype, "AmalgameList*")) { #line 5469 "./src/generator/c_gen.am" listExpr = vname; #line 5470 "./src/generator/c_gen.am" listCType = "AmalgameList*"; } } #line 5478 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_CALL) { #line 5479 "./src/generator/c_gen.am" code_string innerStr = Amalgame_Compiler_CGen_TryEmitListCall(self, callee->Left); #line 5480 "./src/generator/c_gen.am" if (String_Length(innerStr) > 0LL) { #line 5481 "./src/generator/c_gen.am" listExpr = innerStr; #line 5482 "./src/generator/c_gen.am" listCType = "AmalgameList*"; } } #line 5487 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_MEMBER) { #line 5488 "./src/generator/c_gen.am" if (callee->Left->Left != NULL) { #line 5489 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind llk = callee->Left->Left->Kind; #line 5490 "./src/generator/c_gen.am" if (llk == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 5491 "./src/generator/c_gen.am" code_string fname = callee->Left->Name; #line 5492 "./src/generator/c_gen.am" code_string ftype = Amalgame_Compiler_CGen_FieldTypeGet(self, self->CurrentClass, fname); #line 5493 "./src/generator/c_gen.am" if (code_string_equals(ftype, "AmalgameList*")) { #line 5494 "./src/generator/c_gen.am" listExpr = (code_string_concat("self->", fname)); #line 5495 "./src/generator/c_gen.am" listCType = "AmalgameList*"; } } #line 5499 "./src/generator/c_gen.am" if (llk == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 5500 "./src/generator/c_gen.am" code_string vname2 = callee->Left->Left->Name; #line 5501 "./src/generator/c_gen.am" code_string vtype2 = Amalgame_Compiler_CGen_LocalTypeGet(self, vname2); #line 5502 "./src/generator/c_gen.am" code_string fname2 = callee->Left->Name; #line 5504 "./src/generator/c_gen.am" code_string vbare = String_Replace(vtype2, "*", ""); #line 5505 "./src/generator/c_gen.am" code_string ftype2 = Amalgame_Compiler_CGen_FieldTypeGet(self, vbare, fname2); #line 5506 "./src/generator/c_gen.am" if (code_string_equals(ftype2, "AmalgameList*")) { #line 5507 "./src/generator/c_gen.am" listExpr = (code_string_concat((code_string_concat(vname2, "->")), fname2)); #line 5508 "./src/generator/c_gen.am" listCType = "AmalgameList*"; } } } } } #line 5521 "./src/generator/c_gen.am" if (((String_Length(listExpr) == 0LL) && (code_string_equals(rxType, "AmalgameList*"))) && (String_Length(rxExpr) > 0LL)) { #line 5522 "./src/generator/c_gen.am" listExpr = rxExpr; #line 5523 "./src/generator/c_gen.am" listCType = "AmalgameList*"; } #line 5526 "./src/generator/c_gen.am" if (String_Length(listExpr) == 0LL) { return ""; } #line 5529 "./src/generator/c_gen.am" if (code_string_equals(mname, "Clear")) { #line 5530 "./src/generator/c_gen.am" return code_string_concat((code_string_concat("AmalgameList_clear(", listExpr)), ")"); } #line 5532 "./src/generator/c_gen.am" if (code_string_equals(mname, "Reserve")) { #line 5533 "./src/generator/c_gen.am" code_string arg0 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5534 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_reserve(", listExpr)), ", ")), arg0)), ")"); } #line 5536 "./src/generator/c_gen.am" if (code_string_equals(mname, "Count")) { #line 5537 "./src/generator/c_gen.am" return code_string_concat((code_string_concat("AmalgameList_count(", listExpr)), ")"); } #line 5539 "./src/generator/c_gen.am" if (code_string_equals(mname, "Add")) { #line 5540 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(callExpr->Args); #line 5541 "./src/generator/c_gen.am" if (argc == 0LL) { return code_string_concat((code_string_concat("AmalgameList_add(", listExpr)), ", NULL)"); } #line 5544 "./src/generator/c_gen.am" code_string elemA = Amalgame_Compiler_CGen_ResolveListElemC(self, callee); #line 5545 "./src/generator/c_gen.am" if ((String_Length(elemA) > 0LL) && Amalgame_Compiler_CGen_IsInterface(self, elemA)) { #line 5546 "./src/generator/c_gen.am" code_string im = Amalgame_Compiler_CGen_IfaceMangledFor(self, elemA); #line 5547 "./src/generator/c_gen.am" code_string fat = Amalgame_Compiler_CGen_CoerceToIface(self, im, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5548 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_add(", listExpr)), ", ")), Amalgame_Compiler_CGen_BoxIface(self, im, fat))), ")"); } #line 5550 "./src/generator/c_gen.am" code_string arg0 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5551 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_add(", listExpr)), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg0))), ")"); } #line 5553 "./src/generator/c_gen.am" if (code_string_equals(mname, "Set")) { #line 5556 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(callExpr->Args); #line 5557 "./src/generator/c_gen.am" if (argc < 2LL) { return ""; } #line 5558 "./src/generator/c_gen.am" code_string idxArg = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5559 "./src/generator/c_gen.am" code_string elemS = Amalgame_Compiler_CGen_ResolveListElemC(self, callee); #line 5560 "./src/generator/c_gen.am" if ((String_Length(elemS) > 0LL) && Amalgame_Compiler_CGen_IsInterface(self, elemS)) { #line 5561 "./src/generator/c_gen.am" code_string im = Amalgame_Compiler_CGen_IfaceMangledFor(self, elemS); #line 5562 "./src/generator/c_gen.am" code_string fat = Amalgame_Compiler_CGen_CoerceToIface(self, im, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 1LL)); #line 5563 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_set(", listExpr)), ", ")), idxArg)), ", ")), Amalgame_Compiler_CGen_BoxIface(self, im, fat))), ")"); } #line 5565 "./src/generator/c_gen.am" code_string valArg = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 1LL)); #line 5566 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_set(", listExpr)), ", ")), idxArg)), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, valArg))), ")"); } #line 5568 "./src/generator/c_gen.am" if (code_string_equals(mname, "Get")) { #line 5569 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(callExpr->Args); #line 5570 "./src/generator/c_gen.am" code_string idx0 = "0"; #line 5571 "./src/generator/c_gen.am" if (argc > 0LL) { idx0 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); } #line 5573 "./src/generator/c_gen.am" code_string elemType = ""; #line 5574 "./src/generator/c_gen.am" if (callee->Left != NULL) { #line 5575 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind lkG = callee->Left->Kind; #line 5577 "./src/generator/c_gen.am" if (lkG == Amalgame_Compiler_NodeKind_THIS_EXPR) { } #line 5581 "./src/generator/c_gen.am" if (lkG == Amalgame_Compiler_NodeKind_MEMBER) { #line 5582 "./src/generator/c_gen.am" if (callee->Left->Left != NULL) { #line 5583 "./src/generator/c_gen.am" Amalgame_Compiler_AstNode* lll = callee->Left->Left; #line 5585 "./src/generator/c_gen.am" if (lll->Kind == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 5586 "./src/generator/c_gen.am" code_string fn4 = callee->Left->Name; #line 5587 "./src/generator/c_gen.am" elemType = Amalgame_Compiler_CGen_ListElemGet(self, self->CurrentClass, fn4); } #line 5590 "./src/generator/c_gen.am" if (lll->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 5591 "./src/generator/c_gen.am" code_string vn4 = lll->Name; #line 5592 "./src/generator/c_gen.am" code_string vt4 = Amalgame_Compiler_CGen_LocalTypeGet(self, vn4); #line 5593 "./src/generator/c_gen.am" code_string bare4 = String_Replace(vt4, "*", ""); #line 5594 "./src/generator/c_gen.am" code_string fn4b = callee->Left->Name; #line 5595 "./src/generator/c_gen.am" elemType = Amalgame_Compiler_CGen_ListElemGet(self, bare4, fn4b); } } } #line 5601 "./src/generator/c_gen.am" if (lkG == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 5602 "./src/generator/c_gen.am" code_string vn5 = callee->Left->Name; #line 5603 "./src/generator/c_gen.am" elemType = Amalgame_Compiler_CGen_ListElemGet(self, "__local__", vn5); } #line 5610 "./src/generator/c_gen.am" if ((lkG == Amalgame_Compiler_NodeKind_CALL) && (String_Length(elemType) == 0LL)) { #line 5611 "./src/generator/c_gen.am" code_string chainedRaw = Amalgame_Compiler_CGen_RecoverChainedListElemRaw(self, callee->Left); #line 5612 "./src/generator/c_gen.am" if (String_Length(chainedRaw) > 0LL) { #line 5613 "./src/generator/c_gen.am" elemType = Amalgame_Compiler_CGen_TypeToC(self, chainedRaw); } } } #line 5617 "./src/generator/c_gen.am" if (String_Length(elemType) > 0LL) { #line 5620 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsInterface(self, elemType)) { #line 5621 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("(*(", elemType)), "*)AmalgameList_get(")), listExpr)), ", ")), idx0)), "))"); } #line 5629 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsCPointerType(self, elemType)) { #line 5630 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("(", elemType)), ")AmalgameList_get(")), listExpr)), ", ")), idx0)), ")"); } #line 5632 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_UnboxScalar(self, elemType, code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_get(", listExpr)), ", ")), idx0)), ")")); } #line 5634 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("(void*)AmalgameList_get(", listExpr)), ", ")), idx0)), ")"); } #line 5636 "./src/generator/c_gen.am" if (code_string_equals(mname, "IsEmpty")) { #line 5637 "./src/generator/c_gen.am" return code_string_concat((code_string_concat("AmalgameList_isEmpty(", listExpr)), ")"); } #line 5639 "./src/generator/c_gen.am" if (code_string_equals(mname, "Remove")) { #line 5640 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(callExpr->Args); #line 5641 "./src/generator/c_gen.am" if (argc > 0LL) { #line 5642 "./src/generator/c_gen.am" code_string arg0 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5643 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_remove(", listExpr)), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, arg0))), ")"); } } #line 5646 "./src/generator/c_gen.am" if (code_string_equals(mname, "RemoveAt")) { #line 5647 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(callExpr->Args); #line 5648 "./src/generator/c_gen.am" if (argc > 0LL) { #line 5649 "./src/generator/c_gen.am" code_string arg0 = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5650 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_removeAt(", listExpr)), ", ")), arg0)), ")"); } } #line 5659 "./src/generator/c_gen.am" if (code_string_equals(mname, "Filter")) { #line 5660 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(callExpr->Args); #line 5661 "./src/generator/c_gen.am" if (argc != 1LL) { return ""; } #line 5662 "./src/generator/c_gen.am" code_string lamStr = Amalgame_Compiler_CGen_EmitClosureArg(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5663 "./src/generator/c_gen.am" if (String_Length(lamStr) == 0LL) { return ""; } #line 5664 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_filter(", listExpr)), ", ")), lamStr)), ")"); } #line 5666 "./src/generator/c_gen.am" if (code_string_equals(mname, "Map")) { #line 5667 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(callExpr->Args); #line 5668 "./src/generator/c_gen.am" if (argc != 1LL) { return ""; } #line 5669 "./src/generator/c_gen.am" code_string lamStr = Amalgame_Compiler_CGen_EmitClosureArg(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5670 "./src/generator/c_gen.am" if (String_Length(lamStr) == 0LL) { return ""; } #line 5671 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_map(", listExpr)), ", ")), lamStr)), ")"); } #line 5673 "./src/generator/c_gen.am" if (code_string_equals(mname, "ForEach")) { #line 5674 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(callExpr->Args); #line 5675 "./src/generator/c_gen.am" if (argc != 1LL) { return ""; } #line 5676 "./src/generator/c_gen.am" code_string lamStr = Amalgame_Compiler_CGen_EmitClosureArg(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5677 "./src/generator/c_gen.am" if (String_Length(lamStr) == 0LL) { return ""; } #line 5678 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_forEach(", listExpr)), ", ")), lamStr)), ")"); } #line 5680 "./src/generator/c_gen.am" if (code_string_equals(mname, "Reduce")) { #line 5682 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(callExpr->Args); #line 5683 "./src/generator/c_gen.am" if (argc != 2LL) { return ""; } #line 5684 "./src/generator/c_gen.am" code_string initStr = Amalgame_Compiler_CGen_EmitExprStr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5685 "./src/generator/c_gen.am" code_string lamStr = Amalgame_Compiler_CGen_EmitClosureArg(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 1LL)); #line 5686 "./src/generator/c_gen.am" if (String_Length(lamStr) == 0LL) { return ""; } #line 5687 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_UnboxScalar(self, "i64", code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_reduce(", listExpr)), ", ")), Amalgame_Compiler_CGen_BoxAsVoid(self, initStr))), ", ")), lamStr)), ")")); } #line 5689 "./src/generator/c_gen.am" if (code_string_equals(mname, "Any")) { #line 5690 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(callExpr->Args); #line 5691 "./src/generator/c_gen.am" if (argc != 1LL) { return ""; } #line 5692 "./src/generator/c_gen.am" code_string lamStr = Amalgame_Compiler_CGen_EmitClosureArg(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5693 "./src/generator/c_gen.am" if (String_Length(lamStr) == 0LL) { return ""; } #line 5694 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_any(", listExpr)), ", ")), lamStr)), ")"); } #line 5696 "./src/generator/c_gen.am" if (code_string_equals(mname, "All")) { #line 5697 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(callExpr->Args); #line 5698 "./src/generator/c_gen.am" if (argc != 1LL) { return ""; } #line 5699 "./src/generator/c_gen.am" code_string lamStr = Amalgame_Compiler_CGen_EmitClosureArg(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5700 "./src/generator/c_gen.am" if (String_Length(lamStr) == 0LL) { return ""; } #line 5701 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_all(", listExpr)), ", ")), lamStr)), ")"); } #line 5703 "./src/generator/c_gen.am" if (code_string_equals(mname, "CountIf")) { #line 5704 "./src/generator/c_gen.am" i64 argc = AmalgameList_count(callExpr->Args); #line 5705 "./src/generator/c_gen.am" if (argc != 1LL) { return ""; } #line 5706 "./src/generator/c_gen.am" code_string lamStr = Amalgame_Compiler_CGen_EmitClosureArg(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(callExpr->Args, 0LL)); #line 5707 "./src/generator/c_gen.am" if (String_Length(lamStr) == 0LL) { return ""; } #line 5708 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("AmalgameList_countIf(", listExpr)), ", ")), lamStr)), ")"); } #line 5710 "./src/generator/c_gen.am" return ""; } static code_string Amalgame_Compiler_CGen_EmitClosureArg(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* arg) { #line 5720 "./src/generator/c_gen.am" if (arg == NULL) { return ""; } #line 5721 "./src/generator/c_gen.am" if ((arg->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) && (code_string_equals(arg->Name, "__lambda__"))) { #line 5722 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_EmitLambdaAsClosure(self, arg); } #line 5724 "./src/generator/c_gen.am" if (arg->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 5725 "./src/generator/c_gen.am" code_string t = Amalgame_Compiler_CGen_LocalTypeGet(self, arg->Name); #line 5726 "./src/generator/c_gen.am" if (code_string_equals(t, "AmalgameClosure*")) { return arg->Name; } } #line 5728 "./src/generator/c_gen.am" return ""; } static code_string Amalgame_Compiler_CGen_EmitLambdaAsClosure(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* lam) { #line 5735 "./src/generator/c_gen.am" code_string id = lam->Str2; #line 5736 "./src/generator/c_gen.am" code_string envName = code_string_concat("LamEnv_", id); #line 5737 "./src/generator/c_gen.am" code_string fnName = code_string_concat((code_string_concat("lam_", id)), "_fn"); #line 5738 "./src/generator/c_gen.am" code_string envVar = code_string_concat("__env_", id); #line 5739 "./src/generator/c_gen.am" i64 cn = AmalgameList_count(lam->Args); #line 5740 "./src/generator/c_gen.am" code_string s = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("({ ", envName)), "* ")), envVar)), " = (")), envName)), "*)code_alloc(sizeof(")), envName)), ")); "); #line 5741 "./src/generator/c_gen.am" for (i64 i = 0LL; i < cn; i++) { #line 5742 "./src/generator/c_gen.am" s = (code_string_concat(s, Amalgame_Compiler_CGen_EmitLambdaCaptureCopy(self, envVar, (Amalgame_Compiler_AstNode*)AmalgameList_get(lam->Args, i)))); } #line 5744 "./src/generator/c_gen.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "AmalgameClosure_new((void*)")), fnName)), ", ")), envVar)), "); })")); #line 5745 "./src/generator/c_gen.am" return s; } static code_string Amalgame_Compiler_CGen_EmitLambdaCaptureCopy(Amalgame_Compiler_CGen* self, code_string envVar, Amalgame_Compiler_AstNode* cap) { #line 5752 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(envVar, "->_")), cap->Name)), " = ")), cap->Name)), "; "); } static code_string Amalgame_Compiler_CGen_EmitCalleeStr(Amalgame_Compiler_CGen* self, Amalgame_Compiler_AstNode* callee) { #line 5756 "./src/generator/c_gen.am" if (callee == NULL) { return "NULL"; } #line 5757 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind k = callee->Kind; #line 5758 "./src/generator/c_gen.am" if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { return callee->Name; } #line 5759 "./src/generator/c_gen.am" if (k == Amalgame_Compiler_NodeKind_MEMBER) { #line 5760 "./src/generator/c_gen.am" code_string mname = callee->Name; #line 5761 "./src/generator/c_gen.am" if (callee->Left != NULL) { #line 5762 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind lk = callee->Left->Kind; #line 5763 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 5765 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(self->CurrentClass, "_")), mname); } #line 5768 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_LITERAL_STRING) { #line 5769 "./src/generator/c_gen.am" return code_string_concat("String_", mname); } #line 5771 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 5772 "./src/generator/c_gen.am" code_string tname = callee->Left->Name; #line 5773 "./src/generator/c_gen.am" code_string firstChar = String_Substring(tname, 0LL, 1LL); #line 5774 "./src/generator/c_gen.am" code_bool isUpper = code_string_equals(firstChar, String_ToUpper(firstChar)); #line 5775 "./src/generator/c_gen.am" if (isUpper) { #line 5783 "./src/generator/c_gen.am" if (code_string_equals(tname, "Path")) { #line 5784 "./src/generator/c_gen.am" if ((((code_string_equals(mname, "Combine")) || (code_string_equals(mname, "Sep"))) || (code_string_equals(mname, "IsAbsolute"))) || (code_string_equals(mname, "Normalize"))) { #line 5785 "./src/generator/c_gen.am" return code_string_concat("Path_", mname); } } #line 5793 "./src/generator/c_gen.am" code_string externalMangled = Amalgame_Compiler_CGen_ExternalClassMangled(self, tname); #line 5794 "./src/generator/c_gen.am" if (String_Length(externalMangled) > 0LL) { #line 5795 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(externalMangled, "_")), mname); } #line 5801 "./src/generator/c_gen.am" code_string externalEnumMangled = Amalgame_Compiler_CGen_ExternalEnumMangled(self, tname); #line 5802 "./src/generator/c_gen.am" if (String_Length(externalEnumMangled) > 0LL) { #line 5803 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(externalEnumMangled, "_")), mname); } #line 5816 "./src/generator/c_gen.am" code_bool isCoreStdlib = (((((((((code_string_equals(tname, "Console")) || (code_string_equals(tname, "Mcu"))) || (code_string_equals(tname, "File"))) || (code_string_equals(tname, "String"))) || (code_string_equals(tname, "List"))) || (code_string_equals(tname, "Env"))) || (code_string_equals(tname, "Process"))) || (code_string_equals(tname, "Regex"))) || (code_string_equals(tname, "Compress"))) || (code_string_equals(tname, "WebSocket")); #line 5817 "./src/generator/c_gen.am" if (isCoreStdlib) { #line 5818 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(tname, "_")), mname); } #line 5833 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsLocalClass(self, tname)) { #line 5834 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(Amalgame_Compiler_CGen_SymName(self, tname), "_")), mname); } #line 5840 "./src/generator/c_gen.am" code_string mangledPrefix = Amalgame_Compiler_CGen_PkgClassMangledPrefix(self, tname); #line 5841 "./src/generator/c_gen.am" if (String_Length(mangledPrefix) > 0LL) { #line 5842 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(mangledPrefix, "_")), mname); } #line 5845 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(Amalgame_Compiler_CGen_SymName(self, tname), "_")), mname); } #line 5848 "./src/generator/c_gen.am" code_string varType = Amalgame_Compiler_CGen_LocalTypeGet(self, tname); #line 5849 "./src/generator/c_gen.am" code_string bareType = String_Replace(varType, "*", ""); #line 5850 "./src/generator/c_gen.am" if (String_Length(bareType) > 0LL) { #line 5861 "./src/generator/c_gen.am" if (code_string_equals(bareType, "void")) { #line 5862 "./src/generator/c_gen.am" code_bool isListM = (((((((code_string_equals(mname, "Get")) || (code_string_equals(mname, "Count"))) || (code_string_equals(mname, "Size"))) || (code_string_equals(mname, "Add"))) || (code_string_equals(mname, "Remove"))) || (code_string_equals(mname, "Clear"))) || (code_string_equals(mname, "IndexOf"))) || (code_string_equals(mname, "Contains")); #line 5863 "./src/generator/c_gen.am" if (isListM) { #line 5864 "./src/generator/c_gen.am" code_string mfirst = String_Substring(mname, 0LL, 1LL); #line 5865 "./src/generator/c_gen.am" code_string mrest = String_Substring(mname, 1LL, String_Length(mname) - 1LL); #line 5866 "./src/generator/c_gen.am" return code_string_concat((code_string_concat("AmalgameList_", String_ToLower(mfirst))), mrest); } } #line 5875 "./src/generator/c_gen.am" if (code_string_equals(bareType, "AmalgameWebSocket")) { #line 5876 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(String_Replace(bareType, "Amalgame", ""), "_")), mname); } #line 5879 "./src/generator/c_gen.am" if (code_string_equals(bareType, "AmalgameRegexMatch")) { #line 5880 "./src/generator/c_gen.am" return code_string_concat("Match_", mname); } #line 5888 "./src/generator/c_gen.am" if (code_string_equals(bareType, "code_string")) { #line 5889 "./src/generator/c_gen.am" return code_string_concat("String_", mname); } #line 5897 "./src/generator/c_gen.am" if (code_string_equals(mname, "ToString")) { #line 5898 "./src/generator/c_gen.am" if (code_string_equals(bareType, "i64")) { return "String_FromInt"; } #line 5899 "./src/generator/c_gen.am" if (code_string_equals(bareType, "double")) { return "String_FromFloat"; } #line 5900 "./src/generator/c_gen.am" if (code_string_equals(bareType, "code_bool")) { return "String_FromBool"; } } #line 5902 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(bareType, "_")), mname); } #line 5905 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(tname, "_")), mname); } #line 5912 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_CALL) { #line 5913 "./src/generator/c_gen.am" code_string retT = Amalgame_Compiler_CGen_InferTypeFromExpr(self, callee->Left); #line 5914 "./src/generator/c_gen.am" code_string bareR = String_Replace(retT, "*", ""); #line 5915 "./src/generator/c_gen.am" if (String_Length(bareR) > 0LL) { #line 5921 "./src/generator/c_gen.am" if (((code_string_equals(bareR, "AmalgameList")) || (code_string_equals(bareR, "AmalgameMap"))) || (code_string_equals(bareR, "AmalgameSet"))) { #line 5922 "./src/generator/c_gen.am" code_string first = String_Substring(mname, 0LL, 1LL); #line 5923 "./src/generator/c_gen.am" code_string rest = String_Substring(mname, 1LL, String_Length(mname) - 1LL); #line 5924 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat(bareR, "_")), String_ToLower(first))), rest); } #line 5929 "./src/generator/c_gen.am" if (code_string_equals(mname, "ToString")) { #line 5930 "./src/generator/c_gen.am" if (code_string_equals(bareR, "i64")) { return "String_FromInt"; } #line 5931 "./src/generator/c_gen.am" if (code_string_equals(bareR, "double")) { return "String_FromFloat"; } #line 5932 "./src/generator/c_gen.am" if (code_string_equals(bareR, "code_bool")) { return "String_FromBool"; } } #line 5934 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(bareR, "_")), mname); } } #line 5943 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_CALL) { #line 5944 "./src/generator/c_gen.am" code_string rt = Amalgame_Compiler_CGen_InferTypeFromExpr(self, callee->Left); #line 5945 "./src/generator/c_gen.am" code_string bare = String_Replace(rt, "*", ""); #line 5946 "./src/generator/c_gen.am" if (String_Length(bare) > 0LL) { #line 5947 "./src/generator/c_gen.am" if (((code_string_equals(bare, "AmalgameList")) || (code_string_equals(bare, "AmalgameMap"))) || (code_string_equals(bare, "AmalgameSet"))) { #line 5948 "./src/generator/c_gen.am" code_string first = String_Substring(mname, 0LL, 1LL); #line 5949 "./src/generator/c_gen.am" code_string rest = String_Substring(mname, 1LL, String_Length(mname) - 1LL); #line 5950 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat(bare, "_")), String_ToLower(first))), rest); } #line 5952 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(bare, "_")), mname); } } #line 5963 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 5964 "./src/generator/c_gen.am" code_string tname = callee->Left->Name; #line 5965 "./src/generator/c_gen.am" code_string externalMangled = Amalgame_Compiler_CGen_ExternalClassMangled(self, tname); #line 5966 "./src/generator/c_gen.am" if (String_Length(externalMangled) > 0LL) { #line 5967 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(externalMangled, "_")), mname); } #line 5969 "./src/generator/c_gen.am" code_bool isCoreStdlib = (((((((((code_string_equals(tname, "Console")) || (code_string_equals(tname, "Mcu"))) || (code_string_equals(tname, "File"))) || (code_string_equals(tname, "String"))) || (code_string_equals(tname, "List"))) || (code_string_equals(tname, "Env"))) || (code_string_equals(tname, "Process"))) || (code_string_equals(tname, "Regex"))) || (code_string_equals(tname, "Compress"))) || (code_string_equals(tname, "WebSocket")); #line 5970 "./src/generator/c_gen.am" if (isCoreStdlib) { #line 5971 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(tname, "_")), mname); } #line 5973 "./src/generator/c_gen.am" code_string mangledPrefix = Amalgame_Compiler_CGen_PkgClassMangledPrefix(self, tname); #line 5974 "./src/generator/c_gen.am" if (String_Length(mangledPrefix) > 0LL) { #line 5975 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(mangledPrefix, "_")), mname); } #line 5977 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(Amalgame_Compiler_CGen_SymName(self, tname), "_")), mname); } #line 5985 "./src/generator/c_gen.am" if (lk == Amalgame_Compiler_NodeKind_MEMBER) { #line 5986 "./src/generator/c_gen.am" if (callee->Left->Left != NULL) { #line 5987 "./src/generator/c_gen.am" Amalgame_Compiler_NodeKind llk = callee->Left->Left->Kind; #line 5988 "./src/generator/c_gen.am" if (llk == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 5989 "./src/generator/c_gen.am" code_string fname = callee->Left->Name; #line 5990 "./src/generator/c_gen.am" code_string ftype = Amalgame_Compiler_CGen_FieldTypeGet(self, self->CurrentClass, fname); #line 5991 "./src/generator/c_gen.am" code_string bare = String_Replace(ftype, "*", ""); #line 5992 "./src/generator/c_gen.am" if (String_Length(bare) > 0LL) { #line 5993 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(bare, "_")), mname); } } #line 5996 "./src/generator/c_gen.am" if (llk == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 6005 "./src/generator/c_gen.am" code_string vname = callee->Left->Left->Name; #line 6006 "./src/generator/c_gen.am" code_string vtype = Amalgame_Compiler_CGen_LocalTypeGet(self, vname); #line 6007 "./src/generator/c_gen.am" code_string vbare = String_Replace(vtype, "*", ""); #line 6008 "./src/generator/c_gen.am" if (String_Length(vbare) > 0LL) { #line 6009 "./src/generator/c_gen.am" code_string fname = callee->Left->Name; #line 6010 "./src/generator/c_gen.am" code_string ftype = Amalgame_Compiler_CGen_FieldTypeGet(self, vbare, fname); #line 6011 "./src/generator/c_gen.am" code_string fbare = String_Replace(ftype, "*", ""); #line 6012 "./src/generator/c_gen.am" if (String_Length(fbare) > 0LL) { #line 6013 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(fbare, "_")), mname); } } } } #line 6025 "./src/generator/c_gen.am" code_string recvClass = Amalgame_Compiler_CGen_ResolveReceiverClass(self, callee->Left); #line 6026 "./src/generator/c_gen.am" if (String_Length(recvClass) > 0LL) { #line 6027 "./src/generator/c_gen.am" if (((code_string_equals(recvClass, "AmalgameList")) || (code_string_equals(recvClass, "AmalgameMap"))) || (code_string_equals(recvClass, "AmalgameSet"))) { #line 6028 "./src/generator/c_gen.am" code_string cf = String_Substring(mname, 0LL, 1LL); #line 6029 "./src/generator/c_gen.am" code_string cr = String_Substring(mname, 1LL, String_Length(mname) - 1LL); #line 6030 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat(recvClass, "_")), String_ToLower(cf))), cr); } #line 6032 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(recvClass, "_")), mname); } } } #line 6036 "./src/generator/c_gen.am" code_string target = Amalgame_Compiler_CGen_EmitExprStr(self, callee->Left); #line 6037 "./src/generator/c_gen.am" return code_string_concat((code_string_concat(target, "_")), mname); } #line 6039 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_EmitExprStr(self, callee); } static code_bool Amalgame_Compiler_CGen_IsEnum(Amalgame_Compiler_CGen* self, code_string t) { #line 6045 "./src/generator/c_gen.am" i64 n = AmalgameList_count(self->EnumNames); #line 6046 "./src/generator/c_gen.am" for (i64 i = 0LL; i < n; i++) { #line 6047 "./src/generator/c_gen.am" code_string e = (code_string)AmalgameList_get(self->EnumNames, i); #line 6048 "./src/generator/c_gen.am" if (code_string_equals(e, t)) { return 1; } } #line 6050 "./src/generator/c_gen.am" return 0; } static code_bool Amalgame_Compiler_CGen_IsCPointerType(Amalgame_Compiler_CGen* self, code_string ct) { #line 6058 "./src/generator/c_gen.am" if (code_string_equals(ct, "code_string")) { return 1; } #line 6059 "./src/generator/c_gen.am" if (String_EndsWith(ct, "*")) { return 1; } #line 6060 "./src/generator/c_gen.am" return 0; } static code_string Amalgame_Compiler_CGen_BoxAsVoid(Amalgame_Compiler_CGen* self, code_string expr) { #line 6078 "./src/generator/c_gen.am" return code_string_concat((code_string_concat("(void*)(intptr_t)(", expr)), ")"); } static code_string Amalgame_Compiler_CGen_UnboxScalar(Amalgame_Compiler_CGen* self, code_string ctype, code_string expr) { #line 6086 "./src/generator/c_gen.am" return code_string_concat((code_string_concat((code_string_concat("(", ctype)), ")(intptr_t)")), expr); } static code_string Amalgame_Compiler_CGen_TypeToC(Amalgame_Compiler_CGen* self, code_string t) { #line 6090 "./src/generator/c_gen.am" if (code_string_equals(t, "int")) { return "i64"; } #line 6091 "./src/generator/c_gen.am" if (code_string_equals(t, "float")) { return "double"; } #line 6092 "./src/generator/c_gen.am" if (code_string_equals(t, "bool")) { return "code_bool"; } #line 6093 "./src/generator/c_gen.am" if (code_string_equals(t, "string")) { return "code_string"; } #line 6094 "./src/generator/c_gen.am" if (code_string_equals(t, "void")) { return "void"; } #line 6095 "./src/generator/c_gen.am" if (code_string_equals(t, "")) { return "void"; } #line 6101 "./src/generator/c_gen.am" if (code_string_equals(t, "Closure")) { return "AmalgameClosure*"; } #line 6106 "./src/generator/c_gen.am" if (String_StartsWith(t, "Closure<")) { return "AmalgameClosure*"; } #line 6108 "./src/generator/c_gen.am" if (String_EndsWith(t, "[]")) { #line 6109 "./src/generator/c_gen.am" code_string inner = String_Substring(t, 0LL, String_Length(t) - 2LL); #line 6110 "./src/generator/c_gen.am" return code_string_concat(Amalgame_Compiler_CGen_TypeToC(self, inner), "*"); } #line 6112 "./src/generator/c_gen.am" if (String_EndsWith(t, "?")) { #line 6118 "./src/generator/c_gen.am" code_string inner = String_Substring(t, 0LL, String_Length(t) - 1LL); #line 6119 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_TypeToC(self, inner); } #line 6121 "./src/generator/c_gen.am" if (String_StartsWith(t, "List<")) { #line 6122 "./src/generator/c_gen.am" return "AmalgameList*"; } #line 6124 "./src/generator/c_gen.am" if (String_StartsWith(t, "Map<")) { #line 6125 "./src/generator/c_gen.am" return "AmalgameMap*"; } #line 6127 "./src/generator/c_gen.am" if (String_StartsWith(t, "Set<")) { #line 6128 "./src/generator/c_gen.am" return "AmalgameSet*"; } #line 6130 "./src/generator/c_gen.am" if (code_string_equals(t, "List")) { return "AmalgameList*"; } #line 6131 "./src/generator/c_gen.am" if (code_string_equals(t, "Map")) { return "AmalgameMap*"; } #line 6132 "./src/generator/c_gen.am" if (code_string_equals(t, "Set")) { return "AmalgameSet*"; } #line 6136 "./src/generator/c_gen.am" if (code_string_equals(t, "Match")) { return "AmalgameRegexMatch*"; } #line 6137 "./src/generator/c_gen.am" if (code_string_equals(t, "WebSocket")) { return "AmalgameWebSocket*"; } #line 6138 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsEnum(self, t)) { #line 6139 "./src/generator/c_gen.am" return Amalgame_Compiler_CGen_SymName(self, t); } #line 6144 "./src/generator/c_gen.am" code_string ifaceM = Amalgame_Compiler_CGen_IfaceMangledFor(self, t); #line 6145 "./src/generator/c_gen.am" if (String_Length(ifaceM) > 0LL) { #line 6146 "./src/generator/c_gen.am" return ifaceM; } #line 6152 "./src/generator/c_gen.am" code_string externalMangled = Amalgame_Compiler_CGen_ExternalClassMangled(self, t); #line 6153 "./src/generator/c_gen.am" if (String_Length(externalMangled) > 0LL) { #line 6154 "./src/generator/c_gen.am" return code_string_concat(externalMangled, "*"); } #line 6160 "./src/generator/c_gen.am" code_string externalEnumMangled = Amalgame_Compiler_CGen_ExternalEnumMangled(self, t); #line 6161 "./src/generator/c_gen.am" if (String_Length(externalEnumMangled) > 0LL) { #line 6162 "./src/generator/c_gen.am" return externalEnumMangled; } #line 6171 "./src/generator/c_gen.am" i64 opaqueCount = AmalgameList_count(self->PkgOpaqueTypes); #line 6172 "./src/generator/c_gen.am" for (i64 oi = 0LL; oi < opaqueCount; oi++) { #line 6173 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->PkgOpaqueTypes, oi), t)) { #line 6174 "./src/generator/c_gen.am" return code_string_concat(t, "*"); } } #line 6185 "./src/generator/c_gen.am" code_string pkgMangled = Amalgame_Compiler_CGen_PkgClassMangledPrefix(self, t); #line 6186 "./src/generator/c_gen.am" if ((String_Length(pkgMangled) > 0LL) && !Amalgame_Compiler_CGen_IsLocalClass(self, t)) { #line 6187 "./src/generator/c_gen.am" return code_string_concat(pkgMangled, "*"); } #line 6189 "./src/generator/c_gen.am" code_string sym = Amalgame_Compiler_CGen_SymName(self, t); #line 6191 "./src/generator/c_gen.am" if (String_Length(t) == 1LL) { #line 6192 "./src/generator/c_gen.am" code_string fc = String_Substring(t, 0LL, 1LL); #line 6193 "./src/generator/c_gen.am" code_bool isUp = code_string_equals(fc, String_ToUpper(fc)); #line 6194 "./src/generator/c_gen.am" if (isUp) { return "void*"; } } #line 6196 "./src/generator/c_gen.am" if (Amalgame_Compiler_CGen_IsEnum(self, sym)) { #line 6197 "./src/generator/c_gen.am" return sym; } #line 6200 "./src/generator/c_gen.am" code_string algKey = code_string_concat("__alg__", sym); #line 6201 "./src/generator/c_gen.am" i64 en2 = AmalgameList_count(self->EnumNames); #line 6202 "./src/generator/c_gen.am" for (i64 ei2 = 0LL; ei2 < en2; ei2++) { #line 6203 "./src/generator/c_gen.am" if (code_string_equals((code_string)AmalgameList_get(self->EnumNames, ei2), algKey)) { return sym; } } #line 6205 "./src/generator/c_gen.am" return code_string_concat(sym, "*"); } struct _Amalgame_Compiler_Formatter { AmalgameList* Out; code_string Buf; i64 Indent; AmalgameList* Comments; i64 CommentPos; i64 CommentCnt; i64 LastLine; }; code_string Amalgame_Compiler_Formatter_Format(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* prog); static code_string Amalgame_Compiler_Formatter_IndentStr(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_Begin(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_Write(Amalgame_Compiler_Formatter* self, code_string s); static void Amalgame_Compiler_Formatter_End(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_Line(Amalgame_Compiler_Formatter* self, code_string s); static void Amalgame_Compiler_Formatter_Close(Amalgame_Compiler_Formatter* self, code_string s); static void Amalgame_Compiler_Formatter_Blank(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_In_(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_De_(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_AttachToLastEmitted(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_Token* c); static void Amalgame_Compiler_Formatter_DrainTrailingForLastLine(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_Sync(Amalgame_Compiler_Formatter* self, i64 line); static void Amalgame_Compiler_Formatter_FlushTrailingComments(Amalgame_Compiler_Formatter* self); static void Amalgame_Compiler_Formatter_EmitProgram(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* prog); static void Amalgame_Compiler_Formatter_EmitTopDecl(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitClass(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitClassMember(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* m, code_string className); static void Amalgame_Compiler_Formatter_EmitMethod(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n, code_string className); static code_string Amalgame_Compiler_Formatter_EmitParams(Amalgame_Compiler_Formatter* self, AmalgameList* params); static void Amalgame_Compiler_Formatter_EmitField(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitEnum(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static i64 Amalgame_Compiler_Formatter_MaxLineInTree(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static i64 Amalgame_Compiler_Formatter_BlockEndLine(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* body); static void Amalgame_Compiler_Formatter_EmitBlockStmts(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* body); static void Amalgame_Compiler_Formatter_EmitInline(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* body); static void Amalgame_Compiler_Formatter_EmitStmt(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitTry(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitThrow(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitInlineC(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitBlock(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitIf(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitElseTail(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitMatch(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitPattern(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitWhile(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitForIn(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Formatter_EmitVarDecl(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n, code_bool topLevel); static void Amalgame_Compiler_Formatter_EmitReturn(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitExpr(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitBinary(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitUnary(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitCall(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitMember(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitIndex(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitMatchExpr(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitIfExpr(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_EmitLambda(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_LambdaParamName(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* p); static code_string Amalgame_Compiler_Formatter_EmitBlockAsExpr(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* body); static code_string Amalgame_Compiler_Formatter_EmitNew(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n); static code_string Amalgame_Compiler_Formatter_QuoteString(Amalgame_Compiler_Formatter* self, code_string content); static code_string Amalgame_Compiler_Formatter_KindName(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_NodeKind k); Amalgame_Compiler_Formatter* Amalgame_Compiler_Formatter_new(AmalgameList* comments) { Amalgame_Compiler_Formatter* self = (Amalgame_Compiler_Formatter*) GC_MALLOC(sizeof(Amalgame_Compiler_Formatter)); #line 33 "./src/formatter/formatter.am" self->Out = AmalgameList_new(); #line 34 "./src/formatter/formatter.am" self->Buf = ""; #line 35 "./src/formatter/formatter.am" self->Indent = 0LL; #line 36 "./src/formatter/formatter.am" self->Comments = comments; #line 37 "./src/formatter/formatter.am" self->CommentPos = 0LL; #line 38 "./src/formatter/formatter.am" self->CommentCnt = AmalgameList_count(comments); #line 39 "./src/formatter/formatter.am" self->LastLine = 0LL; return self; } code_string Amalgame_Compiler_Formatter_Format(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* prog) { #line 44 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitProgram(self, prog); #line 45 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_FlushTrailingComments(self); #line 46 "./src/formatter/formatter.am" code_string result = ""; #line 47 "./src/formatter/formatter.am" i64 n = AmalgameList_count(self->Out); #line 48 "./src/formatter/formatter.am" for (i64 i = 0LL; i < n; i++) { #line 49 "./src/formatter/formatter.am" code_string line = (code_string)AmalgameList_get(self->Out, i); #line 50 "./src/formatter/formatter.am" result = (code_string_concat((code_string_concat(result, line)), "\n")); } #line 52 "./src/formatter/formatter.am" return result; } static code_string Amalgame_Compiler_Formatter_IndentStr(Amalgame_Compiler_Formatter* self) { #line 57 "./src/formatter/formatter.am" code_string s = ""; #line 58 "./src/formatter/formatter.am" i64 i = 0LL; #line 59 "./src/formatter/formatter.am" while (i < self->Indent) { #line 60 "./src/formatter/formatter.am" s = (code_string_concat(s, " ")); #line 61 "./src/formatter/formatter.am" i = (i + 1LL); } #line 63 "./src/formatter/formatter.am" return s; } static void Amalgame_Compiler_Formatter_Begin(Amalgame_Compiler_Formatter* self) { #line 66 "./src/formatter/formatter.am" self->Buf = Amalgame_Compiler_Formatter_IndentStr(self); } static void Amalgame_Compiler_Formatter_Write(Amalgame_Compiler_Formatter* self, code_string s) { #line 67 "./src/formatter/formatter.am" self->Buf = (code_string_concat(self->Buf, s)); } static void Amalgame_Compiler_Formatter_End(Amalgame_Compiler_Formatter* self) { #line 69 "./src/formatter/formatter.am" AmalgameList_add(self->Out, (void*)(intptr_t)(self->Buf)); #line 70 "./src/formatter/formatter.am" self->Buf = ""; } static void Amalgame_Compiler_Formatter_Line(Amalgame_Compiler_Formatter* self, code_string s) { #line 73 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Begin(self); #line 74 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Write(self, s); #line 75 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_End(self); } static void Amalgame_Compiler_Formatter_Close(Amalgame_Compiler_Formatter* self, code_string s) { #line 83 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, s); } static void Amalgame_Compiler_Formatter_Blank(Amalgame_Compiler_Formatter* self) { #line 85 "./src/formatter/formatter.am" AmalgameList_add(self->Out, (void*)(intptr_t)("")); } static void Amalgame_Compiler_Formatter_In_(Amalgame_Compiler_Formatter* self) { #line 86 "./src/formatter/formatter.am" self->Indent = (self->Indent + 1LL); } static void Amalgame_Compiler_Formatter_De_(Amalgame_Compiler_Formatter* self) { #line 87 "./src/formatter/formatter.am" self->Indent = (self->Indent - 1LL); } static void Amalgame_Compiler_Formatter_AttachToLastEmitted(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_Token* c) { #line 95 "./src/formatter/formatter.am" i64 last = AmalgameList_count(self->Out) - 1LL; #line 96 "./src/formatter/formatter.am" if (last < 0LL) { return; } #line 97 "./src/formatter/formatter.am" code_string prev = (code_string)AmalgameList_get(self->Out, last); #line 98 "./src/formatter/formatter.am" AmalgameList_removeAt(self->Out, last); #line 99 "./src/formatter/formatter.am" AmalgameList_add(self->Out, (void*)(intptr_t)(code_string_concat((code_string_concat(prev, " ")), c->Value))); } static void Amalgame_Compiler_Formatter_DrainTrailingForLastLine(Amalgame_Compiler_Formatter* self) { #line 108 "./src/formatter/formatter.am" while ((self->CommentPos < self->CommentCnt) && (self->LastLine > 0LL)) { #line 109 "./src/formatter/formatter.am" Amalgame_Compiler_Token* c = (Amalgame_Compiler_Token*)AmalgameList_get(self->Comments, self->CommentPos); #line 110 "./src/formatter/formatter.am" if (c->Line != self->LastLine) { break; } #line 111 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_AttachToLastEmitted(self, c); #line 112 "./src/formatter/formatter.am" self->CommentPos = (self->CommentPos + 1LL); } } static void Amalgame_Compiler_Formatter_Sync(Amalgame_Compiler_Formatter* self, i64 line) { #line 121 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_DrainTrailingForLastLine(self); #line 122 "./src/formatter/formatter.am" while (self->CommentPos < self->CommentCnt) { #line 123 "./src/formatter/formatter.am" Amalgame_Compiler_Token* c = (Amalgame_Compiler_Token*)AmalgameList_get(self->Comments, self->CommentPos); #line 124 "./src/formatter/formatter.am" if (c->Line >= line) { break; } #line 125 "./src/formatter/formatter.am" if ((self->LastLine > 0LL) && ((c->Line - self->LastLine) >= 2LL)) { #line 126 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Blank(self); } #line 128 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, c->Value); #line 129 "./src/formatter/formatter.am" self->LastLine = c->Line; #line 130 "./src/formatter/formatter.am" self->CommentPos = (self->CommentPos + 1LL); } #line 132 "./src/formatter/formatter.am" if ((self->LastLine > 0LL) && ((line - self->LastLine) >= 2LL)) { #line 133 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Blank(self); } #line 135 "./src/formatter/formatter.am" if (line > 0LL) { self->LastLine = line; } } static void Amalgame_Compiler_Formatter_FlushTrailingComments(Amalgame_Compiler_Formatter* self) { #line 139 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_DrainTrailingForLastLine(self); #line 140 "./src/formatter/formatter.am" while (self->CommentPos < self->CommentCnt) { #line 141 "./src/formatter/formatter.am" Amalgame_Compiler_Token* c = (Amalgame_Compiler_Token*)AmalgameList_get(self->Comments, self->CommentPos); #line 142 "./src/formatter/formatter.am" if ((self->LastLine > 0LL) && ((c->Line - self->LastLine) >= 2LL)) { #line 143 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Blank(self); } #line 145 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, c->Value); #line 146 "./src/formatter/formatter.am" self->LastLine = c->Line; #line 147 "./src/formatter/formatter.am" self->CommentPos = (self->CommentPos + 1LL); } } static void Amalgame_Compiler_Formatter_EmitProgram(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* prog) { #line 156 "./src/formatter/formatter.am" if (String_Length(prog->Str) > 0LL) { #line 157 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Sync(self, 1LL); #line 158 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat("namespace ", prog->Str)); } #line 160 "./src/formatter/formatter.am" i64 importCount = AmalgameList_count(prog->Args); #line 161 "./src/formatter/formatter.am" for (i64 ii = 0LL; ii < importCount; ii++) { #line 162 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* imp = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Args, ii); #line 163 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Sync(self, imp->Line); #line 164 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat("import ", imp->Name)); } #line 166 "./src/formatter/formatter.am" i64 n = AmalgameList_count(prog->Children); #line 167 "./src/formatter/formatter.am" for (i64 i = 0LL; i < n; i++) { #line 168 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i); #line 169 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Sync(self, decl->Line); #line 170 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitTopDecl(self, decl); } } static void Amalgame_Compiler_Formatter_EmitTopDecl(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 175 "./src/formatter/formatter.am" Amalgame_Compiler_NodeKind k = n->Kind; #line 176 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { #line 177 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitClass(self, n); } else if (k == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 179 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitMethod(self, n, ""); } else if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) { #line 181 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitEnum(self, n); } else if (k == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 183 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitVarDecl(self, n, 1); } else if (k == Amalgame_Compiler_NodeKind_INLINE_C_INCLUDE) { #line 185 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat((code_string_concat("@c_include \"", n->Str)), "\"")); } else if (k == Amalgame_Compiler_NodeKind_INLINE_C_LINK) { #line 187 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat((code_string_concat("@c_link \"", n->Str)), "\"")); } else { #line 189 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat((code_string_concat("// TODO: top-level kind ", Amalgame_Compiler_Formatter_KindName(self, k))), "")); } } static void Amalgame_Compiler_Formatter_EmitClass(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 195 "./src/formatter/formatter.am" code_string head = ""; #line 196 "./src/formatter/formatter.am" if (n->Flag) { head = (code_string_concat(head, "public ")); } #line 197 "./src/formatter/formatter.am" if (n->Flag2) { #line 198 "./src/formatter/formatter.am" head = (code_string_concat((code_string_concat(head, "interface ")), n->Name)); } else { #line 200 "./src/formatter/formatter.am" head = (code_string_concat((code_string_concat(head, "class ")), n->Name)); #line 201 "./src/formatter/formatter.am" if (String_Length(n->Str) > 0LL) { #line 202 "./src/formatter/formatter.am" head = (code_string_concat((code_string_concat(head, " : ")), n->Str)); } } #line 205 "./src/formatter/formatter.am" head = (code_string_concat(head, " {")); #line 206 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, head); #line 207 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 208 "./src/formatter/formatter.am" self->LastLine = n->Line; #line 209 "./src/formatter/formatter.am" i64 count = AmalgameList_count(n->Children); #line 210 "./src/formatter/formatter.am" code_string className = n->Name; #line 211 "./src/formatter/formatter.am" for (i64 i = 0LL; i < count; i++) { #line 212 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, i); #line 213 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Sync(self, m->Line); #line 214 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitClassMember(self, m, className); } #line 216 "./src/formatter/formatter.am" if (String_Length(n->Str2) > 0LL) { #line 217 "./src/formatter/formatter.am" self->LastLine = String_ToInt(n->Str2); } else if (count > 0LL) { #line 219 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* last = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, count - 1LL); #line 220 "./src/formatter/formatter.am" self->LastLine = (Amalgame_Compiler_Formatter_MaxLineInTree(self, last) + 1LL); } #line 222 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 223 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } static void Amalgame_Compiler_Formatter_EmitClassMember(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* m, code_string className) { #line 227 "./src/formatter/formatter.am" Amalgame_Compiler_NodeKind k = m->Kind; #line 228 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 229 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitMethod(self, m, className); } else if (k == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 231 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitField(self, m); } else { #line 233 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat((code_string_concat("// TODO: member kind ", Amalgame_Compiler_Formatter_KindName(self, k))), "")); } } static void Amalgame_Compiler_Formatter_EmitMethod(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n, code_string className) { #line 243 "./src/formatter/formatter.am" if (String_Length(n->Str2) > 0LL) { #line 244 "./src/formatter/formatter.am" code_string decos = n->Str2; #line 245 "./src/formatter/formatter.am" i64 i = 0LL; #line 246 "./src/formatter/formatter.am" i64 len = String_Length(decos); #line 247 "./src/formatter/formatter.am" code_string cur = ""; #line 248 "./src/formatter/formatter.am" while (i < len) { #line 249 "./src/formatter/formatter.am" code_string ch = String_Substring(decos, i, 1LL); #line 250 "./src/formatter/formatter.am" if (code_string_equals(ch, ",")) { #line 251 "./src/formatter/formatter.am" if (String_Length(cur) > 0LL) { Amalgame_Compiler_Formatter_Line(self, code_string_concat("@", cur)); } #line 252 "./src/formatter/formatter.am" cur = ""; } else { #line 254 "./src/formatter/formatter.am" cur = (code_string_concat(cur, ch)); } #line 256 "./src/formatter/formatter.am" i = (i + 1LL); } #line 258 "./src/formatter/formatter.am" if (String_Length(cur) > 0LL) { Amalgame_Compiler_Formatter_Line(self, code_string_concat("@", cur)); } } #line 260 "./src/formatter/formatter.am" code_string head = ""; #line 261 "./src/formatter/formatter.am" if (n->Flag) { head = (code_string_concat(head, "public ")); } #line 262 "./src/formatter/formatter.am" if (n->Flag2) { head = (code_string_concat(head, "static ")); } #line 263 "./src/formatter/formatter.am" if (n->Flag3) { head = (code_string_concat(head, "async ")); } #line 264 "./src/formatter/formatter.am" code_bool isCtor = (String_Length(className) > 0LL) && (code_string_equals(n->Name, className)); #line 265 "./src/formatter/formatter.am" if (isCtor) { #line 266 "./src/formatter/formatter.am" head = (code_string_concat((code_string_concat(head, n->Name)), "(")); } else { #line 268 "./src/formatter/formatter.am" head = (code_string_concat((code_string_concat((code_string_concat((code_string_concat(head, n->Str)), " ")), n->Name)), "(")); } #line 270 "./src/formatter/formatter.am" head = (code_string_concat(head, Amalgame_Compiler_Formatter_EmitParams(self, n->Params))); #line 271 "./src/formatter/formatter.am" head = (code_string_concat(head, ")")); #line 272 "./src/formatter/formatter.am" if (n->Body == NULL) { #line 274 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, head); #line 275 "./src/formatter/formatter.am" return; } #line 277 "./src/formatter/formatter.am" head = (code_string_concat(head, " {")); #line 278 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, head); #line 279 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 280 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* body = n->Body; #line 281 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitBlockStmts(self, body); #line 282 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 283 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } static code_string Amalgame_Compiler_Formatter_EmitParams(Amalgame_Compiler_Formatter* self, AmalgameList* params) { #line 287 "./src/formatter/formatter.am" code_string s = ""; #line 288 "./src/formatter/formatter.am" i64 count = AmalgameList_count(params); #line 289 "./src/formatter/formatter.am" for (i64 i = 0LL; i < count; i++) { #line 290 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(params, i); #line 291 "./src/formatter/formatter.am" if (i > 0LL) { s = (code_string_concat(s, ", ")); } #line 293 "./src/formatter/formatter.am" if (p->Flag) { s = (code_string_concat(s, "...")); } #line 294 "./src/formatter/formatter.am" s = (code_string_concat((code_string_concat((code_string_concat(s, p->Str)), " ")), p->Name)); } #line 296 "./src/formatter/formatter.am" return s; } static void Amalgame_Compiler_Formatter_EmitField(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 301 "./src/formatter/formatter.am" code_string s = ""; #line 302 "./src/formatter/formatter.am" if (n->Flag) { s = (code_string_concat(s, "public ")); } #line 303 "./src/formatter/formatter.am" s = (code_string_concat(s, n->Name)); #line 304 "./src/formatter/formatter.am" if (String_Length(n->Str) > 0LL) { #line 305 "./src/formatter/formatter.am" s = (code_string_concat((code_string_concat(s, ": ")), n->Str)); } #line 307 "./src/formatter/formatter.am" if (n->Left != NULL) { #line 308 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* init = n->Left; #line 309 "./src/formatter/formatter.am" s = (code_string_concat((code_string_concat(s, " = ")), Amalgame_Compiler_Formatter_EmitExpr(self, init))); } #line 311 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, s); } static void Amalgame_Compiler_Formatter_EmitEnum(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 316 "./src/formatter/formatter.am" code_string head = ""; #line 317 "./src/formatter/formatter.am" if (n->Flag) { head = (code_string_concat(head, "public ")); } #line 318 "./src/formatter/formatter.am" head = (code_string_concat((code_string_concat((code_string_concat(head, "enum ")), n->Name)), " {")); #line 319 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, head); #line 320 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 321 "./src/formatter/formatter.am" self->LastLine = n->Line; #line 322 "./src/formatter/formatter.am" i64 c = AmalgameList_count(n->Children); #line 323 "./src/formatter/formatter.am" for (i64 i = 0LL; i < c; i++) { #line 324 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* v = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, i); #line 325 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Sync(self, v->Line); #line 326 "./src/formatter/formatter.am" if (String_Length(v->Str) > 0LL) { #line 327 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat((code_string_concat((code_string_concat(v->Name, "(")), v->Str)), ")")); } else { #line 329 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, v->Name); } } #line 332 "./src/formatter/formatter.am" if (c > 0LL) { #line 333 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* last = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, c - 1LL); #line 334 "./src/formatter/formatter.am" self->LastLine = (last->Line + 1LL); } #line 336 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 337 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } static i64 Amalgame_Compiler_Formatter_MaxLineInTree(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 345 "./src/formatter/formatter.am" if (n == NULL) { return 0LL; } #line 346 "./src/formatter/formatter.am" i64 m = n->Line; #line 347 "./src/formatter/formatter.am" i64 lm = Amalgame_Compiler_Formatter_MaxLineInTree(self, n->Left); if (lm > m) { m = lm; } #line 348 "./src/formatter/formatter.am" i64 rm = Amalgame_Compiler_Formatter_MaxLineInTree(self, n->Right); if (rm > m) { m = rm; } #line 349 "./src/formatter/formatter.am" i64 cm = Amalgame_Compiler_Formatter_MaxLineInTree(self, n->Cond); if (cm > m) { m = cm; } #line 350 "./src/formatter/formatter.am" i64 bm = Amalgame_Compiler_Formatter_MaxLineInTree(self, n->Body); if (bm > m) { m = bm; } #line 351 "./src/formatter/formatter.am" i64 em = Amalgame_Compiler_Formatter_MaxLineInTree(self, n->Else); if (em > m) { m = em; } #line 352 "./src/formatter/formatter.am" i64 cc = AmalgameList_count(n->Children); #line 353 "./src/formatter/formatter.am" for (i64 i = 0LL; i < cc; i++) { #line 354 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* chi = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, i); #line 355 "./src/formatter/formatter.am" i64 cmm = Amalgame_Compiler_Formatter_MaxLineInTree(self, chi); #line 356 "./src/formatter/formatter.am" if (cmm > m) { m = cmm; } } #line 358 "./src/formatter/formatter.am" i64 pc = AmalgameList_count(n->Params); #line 359 "./src/formatter/formatter.am" for (i64 j = 0LL; j < pc; j++) { #line 360 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* pj = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Params, j); #line 361 "./src/formatter/formatter.am" i64 pmm = Amalgame_Compiler_Formatter_MaxLineInTree(self, pj); #line 362 "./src/formatter/formatter.am" if (pmm > m) { m = pmm; } } #line 364 "./src/formatter/formatter.am" i64 ac = AmalgameList_count(n->Args); #line 365 "./src/formatter/formatter.am" for (i64 k = 0LL; k < ac; k++) { #line 366 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* ak = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Args, k); #line 367 "./src/formatter/formatter.am" i64 amm = Amalgame_Compiler_Formatter_MaxLineInTree(self, ak); #line 368 "./src/formatter/formatter.am" if (amm > m) { m = amm; } } #line 370 "./src/formatter/formatter.am" return m; } static i64 Amalgame_Compiler_Formatter_BlockEndLine(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* body) { #line 378 "./src/formatter/formatter.am" if (String_Length(body->Str2) > 0LL) { #line 379 "./src/formatter/formatter.am" return String_ToInt(body->Str2); } #line 381 "./src/formatter/formatter.am" return Amalgame_Compiler_Formatter_MaxLineInTree(self, body) + 1LL; } static void Amalgame_Compiler_Formatter_EmitBlockStmts(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* body) { #line 389 "./src/formatter/formatter.am" self->LastLine = body->Line; #line 390 "./src/formatter/formatter.am" i64 count = AmalgameList_count(body->Children); #line 391 "./src/formatter/formatter.am" for (i64 i = 0LL; i < count; i++) { #line 392 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* s = (Amalgame_Compiler_AstNode*)AmalgameList_get(body->Children, i); #line 393 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Sync(self, s->Line); #line 394 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitStmt(self, s); } #line 400 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_DrainTrailingForLastLine(self); #line 401 "./src/formatter/formatter.am" self->LastLine = Amalgame_Compiler_Formatter_BlockEndLine(self, body); } static void Amalgame_Compiler_Formatter_EmitInline(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* body) { #line 408 "./src/formatter/formatter.am" if (body->Kind == Amalgame_Compiler_NodeKind_BLOCK) { #line 409 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitBlockStmts(self, body); } else { #line 411 "./src/formatter/formatter.am" self->LastLine = body->Line; #line 412 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitStmt(self, body); #line 413 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_DrainTrailingForLastLine(self); #line 414 "./src/formatter/formatter.am" self->LastLine = (Amalgame_Compiler_Formatter_MaxLineInTree(self, body) + 1LL); } } static void Amalgame_Compiler_Formatter_EmitStmt(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 420 "./src/formatter/formatter.am" Amalgame_Compiler_NodeKind k = n->Kind; #line 421 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_IF_STMT) { #line 422 "./src/formatter/formatter.am" if (code_string_equals(n->Name, "__match__")) { Amalgame_Compiler_Formatter_EmitMatch(self, n); } else { Amalgame_Compiler_Formatter_EmitIf(self, n); } } else if (k == Amalgame_Compiler_NodeKind_WHILE_STMT) { #line 424 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitWhile(self, n); } else if (k == Amalgame_Compiler_NodeKind_FOR_IN_STMT) { #line 426 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitForIn(self, n); } else if (k == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 428 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitVarDecl(self, n, 0); } else if (k == Amalgame_Compiler_NodeKind_RETURN_STMT) { #line 430 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitReturn(self, n); } else if (k == Amalgame_Compiler_NodeKind_BREAK_STMT) { #line 432 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, "break"); } else if (k == Amalgame_Compiler_NodeKind_CONTINUE_STMT) { #line 434 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, "continue"); } else if (k == Amalgame_Compiler_NodeKind_TRY_STMT) { #line 436 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitTry(self, n); } else if (k == Amalgame_Compiler_NodeKind_THROW_STMT) { #line 438 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitThrow(self, n); } else if (k == Amalgame_Compiler_NodeKind_INLINE_C) { #line 440 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitInlineC(self, n); } else if (k == Amalgame_Compiler_NodeKind_BLOCK) { #line 442 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitBlock(self, n); } else { #line 445 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, Amalgame_Compiler_Formatter_EmitExpr(self, n)); } } static void Amalgame_Compiler_Formatter_EmitTry(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 450 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, "try {"); #line 451 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 452 "./src/formatter/formatter.am" if (n->Body != NULL) { Amalgame_Compiler_Formatter_EmitInline(self, n->Body); } #line 453 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 454 "./src/formatter/formatter.am" if (n->Else != NULL) { #line 455 "./src/formatter/formatter.am" code_string head = "} catch"; #line 456 "./src/formatter/formatter.am" if (String_Length(n->Name) > 0LL) { head = (code_string_concat((code_string_concat(head, " ")), n->Name)); } #line 457 "./src/formatter/formatter.am" head = (code_string_concat(head, " {")); #line 458 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, head); #line 459 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 460 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitInline(self, n->Else); #line 461 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); } #line 463 "./src/formatter/formatter.am" if (n->Cond != NULL) { #line 464 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, "} finally {"); #line 465 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 466 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitInline(self, n->Cond); #line 467 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); } #line 469 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } static void Amalgame_Compiler_Formatter_EmitThrow(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 473 "./src/formatter/formatter.am" if (n->Left == NULL) { Amalgame_Compiler_Formatter_Line(self, "throw"); return; } #line 474 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat("throw ", Amalgame_Compiler_Formatter_EmitExpr(self, n->Left))); } static void Amalgame_Compiler_Formatter_EmitInlineC(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 481 "./src/formatter/formatter.am" code_string body = n->Str; #line 482 "./src/formatter/formatter.am" if (String_Length(body) == 0LL) { #line 483 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, "@c {}"); #line 484 "./src/formatter/formatter.am" return; } #line 486 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, "@c {"); #line 487 "./src/formatter/formatter.am" AmalgameList* lines = String_Split(body, "\n"); #line 488 "./src/formatter/formatter.am" i64 count = AmalgameList_count(lines); #line 489 "./src/formatter/formatter.am" for (i64 i = 0LL; i < count; i++) { #line 490 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, (code_string)AmalgameList_get(lines, i)); } #line 492 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, "}"); } static void Amalgame_Compiler_Formatter_EmitBlock(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 496 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, "{"); #line 497 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 498 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitBlockStmts(self, n); #line 499 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 500 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } static void Amalgame_Compiler_Formatter_EmitIf(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 504 "./src/formatter/formatter.am" code_string condStr = Amalgame_Compiler_Formatter_EmitExpr(self, n->Cond); #line 505 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat((code_string_concat("if (", condStr)), ") {")); #line 506 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 507 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitInline(self, n->Body); #line 508 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 509 "./src/formatter/formatter.am" if (n->Else != NULL) { #line 510 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* elseN = n->Else; #line 511 "./src/formatter/formatter.am" if ((elseN->Kind == Amalgame_Compiler_NodeKind_IF_STMT) && (!code_string_equals(elseN->Name, "__match__"))) { #line 512 "./src/formatter/formatter.am" code_string inner = Amalgame_Compiler_Formatter_EmitExpr(self, elseN->Cond); #line 513 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat((code_string_concat("} else if (", inner)), ") {")); #line 514 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 515 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitInline(self, elseN->Body); #line 516 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 517 "./src/formatter/formatter.am" if (elseN->Else != NULL) { #line 519 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitElseTail(self, elseN->Else); } else { #line 521 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } } else { #line 524 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, "} else {"); #line 525 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 526 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitInline(self, elseN); #line 527 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 528 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } } else { #line 531 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } } static void Amalgame_Compiler_Formatter_EmitElseTail(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 537 "./src/formatter/formatter.am" if ((n->Kind == Amalgame_Compiler_NodeKind_IF_STMT) && (!code_string_equals(n->Name, "__match__"))) { #line 538 "./src/formatter/formatter.am" code_string inner = Amalgame_Compiler_Formatter_EmitExpr(self, n->Cond); #line 539 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat((code_string_concat("} else if (", inner)), ") {")); #line 540 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 541 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitInline(self, n->Body); #line 542 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 543 "./src/formatter/formatter.am" if (n->Else != NULL) { #line 544 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitElseTail(self, n->Else); } else { #line 546 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } } else { #line 549 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, "} else {"); #line 550 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 551 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitInline(self, n); #line 552 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 553 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } } static void Amalgame_Compiler_Formatter_EmitMatch(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 558 "./src/formatter/formatter.am" code_string subj = Amalgame_Compiler_Formatter_EmitExpr(self, n->Left); #line 559 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat((code_string_concat("match ", subj)), " {")); #line 560 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 561 "./src/formatter/formatter.am" i64 arms = AmalgameList_count(n->Children); #line 562 "./src/formatter/formatter.am" for (i64 i = 0LL; i < arms; i++) { #line 563 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* arm = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, i); #line 565 "./src/formatter/formatter.am" code_string pat = Amalgame_Compiler_Formatter_EmitPattern(self, arm->Left); #line 566 "./src/formatter/formatter.am" code_string head = pat; #line 567 "./src/formatter/formatter.am" if (arm->Cond != NULL) { #line 568 "./src/formatter/formatter.am" head = (code_string_concat((code_string_concat(head, " if ")), Amalgame_Compiler_Formatter_EmitExpr(self, arm->Cond))); } #line 570 "./src/formatter/formatter.am" head = (code_string_concat(head, " => ")); #line 571 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* bodyN = arm->Right; #line 572 "./src/formatter/formatter.am" if (bodyN->Kind == Amalgame_Compiler_NodeKind_BLOCK) { #line 573 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat(head, "{")); #line 574 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 575 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitBlockStmts(self, bodyN); #line 576 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 577 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } else { #line 579 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat(head, Amalgame_Compiler_Formatter_EmitExpr(self, bodyN))); } } #line 582 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 583 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } static code_string Amalgame_Compiler_Formatter_EmitPattern(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 587 "./src/formatter/formatter.am" Amalgame_Compiler_NodeKind k = n->Kind; #line 588 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { return n->Name; } #line 589 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_INT) { return n->Str; } #line 590 "./src/formatter/formatter.am" if ((k == Amalgame_Compiler_NodeKind_BINARY) && (code_string_equals(n->Str, ".."))) { #line 591 "./src/formatter/formatter.am" return code_string_concat((code_string_concat(Amalgame_Compiler_Formatter_EmitExpr(self, n->Left), "..")), Amalgame_Compiler_Formatter_EmitExpr(self, n->Right)); } #line 593 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_CALL) { #line 595 "./src/formatter/formatter.am" code_string s = code_string_concat(n->Name, "("); #line 596 "./src/formatter/formatter.am" i64 c = AmalgameList_count(n->Args); #line 597 "./src/formatter/formatter.am" for (i64 i = 0LL; i < c; i++) { #line 598 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* a = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Args, i); #line 599 "./src/formatter/formatter.am" if (i > 0LL) { s = (code_string_concat(s, ", ")); } #line 600 "./src/formatter/formatter.am" s = (code_string_concat(s, a->Name)); } #line 602 "./src/formatter/formatter.am" return code_string_concat(s, ")"); } #line 604 "./src/formatter/formatter.am" return Amalgame_Compiler_Formatter_EmitExpr(self, n); } static void Amalgame_Compiler_Formatter_EmitWhile(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 608 "./src/formatter/formatter.am" code_string c = Amalgame_Compiler_Formatter_EmitExpr(self, n->Cond); #line 609 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat((code_string_concat("while (", c)), ") {")); #line 610 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 611 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitInline(self, n->Body); #line 612 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 613 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } static void Amalgame_Compiler_Formatter_EmitForIn(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 617 "./src/formatter/formatter.am" code_string it = Amalgame_Compiler_Formatter_EmitExpr(self, n->Left); #line 618 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat("for ", n->Name)), " in ")), it)), " {")); #line 619 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_In_(self); #line 620 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_EmitInline(self, n->Body); #line 621 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_De_(self); #line 622 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Close(self, "}"); } static void Amalgame_Compiler_Formatter_EmitVarDecl(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n, code_bool topLevel) { #line 626 "./src/formatter/formatter.am" code_string kw = "let"; #line 627 "./src/formatter/formatter.am" if (n->Flag) { kw = "var"; } #line 628 "./src/formatter/formatter.am" code_string s = code_string_concat((code_string_concat(kw, " ")), n->Name); #line 629 "./src/formatter/formatter.am" if (String_Length(n->Str) > 0LL) { #line 630 "./src/formatter/formatter.am" s = (code_string_concat((code_string_concat(s, ": ")), n->Str)); } #line 632 "./src/formatter/formatter.am" if (n->Left != NULL) { #line 633 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* init = n->Left; #line 634 "./src/formatter/formatter.am" s = (code_string_concat((code_string_concat(s, " = ")), Amalgame_Compiler_Formatter_EmitExpr(self, init))); } #line 636 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, s); } static void Amalgame_Compiler_Formatter_EmitReturn(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 640 "./src/formatter/formatter.am" if (n->Left == NULL) { #line 641 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, "return"); #line 642 "./src/formatter/formatter.am" return; } #line 644 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* v = n->Left; #line 645 "./src/formatter/formatter.am" if ((v->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) && (code_string_equals(v->Name, "_unknown_"))) { #line 646 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, "return"); #line 647 "./src/formatter/formatter.am" return; } #line 649 "./src/formatter/formatter.am" Amalgame_Compiler_Formatter_Line(self, code_string_concat("return ", Amalgame_Compiler_Formatter_EmitExpr(self, v))); } static code_string Amalgame_Compiler_Formatter_EmitExpr(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 654 "./src/formatter/formatter.am" if (n == NULL) { return ""; } #line 655 "./src/formatter/formatter.am" Amalgame_Compiler_NodeKind k = n->Kind; #line 656 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { return n->Name; } #line 657 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_INT) { return n->Str; } #line 658 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_FLOAT) { return n->Str; } #line 659 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_STRING) { return Amalgame_Compiler_Formatter_QuoteString(self, n->Str); } #line 660 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_BOOL) { #line 661 "./src/formatter/formatter.am" if (n->Flag) { return "true"; } #line 662 "./src/formatter/formatter.am" return "false"; } #line 664 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_NULL) { return "null"; } #line 665 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_THIS_EXPR) { return "this"; } #line 666 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_BINARY) { return Amalgame_Compiler_Formatter_EmitBinary(self, n); } #line 667 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_UNARY) { return Amalgame_Compiler_Formatter_EmitUnary(self, n); } #line 668 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_CALL) { return Amalgame_Compiler_Formatter_EmitCall(self, n); } #line 669 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_MEMBER) { return Amalgame_Compiler_Formatter_EmitMember(self, n); } #line 670 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_INDEX_EXPR) { return Amalgame_Compiler_Formatter_EmitIndex(self, n); } #line 671 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_NEW_EXPR) { return Amalgame_Compiler_Formatter_EmitNew(self, n); } #line 672 "./src/formatter/formatter.am" if ((k == Amalgame_Compiler_NodeKind_METHOD_DECL) && (code_string_equals(n->Name, "__lambda__"))) { #line 673 "./src/formatter/formatter.am" return Amalgame_Compiler_Formatter_EmitLambda(self, n); } #line 675 "./src/formatter/formatter.am" if ((k == Amalgame_Compiler_NodeKind_IF_STMT) && (!code_string_equals(n->Name, "__match__"))) { #line 676 "./src/formatter/formatter.am" return Amalgame_Compiler_Formatter_EmitIfExpr(self, n); } #line 678 "./src/formatter/formatter.am" if ((k == Amalgame_Compiler_NodeKind_IF_STMT) && (code_string_equals(n->Name, "__match__"))) { #line 679 "./src/formatter/formatter.am" return Amalgame_Compiler_Formatter_EmitMatchExpr(self, n); } #line 681 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LIST_COMP) { #line 682 "./src/formatter/formatter.am" code_string s = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("[", Amalgame_Compiler_Formatter_EmitExpr(self, n->Left))), " for ")), n->Str)), " in ")), Amalgame_Compiler_Formatter_EmitExpr(self, n->Right)); #line 683 "./src/formatter/formatter.am" if (n->Cond != NULL) { #line 684 "./src/formatter/formatter.am" s = (code_string_concat((code_string_concat(s, " if ")), Amalgame_Compiler_Formatter_EmitExpr(self, n->Cond))); } #line 686 "./src/formatter/formatter.am" return code_string_concat(s, "]"); } #line 688 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LIST_LITERAL) { #line 689 "./src/formatter/formatter.am" code_string ll = "["; #line 690 "./src/formatter/formatter.am" i64 nc = AmalgameList_count(n->Children); #line 691 "./src/formatter/formatter.am" for (i64 i = 0LL; i < nc; i++) { #line 692 "./src/formatter/formatter.am" if (i > 0LL) { ll = (code_string_concat(ll, ", ")); } #line 693 "./src/formatter/formatter.am" ll = (code_string_concat(ll, Amalgame_Compiler_Formatter_EmitExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, i)))); } #line 695 "./src/formatter/formatter.am" return code_string_concat(ll, "]"); } #line 700 "./src/formatter/formatter.am" return code_string_concat((code_string_concat("_TODO_", Amalgame_Compiler_Formatter_KindName(self, k))), ""); } static code_string Amalgame_Compiler_Formatter_EmitBinary(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 704 "./src/formatter/formatter.am" code_string l = Amalgame_Compiler_Formatter_EmitExpr(self, n->Left); #line 705 "./src/formatter/formatter.am" code_string r = Amalgame_Compiler_Formatter_EmitExpr(self, n->Right); #line 706 "./src/formatter/formatter.am" if (code_string_equals(n->Str, "..")) { return code_string_concat((code_string_concat(l, "..")), r); } #line 707 "./src/formatter/formatter.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat(l, " ")), n->Str)), " ")), r); } static code_string Amalgame_Compiler_Formatter_EmitUnary(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 713 "./src/formatter/formatter.am" if (code_string_equals(n->Str, "await")) { #line 714 "./src/formatter/formatter.am" return code_string_concat("await ", Amalgame_Compiler_Formatter_EmitExpr(self, n->Left)); } #line 716 "./src/formatter/formatter.am" return code_string_concat(n->Str, Amalgame_Compiler_Formatter_EmitExpr(self, n->Left)); } static code_string Amalgame_Compiler_Formatter_EmitCall(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 721 "./src/formatter/formatter.am" if (code_string_equals(n->Name, "__tuple_literal__")) { #line 722 "./src/formatter/formatter.am" code_string t = "("; #line 723 "./src/formatter/formatter.am" i64 c = AmalgameList_count(n->Args); #line 724 "./src/formatter/formatter.am" for (i64 i = 0LL; i < c; i++) { #line 725 "./src/formatter/formatter.am" if (i > 0LL) { t = (code_string_concat(t, ", ")); } #line 726 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* a = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Args, i); #line 727 "./src/formatter/formatter.am" t = (code_string_concat(t, Amalgame_Compiler_Formatter_EmitExpr(self, a))); } #line 729 "./src/formatter/formatter.am" return code_string_concat(t, ")"); } #line 731 "./src/formatter/formatter.am" code_string callee = Amalgame_Compiler_Formatter_EmitExpr(self, n->Left); #line 732 "./src/formatter/formatter.am" code_string s = code_string_concat(callee, "("); #line 733 "./src/formatter/formatter.am" i64 c = AmalgameList_count(n->Args); #line 734 "./src/formatter/formatter.am" for (i64 i = 0LL; i < c; i++) { #line 735 "./src/formatter/formatter.am" if (i > 0LL) { s = (code_string_concat(s, ", ")); } #line 736 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* a = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Args, i); #line 737 "./src/formatter/formatter.am" if (String_Length(a->Str2) > 0LL) { #line 738 "./src/formatter/formatter.am" s = (code_string_concat((code_string_concat((code_string_concat(s, a->Str2)), ": ")), Amalgame_Compiler_Formatter_EmitExpr(self, a))); } else { #line 740 "./src/formatter/formatter.am" s = (code_string_concat(s, Amalgame_Compiler_Formatter_EmitExpr(self, a))); } } #line 743 "./src/formatter/formatter.am" return code_string_concat(s, ")"); } static code_string Amalgame_Compiler_Formatter_EmitMember(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 747 "./src/formatter/formatter.am" code_string base = Amalgame_Compiler_Formatter_EmitExpr(self, n->Left); #line 748 "./src/formatter/formatter.am" code_string sep = (n->Flag ? "?." : "."); #line 749 "./src/formatter/formatter.am" return code_string_concat((code_string_concat(base, sep)), n->Name); } static code_string Amalgame_Compiler_Formatter_EmitIndex(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 753 "./src/formatter/formatter.am" return code_string_concat((code_string_concat((code_string_concat(Amalgame_Compiler_Formatter_EmitExpr(self, n->Left), "[")), Amalgame_Compiler_Formatter_EmitExpr(self, n->Right))), "]"); } static code_string Amalgame_Compiler_Formatter_EmitMatchExpr(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 762 "./src/formatter/formatter.am" code_string s = code_string_concat((code_string_concat("match ", Amalgame_Compiler_Formatter_EmitExpr(self, n->Left))), " { "); #line 763 "./src/formatter/formatter.am" i64 arms = AmalgameList_count(n->Children); #line 764 "./src/formatter/formatter.am" for (i64 i = 0LL; i < arms; i++) { #line 765 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* arm = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, i); #line 766 "./src/formatter/formatter.am" if (i > 0LL) { s = (code_string_concat(s, ", ")); } #line 767 "./src/formatter/formatter.am" s = (code_string_concat(s, Amalgame_Compiler_Formatter_EmitPattern(self, arm->Left))); #line 768 "./src/formatter/formatter.am" if (arm->Cond != NULL) { #line 769 "./src/formatter/formatter.am" s = (code_string_concat((code_string_concat(s, " if ")), Amalgame_Compiler_Formatter_EmitExpr(self, arm->Cond))); } #line 771 "./src/formatter/formatter.am" s = (code_string_concat((code_string_concat(s, " => ")), Amalgame_Compiler_Formatter_EmitExpr(self, arm->Right))); } #line 773 "./src/formatter/formatter.am" return code_string_concat(s, " }"); } static code_string Amalgame_Compiler_Formatter_EmitIfExpr(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 781 "./src/formatter/formatter.am" code_string cond = Amalgame_Compiler_Formatter_EmitExpr(self, n->Cond); #line 782 "./src/formatter/formatter.am" code_string s = code_string_concat((code_string_concat((code_string_concat((code_string_concat("if (", cond)), ") { ")), Amalgame_Compiler_Formatter_EmitBlockAsExpr(self, n->Body))), " }"); #line 783 "./src/formatter/formatter.am" if (n->Else != NULL) { #line 784 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* elseN = n->Else; #line 785 "./src/formatter/formatter.am" if ((elseN->Kind == Amalgame_Compiler_NodeKind_IF_STMT) && (!code_string_equals(elseN->Name, "__match__"))) { #line 786 "./src/formatter/formatter.am" s = (code_string_concat((code_string_concat(s, " else ")), Amalgame_Compiler_Formatter_EmitIfExpr(self, elseN))); } else { #line 788 "./src/formatter/formatter.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " else { ")), Amalgame_Compiler_Formatter_EmitBlockAsExpr(self, elseN))), " }")); } } #line 791 "./src/formatter/formatter.am" return s; } static code_string Amalgame_Compiler_Formatter_EmitLambda(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 798 "./src/formatter/formatter.am" i64 pn = AmalgameList_count(n->Params); #line 799 "./src/formatter/formatter.am" code_string head = ""; #line 800 "./src/formatter/formatter.am" if (pn == 1LL) { #line 801 "./src/formatter/formatter.am" head = Amalgame_Compiler_Formatter_LambdaParamName(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Params, 0LL)); } else { #line 803 "./src/formatter/formatter.am" head = "("; #line 804 "./src/formatter/formatter.am" for (i64 pi = 0LL; pi < pn; pi++) { #line 805 "./src/formatter/formatter.am" if (pi > 0LL) { head = (code_string_concat(head, ", ")); } #line 806 "./src/formatter/formatter.am" head = (code_string_concat(head, Amalgame_Compiler_Formatter_LambdaParamName(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Params, pi)))); } #line 808 "./src/formatter/formatter.am" head = (code_string_concat(head, ")")); } #line 810 "./src/formatter/formatter.am" if (n->Body != NULL) { #line 811 "./src/formatter/formatter.am" return code_string_concat((code_string_concat((code_string_concat(head, " => { ")), Amalgame_Compiler_Formatter_EmitBlockAsExpr(self, n->Body))), " }"); } #line 813 "./src/formatter/formatter.am" if (n->Left != NULL) { #line 814 "./src/formatter/formatter.am" return code_string_concat((code_string_concat(head, " => ")), Amalgame_Compiler_Formatter_EmitExpr(self, n->Left)); } #line 816 "./src/formatter/formatter.am" return code_string_concat(head, " => 0"); } static code_string Amalgame_Compiler_Formatter_LambdaParamName(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* p) { #line 820 "./src/formatter/formatter.am" return p->Name; } static code_string Amalgame_Compiler_Formatter_EmitBlockAsExpr(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* body) { #line 824 "./src/formatter/formatter.am" if (body->Kind != Amalgame_Compiler_NodeKind_BLOCK) { return Amalgame_Compiler_Formatter_EmitExpr(self, body); } #line 825 "./src/formatter/formatter.am" i64 cnt = AmalgameList_count(body->Children); #line 826 "./src/formatter/formatter.am" if (cnt == 0LL) { return ""; } #line 827 "./src/formatter/formatter.am" if (cnt == 1LL) { #line 828 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* s = (Amalgame_Compiler_AstNode*)AmalgameList_get(body->Children, 0LL); #line 829 "./src/formatter/formatter.am" return Amalgame_Compiler_Formatter_EmitExpr(self, s); } #line 831 "./src/formatter/formatter.am" code_string out = ""; #line 832 "./src/formatter/formatter.am" for (i64 i = 0LL; i < cnt; i++) { #line 833 "./src/formatter/formatter.am" if (i > 0LL) { out = (code_string_concat(out, "; ")); } #line 834 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* s = (Amalgame_Compiler_AstNode*)AmalgameList_get(body->Children, i); #line 835 "./src/formatter/formatter.am" out = (code_string_concat(out, Amalgame_Compiler_Formatter_EmitExpr(self, s))); } #line 837 "./src/formatter/formatter.am" return out; } static code_string Amalgame_Compiler_Formatter_EmitNew(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_AstNode* n) { #line 841 "./src/formatter/formatter.am" code_string s = code_string_concat((code_string_concat("new ", n->Name)), "("); #line 842 "./src/formatter/formatter.am" i64 c = AmalgameList_count(n->Args); #line 843 "./src/formatter/formatter.am" for (i64 i = 0LL; i < c; i++) { #line 844 "./src/formatter/formatter.am" if (i > 0LL) { s = (code_string_concat(s, ", ")); } #line 845 "./src/formatter/formatter.am" Amalgame_Compiler_AstNode* a = (Amalgame_Compiler_AstNode*)AmalgameList_get(n->Args, i); #line 846 "./src/formatter/formatter.am" if (String_Length(a->Str2) > 0LL) { #line 847 "./src/formatter/formatter.am" s = (code_string_concat((code_string_concat((code_string_concat(s, a->Str2)), ": ")), Amalgame_Compiler_Formatter_EmitExpr(self, a))); } else { #line 849 "./src/formatter/formatter.am" s = (code_string_concat(s, Amalgame_Compiler_Formatter_EmitExpr(self, a))); } } #line 852 "./src/formatter/formatter.am" return code_string_concat(s, ")"); } static code_string Amalgame_Compiler_Formatter_QuoteString(Amalgame_Compiler_Formatter* self, code_string content) { #line 863 "./src/formatter/formatter.am" i64 len = String_Length(content); #line 864 "./src/formatter/formatter.am" code_string out = "\""; #line 865 "./src/formatter/formatter.am" i64 i = 0LL; #line 866 "./src/formatter/formatter.am" while (i < len) { #line 867 "./src/formatter/formatter.am" code_string ch = String_Substring(content, i, 1LL); #line 868 "./src/formatter/formatter.am" if (code_string_equals(ch, "\\")) { out = (code_string_concat(out, "\\\\")); } else if (code_string_equals(ch, "\"")) { #line 869 "./src/formatter/formatter.am" out = (code_string_concat(out, "\\\"")); } else if (code_string_equals(ch, "\n")) { #line 870 "./src/formatter/formatter.am" out = (code_string_concat(out, "\\n")); } else if (code_string_equals(ch, String_FromByte(13LL))) { #line 871 "./src/formatter/formatter.am" out = (code_string_concat(out, "\\r")); } else if (code_string_equals(ch, "\t")) { #line 872 "./src/formatter/formatter.am" out = (code_string_concat(out, "\\t")); } else { #line 873 "./src/formatter/formatter.am" out = (code_string_concat(out, ch)); } #line 874 "./src/formatter/formatter.am" i = (i + 1LL); } #line 876 "./src/formatter/formatter.am" return code_string_concat(out, "\""); } static code_string Amalgame_Compiler_Formatter_KindName(Amalgame_Compiler_Formatter* self, Amalgame_Compiler_NodeKind k) { #line 881 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_PROGRAM) { return "PROGRAM"; } #line 882 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { return "CLASS_DECL"; } #line 883 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_METHOD_DECL) { return "METHOD_DECL"; } #line 884 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_FIELD_DECL) { return "FIELD_DECL"; } #line 885 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_PARAM) { return "PARAM"; } #line 886 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) { return "ENUM_DECL"; } #line 887 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_BLOCK) { return "BLOCK"; } #line 888 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_VAR_DECL) { return "VAR_DECL"; } #line 889 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_ASSIGN) { return "ASSIGN"; } #line 890 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_RETURN_STMT) { return "RETURN_STMT"; } #line 891 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_IF_STMT) { return "IF_STMT"; } #line 892 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_WHILE_STMT) { return "WHILE_STMT"; } #line 893 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_FOR_IN_STMT) { return "FOR_IN_STMT"; } #line 894 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_BREAK_STMT) { return "BREAK_STMT"; } #line 895 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_CONTINUE_STMT) { return "CONTINUE_STMT"; } #line 896 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_TRY_STMT) { return "TRY_STMT"; } #line 897 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_THROW_STMT) { return "THROW_STMT"; } #line 898 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_BINARY) { return "BINARY"; } #line 899 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_UNARY) { return "UNARY"; } #line 900 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_CALL) { return "CALL"; } #line 901 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_MEMBER) { return "MEMBER"; } #line 902 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { return "IDENTIFIER"; } #line 903 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_INT) { return "LITERAL_INT"; } #line 904 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_FLOAT) { return "LITERAL_FLOAT"; } #line 905 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_STRING) { return "LITERAL_STRING"; } #line 906 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_BOOL) { return "LITERAL_BOOL"; } #line 907 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_NULL) { return "LITERAL_NULL"; } #line 908 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_NEW_EXPR) { return "NEW_EXPR"; } #line 909 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_THIS_EXPR) { return "THIS_EXPR"; } #line 910 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_INDEX_EXPR) { return "INDEX_EXPR"; } #line 911 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LIST_COMP) { return "LIST_COMP"; } #line 912 "./src/formatter/formatter.am" if (k == Amalgame_Compiler_NodeKind_LIST_LITERAL) { return "LIST_LITERAL"; } #line 913 "./src/formatter/formatter.am" return "?"; } struct _Amalgame_Compiler_Ansi { }; code_string Amalgame_Compiler_Ansi_Reset(); code_string Amalgame_Compiler_Ansi_Bold(); code_string Amalgame_Compiler_Ansi_Dim(); code_string Amalgame_Compiler_Ansi_Red(); code_string Amalgame_Compiler_Ansi_Yellow(); code_string Amalgame_Compiler_Ansi_Cyan(); code_string Amalgame_Compiler_Ansi_Green(); code_string Amalgame_Compiler_Ansi_Blue(); code_string Amalgame_Compiler_Ansi_BoldRed(); code_string Amalgame_Compiler_Ansi_BoldYellow(); code_string Amalgame_Compiler_Ansi_BoldCyan(); code_string Amalgame_Compiler_Ansi_BoldGreen(); code_string Amalgame_Compiler_Ansi_BoldBlue(); Amalgame_Compiler_Ansi* Amalgame_Compiler_Ansi_new() { Amalgame_Compiler_Ansi* self = (Amalgame_Compiler_Ansi*) GC_MALLOC(sizeof(Amalgame_Compiler_Ansi)); return self; } code_string Amalgame_Compiler_Ansi_Reset() { #line 12 "./src/diagnostics.am" return "\x1b[0m"; } code_string Amalgame_Compiler_Ansi_Bold() { #line 13 "./src/diagnostics.am" return "\x1b[1m"; } code_string Amalgame_Compiler_Ansi_Dim() { #line 14 "./src/diagnostics.am" return "\x1b[2m"; } code_string Amalgame_Compiler_Ansi_Red() { #line 15 "./src/diagnostics.am" return "\x1b[31m"; } code_string Amalgame_Compiler_Ansi_Yellow() { #line 16 "./src/diagnostics.am" return "\x1b[33m"; } code_string Amalgame_Compiler_Ansi_Cyan() { #line 17 "./src/diagnostics.am" return "\x1b[36m"; } code_string Amalgame_Compiler_Ansi_Green() { #line 18 "./src/diagnostics.am" return "\x1b[32m"; } code_string Amalgame_Compiler_Ansi_Blue() { #line 19 "./src/diagnostics.am" return "\x1b[34m"; } code_string Amalgame_Compiler_Ansi_BoldRed() { #line 20 "./src/diagnostics.am" return "\x1b[1;31m"; } code_string Amalgame_Compiler_Ansi_BoldYellow() { #line 21 "./src/diagnostics.am" return "\x1b[1;33m"; } code_string Amalgame_Compiler_Ansi_BoldCyan() { #line 22 "./src/diagnostics.am" return "\x1b[1;36m"; } code_string Amalgame_Compiler_Ansi_BoldGreen() { #line 23 "./src/diagnostics.am" return "\x1b[1;32m"; } code_string Amalgame_Compiler_Ansi_BoldBlue() { #line 24 "./src/diagnostics.am" return "\x1b[1;34m"; } struct _Amalgame_Compiler_SourceMap { AmalgameList* Paths; AmalgameList* Texts; AmalgameList* LineCache; AmalgameList* LineSplit; }; void Amalgame_Compiler_SourceMap_Add(Amalgame_Compiler_SourceMap* self, code_string path, code_string text); code_string Amalgame_Compiler_SourceMap_GetLine(Amalgame_Compiler_SourceMap* self, code_string path, i64 line); Amalgame_Compiler_SourceMap* Amalgame_Compiler_SourceMap_new() { Amalgame_Compiler_SourceMap* self = (Amalgame_Compiler_SourceMap*) GC_MALLOC(sizeof(Amalgame_Compiler_SourceMap)); #line 46 "./src/diagnostics.am" self->Paths = AmalgameList_new(); #line 47 "./src/diagnostics.am" self->Texts = AmalgameList_new(); #line 48 "./src/diagnostics.am" self->LineCache = AmalgameList_new(); #line 49 "./src/diagnostics.am" self->LineSplit = AmalgameList_new(); return self; } void Amalgame_Compiler_SourceMap_Add(Amalgame_Compiler_SourceMap* self, code_string path, code_string text) { #line 53 "./src/diagnostics.am" i64 count = AmalgameList_count(self->Paths); #line 54 "./src/diagnostics.am" for (i64 i = 0LL; i < count; i++) { #line 55 "./src/diagnostics.am" if (code_string_equals((code_string)AmalgameList_get(self->Paths, i), path)) { return; } } #line 57 "./src/diagnostics.am" AmalgameList_add(self->Paths, (void*)(intptr_t)(path)); #line 58 "./src/diagnostics.am" AmalgameList_add(self->Texts, (void*)(intptr_t)(text)); #line 59 "./src/diagnostics.am" AmalgameList_add(self->LineCache, (void*)(intptr_t)(AmalgameList_new())); #line 60 "./src/diagnostics.am" AmalgameList_add(self->LineSplit, (void*)(intptr_t)(0)); } code_string Amalgame_Compiler_SourceMap_GetLine(Amalgame_Compiler_SourceMap* self, code_string path, i64 line) { #line 65 "./src/diagnostics.am" i64 count = AmalgameList_count(self->Paths); #line 66 "./src/diagnostics.am" for (i64 i = 0LL; i < count; i++) { #line 67 "./src/diagnostics.am" if (code_string_equals((code_string)AmalgameList_get(self->Paths, i), path)) { #line 68 "./src/diagnostics.am" if (!(code_bool)(intptr_t)AmalgameList_get(self->LineSplit, i)) { #line 69 "./src/diagnostics.am" AmalgameList_set(self->LineCache, i, (void*)(intptr_t)(String_Split((code_string)AmalgameList_get(self->Texts, i), "\n"))); #line 70 "./src/diagnostics.am" AmalgameList_set(self->LineSplit, i, (void*)(intptr_t)(1)); } #line 72 "./src/diagnostics.am" AmalgameList* lines = (AmalgameList*)AmalgameList_get(self->LineCache, i); #line 73 "./src/diagnostics.am" i64 idx = line - 1LL; #line 74 "./src/diagnostics.am" if ((idx < 0LL) || (idx >= AmalgameList_count(lines))) { return ""; } #line 75 "./src/diagnostics.am" return (code_string)AmalgameList_get(lines, idx); } } #line 78 "./src/diagnostics.am" return ""; } struct _Amalgame_Compiler_SourceSnippet { }; code_string Amalgame_Compiler_SourceSnippet_Format(code_string lineText, i64 line, i64 col); static code_string Amalgame_Compiler_SourceSnippet_Spaces(i64 n); Amalgame_Compiler_SourceSnippet* Amalgame_Compiler_SourceSnippet_new() { Amalgame_Compiler_SourceSnippet* self = (Amalgame_Compiler_SourceSnippet*) GC_MALLOC(sizeof(Amalgame_Compiler_SourceSnippet)); return self; } code_string Amalgame_Compiler_SourceSnippet_Format(code_string lineText, i64 line, i64 col) { #line 91 "./src/diagnostics.am" if (String_Length(lineText) == 0LL) { return ""; } #line 92 "./src/diagnostics.am" code_string lineNum = String_FromInt(line); #line 93 "./src/diagnostics.am" code_string pad = Amalgame_Compiler_SourceSnippet_Spaces(String_Length(lineNum)); #line 94 "./src/diagnostics.am" code_string caret = ""; #line 95 "./src/diagnostics.am" i64 c = 0LL; #line 96 "./src/diagnostics.am" while (c < (col - 1LL)) { #line 97 "./src/diagnostics.am" caret = (code_string_concat(caret, " ")); #line 98 "./src/diagnostics.am" c = (c + 1LL); } #line 100 "./src/diagnostics.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(pad, " |\n")), lineNum)), " | ")), lineText)), "\n")), pad)), " | ")), caret)), "^\n"); } static code_string Amalgame_Compiler_SourceSnippet_Spaces(i64 n) { #line 104 "./src/diagnostics.am" code_string s = ""; #line 105 "./src/diagnostics.am" i64 i = 0LL; #line 106 "./src/diagnostics.am" while (i < n) { #line 107 "./src/diagnostics.am" s = (code_string_concat(s, " ")); #line 108 "./src/diagnostics.am" i = (i + 1LL); } #line 110 "./src/diagnostics.am" return s; } enum _Amalgame_Compiler_DiagSeverity { Amalgame_Compiler_DiagSeverity_ERROR, Amalgame_Compiler_DiagSeverity_WARNING, Amalgame_Compiler_DiagSeverity_NOTE, Amalgame_Compiler_DiagSeverity_HINT }; struct _Amalgame_Compiler_Diagnostic { Amalgame_Compiler_DiagSeverity Severity; code_string Kind; code_string Message; code_string Filename; i64 Line; i64 Column; }; Amalgame_Compiler_Diagnostic* Amalgame_Compiler_Diagnostic_new(Amalgame_Compiler_DiagSeverity sev, code_string kind, code_string msg, code_string file, i64 line, i64 col) { Amalgame_Compiler_Diagnostic* self = (Amalgame_Compiler_Diagnostic*) GC_MALLOC(sizeof(Amalgame_Compiler_Diagnostic)); #line 133 "./src/diagnostics.am" self->Severity = sev; #line 134 "./src/diagnostics.am" self->Kind = kind; #line 135 "./src/diagnostics.am" self->Message = msg; #line 136 "./src/diagnostics.am" self->Filename = file; #line 137 "./src/diagnostics.am" self->Line = line; #line 138 "./src/diagnostics.am" self->Column = col; return self; } struct _Amalgame_Compiler_DiagnosticFormatter { code_bool UseColor; code_bool Quiet; Amalgame_Compiler_SourceMap* Sources; }; void Amalgame_Compiler_DiagnosticFormatter_EnableColor(Amalgame_Compiler_DiagnosticFormatter* self, code_bool v); void Amalgame_Compiler_DiagnosticFormatter_SetQuiet(Amalgame_Compiler_DiagnosticFormatter* self, code_bool v); void Amalgame_Compiler_DiagnosticFormatter_LoadSource(Amalgame_Compiler_DiagnosticFormatter* self, code_string path, code_string text); static code_string Amalgame_Compiler_DiagnosticFormatter_SevLabel(Amalgame_Compiler_DiagnosticFormatter* self, Amalgame_Compiler_DiagSeverity sev); code_string Amalgame_Compiler_DiagnosticFormatter_FormatDiag(Amalgame_Compiler_DiagnosticFormatter* self, Amalgame_Compiler_Diagnostic* d); code_string Amalgame_Compiler_DiagnosticFormatter_FormatError(Amalgame_Compiler_DiagnosticFormatter* self, code_string kind, code_string message, code_string filename, i64 line, i64 col); code_string Amalgame_Compiler_DiagnosticFormatter_FormatWarning(Amalgame_Compiler_DiagnosticFormatter* self, code_string kind, code_string message, code_string filename, i64 line, i64 col); code_string Amalgame_Compiler_DiagnosticFormatter_FormatNote(Amalgame_Compiler_DiagnosticFormatter* self, code_string kind, code_string message, code_string filename, i64 line, i64 col); void Amalgame_Compiler_DiagnosticFormatter_PrintPhaseOk(Amalgame_Compiler_DiagnosticFormatter* self, code_string phase); void Amalgame_Compiler_DiagnosticFormatter_PrintPhaseError(Amalgame_Compiler_DiagnosticFormatter* self, code_string phase, code_string detail); void Amalgame_Compiler_DiagnosticFormatter_PrintCompileOk(Amalgame_Compiler_DiagnosticFormatter* self, code_string phase); void Amalgame_Compiler_DiagnosticFormatter_PrintCompileError(Amalgame_Compiler_DiagnosticFormatter* self, code_string phase, code_string detail); code_string Amalgame_Compiler_DiagnosticFormatter_FormatSummary(Amalgame_Compiler_DiagnosticFormatter* self, i64 errorCount, i64 warningCount); code_string Amalgame_Compiler_DiagnosticFormatter_FormatCompact(Amalgame_Compiler_DiagnosticFormatter* self, code_string severity, code_string kind, code_string message, code_string filename, i64 line, i64 col); Amalgame_Compiler_DiagnosticFormatter* Amalgame_Compiler_DiagnosticFormatter_new() { Amalgame_Compiler_DiagnosticFormatter* self = (Amalgame_Compiler_DiagnosticFormatter*) GC_MALLOC(sizeof(Amalgame_Compiler_DiagnosticFormatter)); #line 149 "./src/diagnostics.am" self->UseColor = 0; #line 150 "./src/diagnostics.am" self->Quiet = 0; #line 151 "./src/diagnostics.am" self->Sources = Amalgame_Compiler_SourceMap_new(); return self; } void Amalgame_Compiler_DiagnosticFormatter_EnableColor(Amalgame_Compiler_DiagnosticFormatter* self, code_bool v) { #line 154 "./src/diagnostics.am" self->UseColor = v; } void Amalgame_Compiler_DiagnosticFormatter_SetQuiet(Amalgame_Compiler_DiagnosticFormatter* self, code_bool v) { #line 155 "./src/diagnostics.am" self->Quiet = v; } void Amalgame_Compiler_DiagnosticFormatter_LoadSource(Amalgame_Compiler_DiagnosticFormatter* self, code_string path, code_string text) { #line 158 "./src/diagnostics.am" Amalgame_Compiler_SourceMap_Add(self->Sources, path, text); } static code_string Amalgame_Compiler_DiagnosticFormatter_SevLabel(Amalgame_Compiler_DiagnosticFormatter* self, Amalgame_Compiler_DiagSeverity sev) { #line 164 "./src/diagnostics.am" if (sev == Amalgame_Compiler_DiagSeverity_ERROR) { return "error"; } #line 165 "./src/diagnostics.am" if (sev == Amalgame_Compiler_DiagSeverity_WARNING) { return "warning"; } #line 166 "./src/diagnostics.am" if (sev == Amalgame_Compiler_DiagSeverity_NOTE) { return "note"; } #line 167 "./src/diagnostics.am" return "hint"; } code_string Amalgame_Compiler_DiagnosticFormatter_FormatDiag(Amalgame_Compiler_DiagnosticFormatter* self, Amalgame_Compiler_Diagnostic* d) { #line 173 "./src/diagnostics.am" code_string lineStr = String_FromInt(d->Line); #line 174 "./src/diagnostics.am" code_string colStr = String_FromInt(d->Column); #line 175 "./src/diagnostics.am" code_string label = Amalgame_Compiler_DiagnosticFormatter_SevLabel(self, d->Severity); #line 176 "./src/diagnostics.am" code_string header = code_string_concat((code_string_concat((code_string_concat((code_string_concat(label, "[")), d->Kind)), "]: ")), d->Message); #line 177 "./src/diagnostics.am" code_string location = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(" --> ", d->Filename)), ":")), lineStr)), ":")), colStr); #line 178 "./src/diagnostics.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("\n", header)), "\n")), location)), "\n |\n"); } code_string Amalgame_Compiler_DiagnosticFormatter_FormatError(Amalgame_Compiler_DiagnosticFormatter* self, code_string kind, code_string message, code_string filename, i64 line, i64 col) { #line 183 "./src/diagnostics.am" Amalgame_Compiler_Diagnostic* d = Amalgame_Compiler_Diagnostic_new(Amalgame_Compiler_DiagSeverity_ERROR, kind, message, filename, line, col); #line 184 "./src/diagnostics.am" return Amalgame_Compiler_DiagnosticFormatter_FormatDiag(self, d); } code_string Amalgame_Compiler_DiagnosticFormatter_FormatWarning(Amalgame_Compiler_DiagnosticFormatter* self, code_string kind, code_string message, code_string filename, i64 line, i64 col) { #line 189 "./src/diagnostics.am" Amalgame_Compiler_Diagnostic* d = Amalgame_Compiler_Diagnostic_new(Amalgame_Compiler_DiagSeverity_WARNING, kind, message, filename, line, col); #line 190 "./src/diagnostics.am" return Amalgame_Compiler_DiagnosticFormatter_FormatDiag(self, d); } code_string Amalgame_Compiler_DiagnosticFormatter_FormatNote(Amalgame_Compiler_DiagnosticFormatter* self, code_string kind, code_string message, code_string filename, i64 line, i64 col) { #line 195 "./src/diagnostics.am" Amalgame_Compiler_Diagnostic* d = Amalgame_Compiler_Diagnostic_new(Amalgame_Compiler_DiagSeverity_NOTE, kind, message, filename, line, col); #line 196 "./src/diagnostics.am" return Amalgame_Compiler_DiagnosticFormatter_FormatDiag(self, d); } void Amalgame_Compiler_DiagnosticFormatter_PrintPhaseOk(Amalgame_Compiler_DiagnosticFormatter* self, code_string phase) { #line 202 "./src/diagnostics.am" if (self->Quiet) { return; } #line 203 "./src/diagnostics.am" Console_WriteLine(code_string_concat(phase, " OK")); } void Amalgame_Compiler_DiagnosticFormatter_PrintPhaseError(Amalgame_Compiler_DiagnosticFormatter* self, code_string phase, code_string detail) { #line 207 "./src/diagnostics.am" Console_WriteError(code_string_concat(phase, " ERROR")); #line 208 "./src/diagnostics.am" if (String_Length(detail) > 0LL) { Console_WriteError(detail); } } void Amalgame_Compiler_DiagnosticFormatter_PrintCompileOk(Amalgame_Compiler_DiagnosticFormatter* self, code_string phase) { #line 213 "./src/diagnostics.am" Amalgame_Compiler_DiagnosticFormatter_PrintPhaseOk(self, phase); } void Amalgame_Compiler_DiagnosticFormatter_PrintCompileError(Amalgame_Compiler_DiagnosticFormatter* self, code_string phase, code_string detail) { #line 217 "./src/diagnostics.am" Amalgame_Compiler_DiagnosticFormatter_PrintPhaseError(self, phase, detail); } code_string Amalgame_Compiler_DiagnosticFormatter_FormatSummary(Amalgame_Compiler_DiagnosticFormatter* self, i64 errorCount, i64 warningCount) { #line 223 "./src/diagnostics.am" code_string result = " "; #line 224 "./src/diagnostics.am" if (errorCount > 0LL) { #line 225 "./src/diagnostics.am" code_string ec = String_FromInt(errorCount); #line 226 "./src/diagnostics.am" code_string sfx = (errorCount > 1LL ? "s" : " "); #line 227 "./src/diagnostics.am" result = (code_string_concat((code_string_concat((code_string_concat("aborting due to ", ec)), " error")), sfx)); } #line 229 "./src/diagnostics.am" return result; } code_string Amalgame_Compiler_DiagnosticFormatter_FormatCompact(Amalgame_Compiler_DiagnosticFormatter* self, code_string severity, code_string kind, code_string message, code_string filename, i64 line, i64 col) { #line 234 "./src/diagnostics.am" code_string loc = code_string_concat((code_string_concat((code_string_concat((code_string_concat(filename, ":")), String_FromInt(line))), ":")), String_FromInt(col)); #line 235 "./src/diagnostics.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(loc, ": ")), severity)), "[")), kind)), "]: ")), message); } enum _Amalgame_Compiler_SymKind { Amalgame_Compiler_SymKind_CLASS, Amalgame_Compiler_SymKind_ENUM, Amalgame_Compiler_SymKind_METHOD, Amalgame_Compiler_SymKind_FIELD, Amalgame_Compiler_SymKind_PARAM, Amalgame_Compiler_SymKind_LOCAL, Amalgame_Compiler_SymKind_BUILTIN }; struct _Amalgame_Compiler_Symbol { code_string Name; Amalgame_Compiler_SymKind Kind; code_string TypeName; code_bool IsPublic; code_bool IsStatic; }; Amalgame_Compiler_Symbol* Amalgame_Compiler_Symbol_new(code_string name, Amalgame_Compiler_SymKind kind) { Amalgame_Compiler_Symbol* self = (Amalgame_Compiler_Symbol*) GC_MALLOC(sizeof(Amalgame_Compiler_Symbol)); #line 26 "./src/resolver/symbol.am" self->Name = name; #line 27 "./src/resolver/symbol.am" self->Kind = kind; #line 28 "./src/resolver/symbol.am" self->TypeName = ""; #line 29 "./src/resolver/symbol.am" self->IsPublic = 0; #line 30 "./src/resolver/symbol.am" self->IsStatic = 0; return self; } struct _Amalgame_Compiler_SymbolTable { AmalgameList* Symbols; Amalgame_Compiler_SymbolTable* Parent; }; void Amalgame_Compiler_SymbolTable_Declare(Amalgame_Compiler_SymbolTable* self, Amalgame_Compiler_Symbol* sym); code_bool Amalgame_Compiler_SymbolTable_Has(Amalgame_Compiler_SymbolTable* self, code_string name); Amalgame_Compiler_Symbol* Amalgame_Compiler_SymbolTable_Lookup(Amalgame_Compiler_SymbolTable* self, code_string name); code_bool Amalgame_Compiler_SymbolTable_HasSymbol(Amalgame_Compiler_SymbolTable* self, code_string name); code_string Amalgame_Compiler_SymbolTable_GetTypeName(Amalgame_Compiler_SymbolTable* self, code_string name); void Amalgame_Compiler_SymbolTable_SetTypeName(Amalgame_Compiler_SymbolTable* self, code_string name, code_string typeName); Amalgame_Compiler_SymbolTable* Amalgame_Compiler_SymbolTable_new() { Amalgame_Compiler_SymbolTable* self = (Amalgame_Compiler_SymbolTable*) GC_MALLOC(sizeof(Amalgame_Compiler_SymbolTable)); #line 40 "./src/resolver/symbol.am" self->Symbols = AmalgameList_new(); return self; } void Amalgame_Compiler_SymbolTable_Declare(Amalgame_Compiler_SymbolTable* self, Amalgame_Compiler_Symbol* sym) { #line 44 "./src/resolver/symbol.am" AmalgameList_add(self->Symbols, (void*)(intptr_t)(sym)); } code_bool Amalgame_Compiler_SymbolTable_Has(Amalgame_Compiler_SymbolTable* self, code_string name) { #line 48 "./src/resolver/symbol.am" i64 count = AmalgameList_count(self->Symbols); #line 49 "./src/resolver/symbol.am" for (i64 i = 0LL; i < count; i++) { #line 50 "./src/resolver/symbol.am" Amalgame_Compiler_Symbol* sym = (Amalgame_Compiler_Symbol*)AmalgameList_get(self->Symbols, i); #line 51 "./src/resolver/symbol.am" if (code_string_equals(sym->Name, name)) { return 1; } } #line 53 "./src/resolver/symbol.am" return 0; } Amalgame_Compiler_Symbol* Amalgame_Compiler_SymbolTable_Lookup(Amalgame_Compiler_SymbolTable* self, code_string name) { #line 57 "./src/resolver/symbol.am" i64 count = AmalgameList_count(self->Symbols); #line 58 "./src/resolver/symbol.am" for (i64 i = 0LL; i < count; i++) { #line 59 "./src/resolver/symbol.am" Amalgame_Compiler_Symbol* sym = (Amalgame_Compiler_Symbol*)AmalgameList_get(self->Symbols, i); #line 60 "./src/resolver/symbol.am" if (code_string_equals(sym->Name, name)) { return sym; } } #line 62 "./src/resolver/symbol.am" return Amalgame_Compiler_Symbol_new("_not_found_", Amalgame_Compiler_SymKind_BUILTIN); } code_bool Amalgame_Compiler_SymbolTable_HasSymbol(Amalgame_Compiler_SymbolTable* self, code_string name) { #line 68 "./src/resolver/symbol.am" i64 count = AmalgameList_count(self->Symbols); #line 69 "./src/resolver/symbol.am" for (i64 i = 0LL; i < count; i++) { #line 70 "./src/resolver/symbol.am" Amalgame_Compiler_Symbol* sym = (Amalgame_Compiler_Symbol*)AmalgameList_get(self->Symbols, i); #line 71 "./src/resolver/symbol.am" if (code_string_equals(sym->Name, name)) { return 1; } } #line 73 "./src/resolver/symbol.am" return 0; } code_string Amalgame_Compiler_SymbolTable_GetTypeName(Amalgame_Compiler_SymbolTable* self, code_string name) { #line 77 "./src/resolver/symbol.am" i64 count = AmalgameList_count(self->Symbols); #line 78 "./src/resolver/symbol.am" for (i64 i = 0LL; i < count; i++) { #line 79 "./src/resolver/symbol.am" Amalgame_Compiler_Symbol* sym = (Amalgame_Compiler_Symbol*)AmalgameList_get(self->Symbols, i); #line 80 "./src/resolver/symbol.am" if (code_string_equals(sym->Name, name)) { return sym->TypeName; } } #line 82 "./src/resolver/symbol.am" return "?"; } void Amalgame_Compiler_SymbolTable_SetTypeName(Amalgame_Compiler_SymbolTable* self, code_string name, code_string typeName) { #line 86 "./src/resolver/symbol.am" i64 count = AmalgameList_count(self->Symbols); #line 87 "./src/resolver/symbol.am" for (i64 i = 0LL; i < count; i++) { #line 88 "./src/resolver/symbol.am" Amalgame_Compiler_Symbol* sym = (Amalgame_Compiler_Symbol*)AmalgameList_get(self->Symbols, i); #line 89 "./src/resolver/symbol.am" if (code_string_equals(sym->Name, name)) { #line 90 "./src/resolver/symbol.am" if (String_Length(sym->TypeName) == 0LL) { #line 91 "./src/resolver/symbol.am" sym->TypeName = typeName; } #line 93 "./src/resolver/symbol.am" return; } } } struct _Amalgame_Compiler_Resolver { Amalgame_Compiler_SymbolTable* Global; AmalgameList* Errors; Amalgame_Compiler_SymbolTable* Current; AmalgameList* Programs; }; static void Amalgame_Compiler_Resolver_RegisterBuiltins(Amalgame_Compiler_Resolver* self); void Amalgame_Compiler_Resolver_Resolve(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* prog); void Amalgame_Compiler_Resolver_ResolvePrograms(Amalgame_Compiler_Resolver* self); code_bool Amalgame_Compiler_Resolver_HasErrors(Amalgame_Compiler_Resolver* self); code_string Amalgame_Compiler_Resolver_GetErrors(Amalgame_Compiler_Resolver* self); static void Amalgame_Compiler_Resolver_CollectDecl(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_Resolver_ResolveDecl(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_Resolver_ResolveClass(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* cls); static void Amalgame_Compiler_Resolver_ResolveMethod(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* method, Amalgame_Compiler_SymbolTable* classScope); static void Amalgame_Compiler_Resolver_ResolveBlock(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* block); static void Amalgame_Compiler_Resolver_ResolveStmt(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_Resolver_ResolveExpr(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* expr); static code_bool Amalgame_Compiler_Resolver_LookupInScopes(Amalgame_Compiler_Resolver* self, code_string name); Amalgame_Compiler_Resolver* Amalgame_Compiler_Resolver_new() { Amalgame_Compiler_Resolver* self = (Amalgame_Compiler_Resolver*) GC_MALLOC(sizeof(Amalgame_Compiler_Resolver)); #line 107 "./src/resolver/symbol.am" self->Global = Amalgame_Compiler_SymbolTable_new(); #line 108 "./src/resolver/symbol.am" self->Errors = AmalgameList_new(); #line 109 "./src/resolver/symbol.am" self->Current = self->Global; #line 110 "./src/resolver/symbol.am" self->Programs = AmalgameList_new(); #line 111 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_RegisterBuiltins(self); return self; } static void Amalgame_Compiler_Resolver_RegisterBuiltins(Amalgame_Compiler_Resolver* self) { #line 115 "./src/resolver/symbol.am" AmalgameList* builtins = AmalgameList_new(); #line 117 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("Console")); #line 118 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("Mcu")); #line 119 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("File")); #line 120 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("Path")); #line 121 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("Math")); #line 122 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("Vec3")); #line 123 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("Vec4")); #line 124 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("Mat4")); #line 125 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("FileWatcher")); #line 126 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("Regex")); #line 127 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("Match")); #line 128 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("Compress")); #line 129 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("WebSocket")); #line 130 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String")); #line 132 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("int")); #line 133 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("string")); #line 134 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("bool")); #line 135 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("float")); #line 136 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("void")); #line 138 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_Length")); #line 139 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_Contains")); #line 140 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_StartsWith")); #line 141 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_EndsWith")); #line 142 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_Substring")); #line 143 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_ToUpper")); #line 144 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_ToLower")); #line 145 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_Trim")); #line 146 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_Replace")); #line 147 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_IndexOf")); #line 148 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_FromInt")); #line 149 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_ToInt")); #line 150 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_IsEmpty")); #line 151 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("String_From")); #line 153 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("File_ReadAll")); #line 154 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("File_WriteAll")); #line 155 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("File_Exists")); #line 156 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("File_Delete")); #line 157 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("File_Size")); #line 158 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("File_Mtime")); #line 159 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("File_IsFile")); #line 160 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("File_IsDir")); #line 164 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("null")); #line 165 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("true")); #line 166 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("false")); #line 167 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("this")); #line 168 "./src/resolver/symbol.am" AmalgameList_add(builtins, (void*)(intptr_t)("args")); #line 169 "./src/resolver/symbol.am" i64 count = AmalgameList_count(builtins); #line 170 "./src/resolver/symbol.am" for (i64 i = 0LL; i < count; i++) { #line 171 "./src/resolver/symbol.am" code_string name = (code_string)AmalgameList_get(builtins, i); #line 172 "./src/resolver/symbol.am" Amalgame_Compiler_Symbol* sym = Amalgame_Compiler_Symbol_new(name, Amalgame_Compiler_SymKind_BUILTIN); #line 173 "./src/resolver/symbol.am" Amalgame_Compiler_SymbolTable_Declare(self->Global, sym); } } void Amalgame_Compiler_Resolver_Resolve(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* prog) { #line 179 "./src/resolver/symbol.am" i64 decls = AmalgameList_count(prog->Children); #line 180 "./src/resolver/symbol.am" for (i64 i = 0LL; i < decls; i++) { #line 181 "./src/resolver/symbol.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i); #line 182 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_CollectDecl(self, decl); } #line 185 "./src/resolver/symbol.am" for (i64 j = 0LL; j < decls; j++) { #line 186 "./src/resolver/symbol.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, j); #line 187 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveDecl(self, decl); } } void Amalgame_Compiler_Resolver_ResolvePrograms(Amalgame_Compiler_Resolver* self) { #line 192 "./src/resolver/symbol.am" i64 progCount = AmalgameList_count(self->Programs); #line 194 "./src/resolver/symbol.am" for (i64 p = 0LL; p < progCount; p++) { #line 195 "./src/resolver/symbol.am" Amalgame_Compiler_AstNode* prog = (Amalgame_Compiler_AstNode*)AmalgameList_get(self->Programs, p); #line 196 "./src/resolver/symbol.am" i64 decls = AmalgameList_count(prog->Children); #line 197 "./src/resolver/symbol.am" for (i64 i = 0LL; i < decls; i++) { #line 198 "./src/resolver/symbol.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i); #line 199 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_CollectDecl(self, decl); } } #line 203 "./src/resolver/symbol.am" for (i64 p2 = 0LL; p2 < progCount; p2++) { #line 204 "./src/resolver/symbol.am" Amalgame_Compiler_AstNode* prog2 = (Amalgame_Compiler_AstNode*)AmalgameList_get(self->Programs, p2); #line 205 "./src/resolver/symbol.am" i64 decls2 = AmalgameList_count(prog2->Children); #line 206 "./src/resolver/symbol.am" for (i64 j = 0LL; j < decls2; j++) { #line 207 "./src/resolver/symbol.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog2->Children, j); #line 208 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveDecl(self, decl); } } } code_bool Amalgame_Compiler_Resolver_HasErrors(Amalgame_Compiler_Resolver* self) { #line 214 "./src/resolver/symbol.am" return AmalgameList_count(self->Errors) > 0LL; } code_string Amalgame_Compiler_Resolver_GetErrors(Amalgame_Compiler_Resolver* self) { #line 218 "./src/resolver/symbol.am" code_string result = ""; #line 219 "./src/resolver/symbol.am" i64 count = AmalgameList_count(self->Errors); #line 220 "./src/resolver/symbol.am" for (i64 i = 0LL; i < count; i++) { #line 221 "./src/resolver/symbol.am" code_string e = (code_string)AmalgameList_get(self->Errors, i); #line 222 "./src/resolver/symbol.am" result = (code_string_concat((code_string_concat(result, e)), "\n")); } #line 224 "./src/resolver/symbol.am" return result; } static void Amalgame_Compiler_Resolver_CollectDecl(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* decl) { #line 230 "./src/resolver/symbol.am" Amalgame_Compiler_NodeKind k = decl->Kind; #line 231 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { #line 232 "./src/resolver/symbol.am" Amalgame_Compiler_Symbol* sym = Amalgame_Compiler_Symbol_new(decl->Name, Amalgame_Compiler_SymKind_CLASS); #line 233 "./src/resolver/symbol.am" sym->IsPublic = decl->Flag; #line 234 "./src/resolver/symbol.am" Amalgame_Compiler_SymbolTable_Declare(self->Global, sym); } #line 236 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) { #line 237 "./src/resolver/symbol.am" Amalgame_Compiler_Symbol* esym = Amalgame_Compiler_Symbol_new(decl->Name, Amalgame_Compiler_SymKind_ENUM); #line 238 "./src/resolver/symbol.am" esym->IsPublic = decl->Flag; #line 239 "./src/resolver/symbol.am" Amalgame_Compiler_SymbolTable_Declare(self->Global, esym); } } static void Amalgame_Compiler_Resolver_ResolveDecl(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* decl) { #line 246 "./src/resolver/symbol.am" Amalgame_Compiler_NodeKind k = decl->Kind; #line 247 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { #line 248 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveClass(self, decl); } } static void Amalgame_Compiler_Resolver_ResolveClass(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* cls) { #line 254 "./src/resolver/symbol.am" Amalgame_Compiler_SymbolTable* classScope = Amalgame_Compiler_SymbolTable_new(); #line 255 "./src/resolver/symbol.am" classScope->Parent = self->Global; #line 256 "./src/resolver/symbol.am" Amalgame_Compiler_SymbolTable* prev = self->Current; #line 257 "./src/resolver/symbol.am" self->Current = classScope; #line 260 "./src/resolver/symbol.am" i64 members = AmalgameList_count(cls->Children); #line 261 "./src/resolver/symbol.am" for (i64 i = 0LL; i < members; i++) { #line 262 "./src/resolver/symbol.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, i); #line 263 "./src/resolver/symbol.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 264 "./src/resolver/symbol.am" if (mk == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 265 "./src/resolver/symbol.am" Amalgame_Compiler_Symbol* fsym = Amalgame_Compiler_Symbol_new(m->Name, Amalgame_Compiler_SymKind_FIELD); #line 266 "./src/resolver/symbol.am" fsym->TypeName = m->Str; #line 267 "./src/resolver/symbol.am" fsym->IsPublic = m->Flag; #line 268 "./src/resolver/symbol.am" Amalgame_Compiler_SymbolTable_Declare(classScope, fsym); } #line 270 "./src/resolver/symbol.am" if (mk == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 271 "./src/resolver/symbol.am" Amalgame_Compiler_Symbol* msym = Amalgame_Compiler_Symbol_new(m->Name, Amalgame_Compiler_SymKind_METHOD); #line 272 "./src/resolver/symbol.am" msym->TypeName = m->Str; #line 273 "./src/resolver/symbol.am" msym->IsPublic = m->Flag; #line 274 "./src/resolver/symbol.am" msym->IsStatic = m->Flag2; #line 275 "./src/resolver/symbol.am" Amalgame_Compiler_SymbolTable_Declare(classScope, msym); } } #line 280 "./src/resolver/symbol.am" for (i64 j = 0LL; j < members; j++) { #line 281 "./src/resolver/symbol.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, j); #line 282 "./src/resolver/symbol.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 283 "./src/resolver/symbol.am" if (mk == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 284 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveMethod(self, m, classScope); } } #line 288 "./src/resolver/symbol.am" self->Current = prev; } static void Amalgame_Compiler_Resolver_ResolveMethod(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* method, Amalgame_Compiler_SymbolTable* classScope) { #line 292 "./src/resolver/symbol.am" Amalgame_Compiler_SymbolTable* methodScope = Amalgame_Compiler_SymbolTable_new(); #line 293 "./src/resolver/symbol.am" methodScope->Parent = classScope; #line 294 "./src/resolver/symbol.am" Amalgame_Compiler_SymbolTable* prev = self->Current; #line 295 "./src/resolver/symbol.am" self->Current = methodScope; #line 298 "./src/resolver/symbol.am" i64 params = AmalgameList_count(method->Params); #line 299 "./src/resolver/symbol.am" for (i64 i = 0LL; i < params; i++) { #line 300 "./src/resolver/symbol.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 301 "./src/resolver/symbol.am" Amalgame_Compiler_Symbol* psym = Amalgame_Compiler_Symbol_new(p->Name, Amalgame_Compiler_SymKind_PARAM); #line 302 "./src/resolver/symbol.am" psym->TypeName = p->Str; #line 303 "./src/resolver/symbol.am" Amalgame_Compiler_SymbolTable_Declare(methodScope, psym); } #line 307 "./src/resolver/symbol.am" if (method->Body != NULL) { #line 308 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveBlock(self, method->Body); } #line 311 "./src/resolver/symbol.am" self->Current = prev; } static void Amalgame_Compiler_Resolver_ResolveBlock(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* block) { #line 315 "./src/resolver/symbol.am" i64 stmts = AmalgameList_count(block->Children); #line 316 "./src/resolver/symbol.am" for (i64 i = 0LL; i < stmts; i++) { #line 317 "./src/resolver/symbol.am" Amalgame_Compiler_AstNode* stmt = (Amalgame_Compiler_AstNode*)AmalgameList_get(block->Children, i); #line 318 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveStmt(self, stmt); } } static void Amalgame_Compiler_Resolver_ResolveStmt(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* stmt) { #line 323 "./src/resolver/symbol.am" Amalgame_Compiler_NodeKind k = stmt->Kind; #line 324 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 325 "./src/resolver/symbol.am" if (stmt->Left != NULL) { #line 326 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveExpr(self, stmt->Left); } #line 328 "./src/resolver/symbol.am" Amalgame_Compiler_Symbol* vsym = Amalgame_Compiler_Symbol_new(stmt->Name, Amalgame_Compiler_SymKind_LOCAL); #line 329 "./src/resolver/symbol.am" vsym->TypeName = stmt->Str; #line 330 "./src/resolver/symbol.am" Amalgame_Compiler_SymbolTable_Declare(self->Current, vsym); } #line 332 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_RETURN_STMT) { #line 333 "./src/resolver/symbol.am" if (stmt->Left != NULL) { #line 334 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveExpr(self, stmt->Left); } } #line 337 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_IF_STMT) { #line 338 "./src/resolver/symbol.am" if (stmt->Cond != NULL) { Amalgame_Compiler_Resolver_ResolveExpr(self, stmt->Cond); } #line 339 "./src/resolver/symbol.am" if (stmt->Body != NULL) { Amalgame_Compiler_Resolver_ResolveBlock(self, stmt->Body); } #line 340 "./src/resolver/symbol.am" if (stmt->Else != NULL) { Amalgame_Compiler_Resolver_ResolveBlock(self, stmt->Else); } } #line 342 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_WHILE_STMT) { #line 343 "./src/resolver/symbol.am" if (stmt->Cond != NULL) { Amalgame_Compiler_Resolver_ResolveExpr(self, stmt->Cond); } #line 344 "./src/resolver/symbol.am" if (stmt->Body != NULL) { Amalgame_Compiler_Resolver_ResolveBlock(self, stmt->Body); } } #line 346 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_BINARY) { #line 347 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveExpr(self, stmt); } #line 349 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_CALL) { #line 350 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveExpr(self, stmt); } #line 352 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_MEMBER) { #line 353 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveExpr(self, stmt); } } static void Amalgame_Compiler_Resolver_ResolveExpr(Amalgame_Compiler_Resolver* self, Amalgame_Compiler_AstNode* expr) { #line 358 "./src/resolver/symbol.am" if (expr == NULL) { return; } #line 359 "./src/resolver/symbol.am" Amalgame_Compiler_NodeKind k = expr->Kind; #line 360 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 361 "./src/resolver/symbol.am" code_string name = expr->Name; #line 362 "./src/resolver/symbol.am" if (!Amalgame_Compiler_Resolver_LookupInScopes(self, name)) { #line 363 "./src/resolver/symbol.am" i64 line = expr->Line; #line 364 "./src/resolver/symbol.am" code_string ln = String_FromInt(line); #line 365 "./src/resolver/symbol.am" AmalgameList_add(self->Errors, (void*)(intptr_t)(code_string_concat((code_string_concat((code_string_concat("Unknown symbol '", name)), "' at line ")), ln))); } } #line 368 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_BINARY) { #line 369 "./src/resolver/symbol.am" if (expr->Left != NULL) { Amalgame_Compiler_Resolver_ResolveExpr(self, expr->Left); } #line 370 "./src/resolver/symbol.am" if (expr->Right != NULL) { Amalgame_Compiler_Resolver_ResolveExpr(self, expr->Right); } } #line 372 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_CALL) { #line 373 "./src/resolver/symbol.am" if (expr->Left != NULL) { Amalgame_Compiler_Resolver_ResolveExpr(self, expr->Left); } #line 374 "./src/resolver/symbol.am" i64 argc = AmalgameList_count(expr->Args); #line 375 "./src/resolver/symbol.am" for (i64 i = 0LL; i < argc; i++) { #line 376 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i)); } } #line 379 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_MEMBER) { #line 380 "./src/resolver/symbol.am" if (expr->Left != NULL) { Amalgame_Compiler_Resolver_ResolveExpr(self, expr->Left); } } #line 382 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 383 "./src/resolver/symbol.am" i64 argc2 = AmalgameList_count(expr->Args); #line 384 "./src/resolver/symbol.am" for (i64 i = 0LL; i < argc2; i++) { #line 385 "./src/resolver/symbol.am" Amalgame_Compiler_Resolver_ResolveExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i)); } } #line 388 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_UNARY) { #line 389 "./src/resolver/symbol.am" if (expr->Left != NULL) { Amalgame_Compiler_Resolver_ResolveExpr(self, expr->Left); } } #line 391 "./src/resolver/symbol.am" if (k == Amalgame_Compiler_NodeKind_INDEX_EXPR) { #line 392 "./src/resolver/symbol.am" if (expr->Left != NULL) { Amalgame_Compiler_Resolver_ResolveExpr(self, expr->Left); } #line 393 "./src/resolver/symbol.am" if (expr->Right != NULL) { Amalgame_Compiler_Resolver_ResolveExpr(self, expr->Right); } } } static code_bool Amalgame_Compiler_Resolver_LookupInScopes(Amalgame_Compiler_Resolver* self, code_string name) { #line 398 "./src/resolver/symbol.am" Amalgame_Compiler_SymbolTable* scope = self->Current; #line 399 "./src/resolver/symbol.am" code_bool found = 0; #line 400 "./src/resolver/symbol.am" i64 safety = 0LL; #line 401 "./src/resolver/symbol.am" while ((scope != NULL) && !found) { #line 402 "./src/resolver/symbol.am" safety = (safety + 1LL); #line 403 "./src/resolver/symbol.am" if (safety > 100LL) { break; } #line 404 "./src/resolver/symbol.am" if (Amalgame_Compiler_SymbolTable_Has(scope, name)) { found = 1; } #line 405 "./src/resolver/symbol.am" if (!found) { #line 406 "./src/resolver/symbol.am" scope = scope->Parent; } } #line 409 "./src/resolver/symbol.am" return found; } struct _Amalgame_Compiler_MemberTable { AmalgameList* Keys; AmalgameList* Values; AmalgameMap* Index; }; void Amalgame_Compiler_MemberTable_Set(Amalgame_Compiler_MemberTable* self, code_string className, code_string memberName, code_string typeName); code_string Amalgame_Compiler_MemberTable_Get(Amalgame_Compiler_MemberTable* self, code_string className, code_string memberName); code_bool Amalgame_Compiler_MemberTable_Has(Amalgame_Compiler_MemberTable* self, code_string className, code_string memberName); i64 Amalgame_Compiler_MemberTable_MemberCountFor(Amalgame_Compiler_MemberTable* self, code_string className); code_string Amalgame_Compiler_MemberTable_MemberNameForAt(Amalgame_Compiler_MemberTable* self, code_string className, i64 idx); Amalgame_Compiler_MemberTable* Amalgame_Compiler_MemberTable_new() { Amalgame_Compiler_MemberTable* self = (Amalgame_Compiler_MemberTable*) GC_MALLOC(sizeof(Amalgame_Compiler_MemberTable)); #line 39 "./src/resolver/resolver.am" self->Keys = AmalgameList_new(); #line 40 "./src/resolver/resolver.am" self->Values = AmalgameList_new(); #line 41 "./src/resolver/resolver.am" self->Index = AmalgameMap_new(); return self; } void Amalgame_Compiler_MemberTable_Set(Amalgame_Compiler_MemberTable* self, code_string className, code_string memberName, code_string typeName) { #line 45 "./src/resolver/resolver.am" code_string key = code_string_concat((code_string_concat(className, ".")), memberName); #line 49 "./src/resolver/resolver.am" if (AmalgameMap_has(self->Index, key)) { return; } #line 50 "./src/resolver/resolver.am" i64 idx = AmalgameList_count(self->Keys); #line 51 "./src/resolver/resolver.am" AmalgameList_add(self->Keys, (void*)(intptr_t)(key)); #line 52 "./src/resolver/resolver.am" AmalgameList_add(self->Values, (void*)(intptr_t)(typeName)); #line 53 "./src/resolver/resolver.am" AmalgameMap_set(self->Index, key, (void*)(intptr_t)(idx)); } code_string Amalgame_Compiler_MemberTable_Get(Amalgame_Compiler_MemberTable* self, code_string className, code_string memberName) { #line 57 "./src/resolver/resolver.am" code_string key = code_string_concat((code_string_concat(className, ".")), memberName); #line 58 "./src/resolver/resolver.am" if (!AmalgameMap_has(self->Index, key)) { return "?"; } #line 59 "./src/resolver/resolver.am" i64 idx = (i64)AmalgameMap_get(self->Index, key); #line 60 "./src/resolver/resolver.am" return (code_string)AmalgameList_get(self->Values, idx); } code_bool Amalgame_Compiler_MemberTable_Has(Amalgame_Compiler_MemberTable* self, code_string className, code_string memberName) { #line 64 "./src/resolver/resolver.am" return AmalgameMap_has(self->Index, code_string_concat((code_string_concat(className, ".")), memberName)); } i64 Amalgame_Compiler_MemberTable_MemberCountFor(Amalgame_Compiler_MemberTable* self, code_string className) { #line 73 "./src/resolver/resolver.am" code_string prefix = code_string_concat(className, "."); #line 74 "./src/resolver/resolver.am" i64 n = AmalgameList_count(self->Keys); #line 75 "./src/resolver/resolver.am" i64 seen = 0LL; #line 76 "./src/resolver/resolver.am" AmalgameList* names = AmalgameList_new(); #line 77 "./src/resolver/resolver.am" for (i64 i = 0LL; i < n; i++) { #line 78 "./src/resolver/resolver.am" code_string k = (code_string)AmalgameList_get(self->Keys, i); #line 79 "./src/resolver/resolver.am" if (String_StartsWith(k, prefix)) { #line 80 "./src/resolver/resolver.am" i64 nameLen = String_Length(k) - String_Length(prefix); #line 81 "./src/resolver/resolver.am" code_string name = String_Substring(k, String_Length(prefix), nameLen); #line 82 "./src/resolver/resolver.am" code_bool dup = 0; #line 83 "./src/resolver/resolver.am" i64 sn = AmalgameList_count(names); #line 84 "./src/resolver/resolver.am" for (i64 j = 0LL; j < sn; j++) { #line 85 "./src/resolver/resolver.am" if (code_string_equals((code_string)AmalgameList_get(names, j), name)) { dup = 1; } } #line 87 "./src/resolver/resolver.am" if (!dup) { #line 88 "./src/resolver/resolver.am" AmalgameList_add(names, (void*)(intptr_t)(name)); #line 89 "./src/resolver/resolver.am" seen = (seen + 1LL); } } } #line 93 "./src/resolver/resolver.am" return seen; } code_string Amalgame_Compiler_MemberTable_MemberNameForAt(Amalgame_Compiler_MemberTable* self, code_string className, i64 idx) { #line 97 "./src/resolver/resolver.am" code_string prefix = code_string_concat(className, "."); #line 98 "./src/resolver/resolver.am" i64 n = AmalgameList_count(self->Keys); #line 99 "./src/resolver/resolver.am" i64 seen = 0LL; #line 100 "./src/resolver/resolver.am" AmalgameList* names = AmalgameList_new(); #line 101 "./src/resolver/resolver.am" for (i64 i = 0LL; i < n; i++) { #line 102 "./src/resolver/resolver.am" code_string k = (code_string)AmalgameList_get(self->Keys, i); #line 103 "./src/resolver/resolver.am" if (String_StartsWith(k, prefix)) { #line 104 "./src/resolver/resolver.am" i64 nameLen = String_Length(k) - String_Length(prefix); #line 105 "./src/resolver/resolver.am" code_string name = String_Substring(k, String_Length(prefix), nameLen); #line 106 "./src/resolver/resolver.am" code_bool dup = 0; #line 107 "./src/resolver/resolver.am" i64 sn = AmalgameList_count(names); #line 108 "./src/resolver/resolver.am" for (i64 j = 0LL; j < sn; j++) { #line 109 "./src/resolver/resolver.am" if (code_string_equals((code_string)AmalgameList_get(names, j), name)) { dup = 1; } } #line 111 "./src/resolver/resolver.am" if (!dup) { #line 112 "./src/resolver/resolver.am" if (seen == idx) { return name; } #line 113 "./src/resolver/resolver.am" AmalgameList_add(names, (void*)(intptr_t)(name)); #line 114 "./src/resolver/resolver.am" seen = (seen + 1LL); } } } #line 118 "./src/resolver/resolver.am" return ""; } struct _Amalgame_Compiler_ResolverError { code_string Message; code_string Filename; i64 Line; i64 Column; }; Amalgame_Compiler_ResolverError* Amalgame_Compiler_ResolverError_new(code_string msg, code_string file, i64 line, i64 col) { Amalgame_Compiler_ResolverError* self = (Amalgame_Compiler_ResolverError*) GC_MALLOC(sizeof(Amalgame_Compiler_ResolverError)); #line 135 "./src/resolver/resolver.am" self->Message = msg; #line 136 "./src/resolver/resolver.am" self->Filename = file; #line 137 "./src/resolver/resolver.am" self->Line = line; #line 138 "./src/resolver/resolver.am" self->Column = col; return self; } struct _Amalgame_Compiler_FullResolver { AmalgameList* GlobalNames; AmalgameList* GlobalTypes; AmalgameMap* GlobalIndex; AmalgameMap* MethodNodeIndex; AmalgameMap* LocalIndex; AmalgameList* ShadowPrev; AmalgameList* LocalNames; AmalgameList* LocalTypes; AmalgameList* LocalIsLets; AmalgameList* ScopeStarts; Amalgame_Compiler_MemberTable* Members; AmalgameList* Errors; AmalgameList* RawErrors; AmalgameList* Programs; code_string CurrentClass; code_string CurrentReturn; i64 LoopDepth; Amalgame_Compiler_AstNode* LambdaInProgress; i64 LambdaBoundary; code_string CurrentFile; Amalgame_Compiler_SourceMap* Sources; AmalgameList* PkgClasses; AmalgameList* PkgFuncs; AmalgameList* PkgFuncCTypes; }; void Amalgame_Compiler_FullResolver_RegisterPackages(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_PackageRegistry* reg); static void Amalgame_Compiler_FullResolver_RegisterBuiltins(Amalgame_Compiler_FullResolver* self); static void Amalgame_Compiler_FullResolver_PushScope(Amalgame_Compiler_FullResolver* self, code_string label); static void Amalgame_Compiler_FullResolver_PopScope(Amalgame_Compiler_FullResolver* self); static i64 Amalgame_Compiler_FullResolver_CurrentScopeStart(Amalgame_Compiler_FullResolver* self); static void Amalgame_Compiler_FullResolver_DeclareGlobal(Amalgame_Compiler_FullResolver* self, code_string name, code_string typeName, code_bool isLet); static void Amalgame_Compiler_FullResolver_DeclareLambdaParam(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* p); static code_bool Amalgame_Compiler_FullResolver_DeclareCurrent(Amalgame_Compiler_FullResolver* self, code_string name, code_string typeName, code_bool isLet); static code_bool Amalgame_Compiler_FullResolver_LookupInScopes(Amalgame_Compiler_FullResolver* self, code_string name); static code_string Amalgame_Compiler_FullResolver_LookupType(Amalgame_Compiler_FullResolver* self, code_string name); static code_bool Amalgame_Compiler_FullResolver_LookupIsLet(Amalgame_Compiler_FullResolver* self, code_string name); static i64 Amalgame_Compiler_FullResolver_IndexOfLocal(Amalgame_Compiler_FullResolver* self, code_string name); static void Amalgame_Compiler_FullResolver_AddCapture(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* lam, code_string name, code_string typeName, i64 line, i64 col); static void Amalgame_Compiler_FullResolver_TryCaptureLocalByName(Amalgame_Compiler_FullResolver* self, code_string name, i64 line, i64 col); static void Amalgame_Compiler_FullResolver_CaptureIdentsInInterpExpr(Amalgame_Compiler_FullResolver* self, code_string inner, i64 line, i64 col); static void Amalgame_Compiler_FullResolver_Error(Amalgame_Compiler_FullResolver* self, code_string msg, Amalgame_Compiler_AstNode* node); static void Amalgame_Compiler_FullResolver_ErrorMsg(Amalgame_Compiler_FullResolver* self, code_string msg); static void Amalgame_Compiler_FullResolver_EmitError(Amalgame_Compiler_FullResolver* self, code_string msg, i64 line, i64 col); code_bool Amalgame_Compiler_FullResolver_HasErrors(Amalgame_Compiler_FullResolver* self); code_string Amalgame_Compiler_FullResolver_GetErrors(Amalgame_Compiler_FullResolver* self); i64 Amalgame_Compiler_FullResolver_ProgramCount(Amalgame_Compiler_FullResolver* self); Amalgame_Compiler_AstNode* Amalgame_Compiler_FullResolver_ProgramAt(Amalgame_Compiler_FullResolver* self, i64 i); i64 Amalgame_Compiler_FullResolver_GlobalCount(Amalgame_Compiler_FullResolver* self); code_string Amalgame_Compiler_FullResolver_GlobalNameAt(Amalgame_Compiler_FullResolver* self, i64 i); code_string Amalgame_Compiler_FullResolver_GlobalTypeAt(Amalgame_Compiler_FullResolver* self, i64 i); void Amalgame_Compiler_FullResolver_ResolvePrograms(Amalgame_Compiler_FullResolver* self); void Amalgame_Compiler_FullResolver_CollectAll(Amalgame_Compiler_FullResolver* self); void Amalgame_Compiler_FullResolver_ResolveAll(Amalgame_Compiler_FullResolver* self); static void Amalgame_Compiler_FullResolver_CollectProgram(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* prog); static void Amalgame_Compiler_FullResolver_CollectDecl(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_FullResolver_CollectClassMembers(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* cls); static void Amalgame_Compiler_FullResolver_CollectClassMember(Amalgame_Compiler_FullResolver* self, code_string className, Amalgame_Compiler_AstNode* m); static void Amalgame_Compiler_FullResolver_CollectEnumMembers(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* en); static void Amalgame_Compiler_FullResolver_CollectEnumMember(Amalgame_Compiler_FullResolver* self, code_string enumName, Amalgame_Compiler_AstNode* m); static void Amalgame_Compiler_FullResolver_ResolveEnumChild(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* m); static void Amalgame_Compiler_FullResolver_ResolveProgram(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* prog); static void Amalgame_Compiler_FullResolver_ResolveDecl(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_FullResolver_ResolveClass(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* cls); static void Amalgame_Compiler_FullResolver_PreRegisterMember(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* m); static void Amalgame_Compiler_FullResolver_ResolveMember(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* m); static void Amalgame_Compiler_FullResolver_ResolveMethod(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* method); static void Amalgame_Compiler_FullResolver_ResolveBlock(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* block); static void Amalgame_Compiler_FullResolver_ResolveStmt(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_FullResolver_ResolveIf(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_FullResolver_ResolveElseBranch(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* branch); static void Amalgame_Compiler_FullResolver_ResolveForIn(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_FullResolver_ResolveAssign(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_FullResolver_ResolveMatch(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_FullResolver_ResolveMatchArm(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* arm); static void Amalgame_Compiler_FullResolver_ResolveArmBody(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* body); static code_bool Amalgame_Compiler_FullResolver_HasLambdaArg(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* call); static void Amalgame_Compiler_FullResolver_PatchLambdaParamTypes(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* call); static Amalgame_Compiler_AstNode* Amalgame_Compiler_FullResolver_FindMethodInPrograms(Amalgame_Compiler_FullResolver* self, code_string className, code_string methodName); static void Amalgame_Compiler_FullResolver_PatchLambdasFromTypedClosureParams(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* call, Amalgame_Compiler_AstNode* methodDecl); static AmalgameList* Amalgame_Compiler_FullResolver_SplitTopLevelCommasResolver(Amalgame_Compiler_FullResolver* self, code_string s); static void Amalgame_Compiler_FullResolver_PatchLambdaParamTypesGeneric(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_FullResolver_ResolveExpr(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* expr); static code_string Amalgame_Compiler_FullResolver_InferExprType(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* expr); static code_string Amalgame_Compiler_FullResolver_CollectionElemType(Amalgame_Compiler_FullResolver* self, code_string typeKey); code_string Amalgame_Compiler_FullResolver_GetMemberType(Amalgame_Compiler_FullResolver* self, code_string className, code_string memberName); code_bool Amalgame_Compiler_FullResolver_HasMember(Amalgame_Compiler_FullResolver* self, code_string className, code_string memberName); code_string Amalgame_Compiler_FullResolver_GetVarType(Amalgame_Compiler_FullResolver* self, code_string name); code_bool Amalgame_Compiler_FullResolver_HasSymbol(Amalgame_Compiler_FullResolver* self, code_string name); code_string Amalgame_Compiler_FullResolver_GetTypeName(Amalgame_Compiler_FullResolver* self, code_string name); void Amalgame_Compiler_FullResolver_SetTypeName(Amalgame_Compiler_FullResolver* self, code_string name, code_string typeName); Amalgame_Compiler_FullResolver* Amalgame_Compiler_FullResolver_new() { Amalgame_Compiler_FullResolver* self = (Amalgame_Compiler_FullResolver*) GC_MALLOC(sizeof(Amalgame_Compiler_FullResolver)); #line 223 "./src/resolver/resolver.am" self->GlobalNames = AmalgameList_new(); #line 224 "./src/resolver/resolver.am" self->GlobalTypes = AmalgameList_new(); #line 225 "./src/resolver/resolver.am" self->GlobalIndex = AmalgameMap_new(); #line 226 "./src/resolver/resolver.am" self->MethodNodeIndex = AmalgameMap_new(); #line 227 "./src/resolver/resolver.am" self->LocalIndex = AmalgameMap_new(); #line 228 "./src/resolver/resolver.am" self->ShadowPrev = AmalgameList_new(); #line 229 "./src/resolver/resolver.am" self->LocalNames = AmalgameList_new(); #line 230 "./src/resolver/resolver.am" self->LocalTypes = AmalgameList_new(); #line 231 "./src/resolver/resolver.am" self->LocalIsLets = AmalgameList_new(); #line 232 "./src/resolver/resolver.am" self->ScopeStarts = AmalgameList_new(); #line 233 "./src/resolver/resolver.am" self->Members = Amalgame_Compiler_MemberTable_new(); #line 234 "./src/resolver/resolver.am" self->Errors = AmalgameList_new(); #line 235 "./src/resolver/resolver.am" self->RawErrors = AmalgameList_new(); #line 236 "./src/resolver/resolver.am" self->Programs = AmalgameList_new(); #line 237 "./src/resolver/resolver.am" self->CurrentClass = ""; #line 238 "./src/resolver/resolver.am" self->CurrentReturn = "void"; #line 239 "./src/resolver/resolver.am" self->LoopDepth = 0LL; #line 240 "./src/resolver/resolver.am" self->LambdaInProgress = NULL; #line 241 "./src/resolver/resolver.am" self->LambdaBoundary = 0LL; #line 242 "./src/resolver/resolver.am" self->CurrentFile = ""; #line 243 "./src/resolver/resolver.am" self->Sources = Amalgame_Compiler_SourceMap_new(); #line 244 "./src/resolver/resolver.am" self->PkgClasses = AmalgameList_new(); #line 245 "./src/resolver/resolver.am" self->PkgFuncs = AmalgameList_new(); #line 246 "./src/resolver/resolver.am" self->PkgFuncCTypes = AmalgameList_new(); #line 247 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_RegisterBuiltins(self); return self; } void Amalgame_Compiler_FullResolver_RegisterPackages(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_PackageRegistry* reg) { #line 267 "./src/resolver/resolver.am" i64 n = AmalgameList_count(reg->Packages); #line 268 "./src/resolver/resolver.am" for (i64 i = 0LL; i < n; i++) { #line 269 "./src/resolver/resolver.am" Amalgame_Compiler_LoadedPackage* p = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(reg->Packages, i); #line 274 "./src/resolver/resolver.am" i64 pkgCn = AmalgameList_count(p->ClassNames); #line 275 "./src/resolver/resolver.am" for (i64 pkgCi = 0LL; pkgCi < pkgCn; pkgCi++) { #line 276 "./src/resolver/resolver.am" code_string pkgCls = (code_string)AmalgameList_get(p->ClassNames, pkgCi); #line 277 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, pkgCls, "type", 0); #line 278 "./src/resolver/resolver.am" AmalgameList_add(self->PkgClasses, (void*)(intptr_t)(pkgCls)); } #line 285 "./src/resolver/resolver.am" i64 fn = AmalgameList_count(p->FuncNames); #line 286 "./src/resolver/resolver.am" for (i64 j = 0LL; j < fn; j++) { #line 287 "./src/resolver/resolver.am" code_string fName = (code_string)AmalgameList_get(p->FuncNames, j); #line 288 "./src/resolver/resolver.am" code_string cType = (code_string)AmalgameList_get(p->FuncRets, j); #line 289 "./src/resolver/resolver.am" code_string mangled = Amalgame_Compiler_PackageRegistry_ManglePackageSymbol(p->Ns, fName); #line 290 "./src/resolver/resolver.am" code_string amType = Amalgame_Compiler_PackageRegistry_AmalgameTypeFromC(cType); #line 291 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, mangled, amType, 0); #line 292 "./src/resolver/resolver.am" AmalgameList_add(self->PkgFuncs, (void*)(intptr_t)(mangled)); #line 293 "./src/resolver/resolver.am" AmalgameList_add(self->PkgFuncCTypes, (void*)(intptr_t)(cType)); } } } static void Amalgame_Compiler_FullResolver_RegisterBuiltins(Amalgame_Compiler_FullResolver* self) { #line 301 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "int", "type", 0); #line 302 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "float", "type", 0); #line 303 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "double", "type", 0); #line 304 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "bool", "type", 0); #line 305 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "string", "type", 0); #line 306 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "void", "type", 0); #line 307 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "null", "null", 0); #line 308 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "true", "bool", 0); #line 309 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "false", "bool", 0); #line 310 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "this", "?", 0); #line 311 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "args", "string[]", 0); #line 317 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "persist", "?", 0); #line 322 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String", "type", 0); #line 323 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "List", "type", 0); #line 324 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Map", "type", 0); #line 325 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Set", "type", 0); #line 326 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Path", "type", 0); #line 327 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Env", "type", 0); #line 329 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process", "type", 0); #line 330 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_Run", "int", 0); #line 331 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_RunCapture", "AmalgameProcessResult", 0); #line 333 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_RunTimeout", "int", 0); #line 334 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_RunCaptureBoth", "AmalgameProcessResult", 0); #line 335 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_RunCaptureBothTimeout", "AmalgameProcessResult", 0); #line 337 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_Spawn", "AmalgameProcessHandle", 0); #line 338 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_IsAlive", "bool", 0); #line 339 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_ExitCode", "int", 0); #line 340 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_Wait", "bool", 0); #line 341 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_Kill", "void", 0); #line 342 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_KillForce", "void", 0); #line 343 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_WriteLine", "bool", 0); #line 344 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_ReadLine", "string", 0); #line 345 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Process_ReadErrLine", "string", 0); #line 350 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu", "type", 0); #line 351 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu_PinMode", "void", 0); #line 352 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu_DigitalWrite", "void", 0); #line 353 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu_DigitalRead", "int", 0); #line 354 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu_Toggle", "void", 0); #line 355 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu_DelayMs", "void", 0); #line 356 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu_Millis", "int", 0); #line 357 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu_WaitTick", "void", 0); #line 358 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu_Ticks", "int", 0); #line 359 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu_High", "int", 0); #line 360 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu_Low", "int", 0); #line 361 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu_Output", "int", 0); #line 362 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mcu_Input", "int", 0); #line 363 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Console", "type", 0); #line 364 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Console_WriteLine", "void", 0); #line 365 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Console_WriteError", "void", 0); #line 366 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Console_Clear", "void", 0); #line 367 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Console_Write", "void", 0); #line 368 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Console_ReadLine", "string", 0); #line 369 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Console_ReadBytes", "string", 0); #line 370 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Console_Flush", "void", 0); #line 372 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File", "type", 0); #line 373 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Path", "type", 0); #line 374 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_CharAt1", "string", 0); #line 375 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_CharAtUnchecked", "string", 0); #line 376 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_ReadAll", "string", 0); #line 377 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_WriteAll", "void", 0); #line 378 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_AppendAll", "void", 0); #line 379 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_WriteLines", "void", 0); #line 380 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_OpenWrite", "void", 0); #line 381 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_StreamLine", "void", 0); #line 382 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_CloseWrite", "void", 0); #line 383 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_Exists", "bool", 0); #line 384 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_Delete", "bool", 0); #line 385 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_Size", "int", 0); #line 386 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_Mtime", "int", 0); #line 387 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_IsFile", "bool", 0); #line 388 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "File_IsDir", "bool", 0); #line 389 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Path_Combine", "string", 0); #line 390 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Path_GetExtension", "string", 0); #line 391 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Path_GetFilename", "string", 0); #line 392 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Path_GetDirectory", "string", 0); #line 393 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Path_GetStem", "string", 0); #line 394 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Path_IsAbsolute", "bool", 0); #line 395 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Path_Normalize", "string", 0); #line 396 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Path_Sep", "string", 0); #line 420 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Service_ShouldStop", "bool", 0); #line 421 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Service_RequestStop", "void", 0); #line 422 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Service_Sleep", "void", 0); #line 424 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Env_Get", "string", 0); #line 425 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Env_Has", "bool", 0); #line 430 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Math", "type", 0); #line 433 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "WebSocket", "type", 0); #line 434 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "WebSocket_Connect", "WebSocket", 0); #line 435 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "WebSocket_SendText", "bool", 0); #line 436 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "WebSocket_ReceiveText", "string", 0); #line 437 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "WebSocket_Close", "void", 0); #line 438 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "WebSocket_IsConnected", "bool", 0); #line 439 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "WebSocket_GetHost", "string", 0); #line 440 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "WebSocket_GetPort", "int", 0); #line 441 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "WebSocket_AcceptKey", "string", 0); #line 444 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Compress", "type", 0); #line 445 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Compress_Gzip", "List", 0); #line 446 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Compress_Gunzip", "List", 0); #line 447 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Compress_Deflate", "List", 0); #line 448 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Compress_Inflate", "List", 0); #line 449 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Compress_GzipString", "List", 0); #line 450 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Compress_GunzipString", "string", 0); #line 453 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Regex", "type", 0); #line 454 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Match", "type", 0); #line 455 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Regex_Test", "bool", 0); #line 456 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Regex_Match", "Match", 0); #line 457 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Regex_Replace", "string", 0); #line 458 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Regex_ReplaceAll", "string", 0); #line 459 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Match_GetText", "string", 0); #line 460 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Match_GetStart", "int", 0); #line 461 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Match_GetEnd", "int", 0); #line 462 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Match_GroupCount", "int", 0); #line 463 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Match_GroupText", "string", 0); #line 464 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Match_GroupStart", "int", 0); #line 465 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Match_GroupEnd", "int", 0); #line 474 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3", "type", 0); #line 475 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec4", "type", 0); #line 476 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mat4", "type", 0); #line 477 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3_new", "Vec3", 0); #line 478 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3_GetX", "float", 0); #line 479 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3_GetY", "float", 0); #line 480 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3_GetZ", "float", 0); #line 481 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3_Add", "Vec3", 0); #line 482 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3_Sub", "Vec3", 0); #line 483 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3_Scale", "Vec3", 0); #line 484 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3_Dot", "float", 0); #line 485 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3_Cross", "Vec3", 0); #line 486 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3_Length", "float", 0); #line 487 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3_Normalize", "Vec3", 0); #line 488 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec3_Equals", "bool", 0); #line 489 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec4_new", "Vec4", 0); #line 490 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec4_GetX", "float", 0); #line 491 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec4_GetY", "float", 0); #line 492 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec4_GetZ", "float", 0); #line 493 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec4_GetW", "float", 0); #line 494 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec4_Add", "Vec4", 0); #line 495 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec4_Sub", "Vec4", 0); #line 496 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec4_Scale", "Vec4", 0); #line 497 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Vec4_Dot", "float", 0); #line 498 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mat4_new", "Mat4", 0); #line 499 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mat4_Identity", "Mat4", 0); #line 500 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mat4_Get", "float", 0); #line 501 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mat4_Set", "void", 0); #line 502 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mat4_Multiply", "Mat4", 0); #line 503 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mat4_Translate", "Mat4", 0); #line 504 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mat4_Scale", "Mat4", 0); #line 505 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mat4_RotateX", "Mat4", 0); #line 506 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mat4_RotateY", "Mat4", 0); #line 507 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mat4_RotateZ", "Mat4", 0); #line 508 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Mat4_TransformVec4", "Vec4", 0); #line 526 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_Length", "int", 0); #line 527 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_IsEmpty", "bool", 0); #line 528 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_Contains", "bool", 0); #line 529 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_StartsWith", "bool", 0); #line 530 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_EndsWith", "bool", 0); #line 531 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_IndexOf", "int", 0); #line 532 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_LastIndexOf", "int", 0); #line 533 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_Substring", "string", 0); #line 534 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_ToUpper", "string", 0); #line 535 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_ToLower", "string", 0); #line 536 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_Trim", "string", 0); #line 537 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_TrimStart", "string", 0); #line 538 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_TrimEnd", "string", 0); #line 539 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_Replace", "string", 0); #line 540 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_Split", "List", 0); #line 541 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_Join", "string", 0); #line 542 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_Repeat", "string", 0); #line 543 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_ToInt", "int", 0); #line 544 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_ToFloat", "float", 0); #line 545 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_FromInt", "string", 0); #line 546 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_FromByte", "string", 0); #line 547 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_FromCodepoint", "string", 0); #line 549 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Args_Count", "int", 0); #line 550 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Args_Get", "string", 0); #line 551 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Exit_Set", "void", 0); #line 552 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "Exit_Get", "int", 0); #line 553 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_FromFloat", "string", 0); #line 554 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_From", "string", 0); #line 555 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "String_CharAt", "string", 0); #line 561 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpServer_Listen", "?", 0); #line 562 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpServer_Accept", "?", 0); #line 563 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpServer_Close", "void", 0); #line 564 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpServer_IsListening", "bool", 0); #line 565 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpClient_Connect", "?", 0); #line 566 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpClient_Send", "void", 0); #line 567 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpClient_Receive", "string", 0); #line 568 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpClient_Close", "void", 0); #line 569 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpClient_IsConnected", "bool", 0); #line 570 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpConn_Send", "void", 0); #line 571 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpConn_Receive", "string", 0); #line 572 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpConn_Close", "void", 0); #line 573 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "TcpConn_IsConnected", "bool", 0); #line 574 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "UdpSocket_New", "?", 0); #line 575 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "UdpSocket_Bind", "bool", 0); #line 576 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "UdpSocket_Send", "bool", 0); #line 577 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "UdpSocket_Receive", "string", 0); #line 583 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "UdpSocket_ReceiveFrom", "?", 0); #line 587 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "UdpSocket_SetRecvBuf", "i64", 0); #line 588 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, "UdpSocket_Close", "void", 0); } static void Amalgame_Compiler_FullResolver_PushScope(Amalgame_Compiler_FullResolver* self, code_string label) { #line 597 "./src/resolver/resolver.am" AmalgameList_add(self->ScopeStarts, (void*)(intptr_t)(AmalgameList_count(self->LocalNames))); } static void Amalgame_Compiler_FullResolver_PopScope(Amalgame_Compiler_FullResolver* self) { #line 601 "./src/resolver/resolver.am" i64 depth = AmalgameList_count(self->ScopeStarts); #line 602 "./src/resolver/resolver.am" if (depth == 0LL) { return; } #line 603 "./src/resolver/resolver.am" i64 mark = (i64)(intptr_t)AmalgameList_get(self->ScopeStarts, depth - 1LL); #line 604 "./src/resolver/resolver.am" AmalgameList_removeAt(self->ScopeStarts, depth - 1LL); #line 609 "./src/resolver/resolver.am" while (AmalgameList_count(self->LocalNames) > mark) { #line 610 "./src/resolver/resolver.am" i64 last = AmalgameList_count(self->LocalNames) - 1LL; #line 611 "./src/resolver/resolver.am" code_string lname = (code_string)AmalgameList_get(self->LocalNames, last); #line 612 "./src/resolver/resolver.am" i64 prev = (i64)(intptr_t)AmalgameList_get(self->ShadowPrev, last); #line 613 "./src/resolver/resolver.am" if (prev < 0LL) { #line 614 "./src/resolver/resolver.am" AmalgameMap_remove(self->LocalIndex, lname); } else { #line 616 "./src/resolver/resolver.am" AmalgameMap_set(self->LocalIndex, lname, (void*)(intptr_t)(prev)); } #line 618 "./src/resolver/resolver.am" AmalgameList_removeAt(self->LocalNames, last); #line 619 "./src/resolver/resolver.am" AmalgameList_removeAt(self->LocalTypes, last); #line 620 "./src/resolver/resolver.am" AmalgameList_removeAt(self->LocalIsLets, last); #line 621 "./src/resolver/resolver.am" AmalgameList_removeAt(self->ShadowPrev, last); } } static i64 Amalgame_Compiler_FullResolver_CurrentScopeStart(Amalgame_Compiler_FullResolver* self) { #line 626 "./src/resolver/resolver.am" i64 depth = AmalgameList_count(self->ScopeStarts); #line 627 "./src/resolver/resolver.am" if (depth == 0LL) { return 0LL; } #line 628 "./src/resolver/resolver.am" return (i64)(intptr_t)AmalgameList_get(self->ScopeStarts, depth - 1LL); } static void Amalgame_Compiler_FullResolver_DeclareGlobal(Amalgame_Compiler_FullResolver* self, code_string name, code_string typeName, code_bool isLet) { #line 636 "./src/resolver/resolver.am" if (AmalgameMap_has(self->GlobalIndex, name)) { return; } #line 637 "./src/resolver/resolver.am" i64 idx = AmalgameList_count(self->GlobalNames); #line 638 "./src/resolver/resolver.am" AmalgameList_add(self->GlobalNames, (void*)(intptr_t)(name)); #line 639 "./src/resolver/resolver.am" AmalgameList_add(self->GlobalTypes, (void*)(intptr_t)(typeName)); #line 640 "./src/resolver/resolver.am" AmalgameMap_set(self->GlobalIndex, name, (void*)(intptr_t)(idx)); } static void Amalgame_Compiler_FullResolver_DeclareLambdaParam(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* p) { #line 652 "./src/resolver/resolver.am" code_string t = p->Str; #line 653 "./src/resolver/resolver.am" if (String_Length(t) == 0LL) { t = "?"; } #line 654 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareCurrent(self, p->Name, t, 1); } static code_bool Amalgame_Compiler_FullResolver_DeclareCurrent(Amalgame_Compiler_FullResolver* self, code_string name, code_string typeName, code_bool isLet) { #line 663 "./src/resolver/resolver.am" i64 start = Amalgame_Compiler_FullResolver_CurrentScopeStart(self); #line 664 "./src/resolver/resolver.am" if (AmalgameMap_has(self->LocalIndex, name)) { #line 665 "./src/resolver/resolver.am" i64 existing = (i64)AmalgameMap_get(self->LocalIndex, name); #line 666 "./src/resolver/resolver.am" if (existing >= start) { return 0; } } #line 668 "./src/resolver/resolver.am" i64 newIdx = AmalgameList_count(self->LocalNames); #line 669 "./src/resolver/resolver.am" i64 prev = -1LL; #line 670 "./src/resolver/resolver.am" if (AmalgameMap_has(self->LocalIndex, name)) { prev = (i64)AmalgameMap_get(self->LocalIndex, name); } #line 671 "./src/resolver/resolver.am" AmalgameList_add(self->LocalNames, (void*)(intptr_t)(name)); #line 672 "./src/resolver/resolver.am" AmalgameList_add(self->LocalTypes, (void*)(intptr_t)(typeName)); #line 673 "./src/resolver/resolver.am" AmalgameList_add(self->LocalIsLets, (void*)(intptr_t)(isLet)); #line 674 "./src/resolver/resolver.am" AmalgameList_add(self->ShadowPrev, (void*)(intptr_t)(prev)); #line 675 "./src/resolver/resolver.am" AmalgameMap_set(self->LocalIndex, name, (void*)(intptr_t)(newIdx)); #line 676 "./src/resolver/resolver.am" return 1; } static code_bool Amalgame_Compiler_FullResolver_LookupInScopes(Amalgame_Compiler_FullResolver* self, code_string name) { #line 680 "./src/resolver/resolver.am" if (AmalgameMap_has(self->LocalIndex, name)) { return 1; } #line 681 "./src/resolver/resolver.am" return AmalgameMap_has(self->GlobalIndex, name); } static code_string Amalgame_Compiler_FullResolver_LookupType(Amalgame_Compiler_FullResolver* self, code_string name) { #line 685 "./src/resolver/resolver.am" if (AmalgameMap_has(self->LocalIndex, name)) { #line 686 "./src/resolver/resolver.am" i64 idx = (i64)AmalgameMap_get(self->LocalIndex, name); #line 687 "./src/resolver/resolver.am" return (code_string)AmalgameList_get(self->LocalTypes, idx); } #line 689 "./src/resolver/resolver.am" if (AmalgameMap_has(self->GlobalIndex, name)) { #line 690 "./src/resolver/resolver.am" i64 idx = (i64)AmalgameMap_get(self->GlobalIndex, name); #line 691 "./src/resolver/resolver.am" return (code_string)AmalgameList_get(self->GlobalTypes, idx); } #line 693 "./src/resolver/resolver.am" return "?"; } static code_bool Amalgame_Compiler_FullResolver_LookupIsLet(Amalgame_Compiler_FullResolver* self, code_string name) { #line 697 "./src/resolver/resolver.am" if (AmalgameMap_has(self->LocalIndex, name)) { #line 698 "./src/resolver/resolver.am" i64 idx = (i64)AmalgameMap_get(self->LocalIndex, name); #line 699 "./src/resolver/resolver.am" return (code_bool)(intptr_t)AmalgameList_get(self->LocalIsLets, idx); } #line 701 "./src/resolver/resolver.am" return 0; } static i64 Amalgame_Compiler_FullResolver_IndexOfLocal(Amalgame_Compiler_FullResolver* self, code_string name) { #line 708 "./src/resolver/resolver.am" if (AmalgameMap_has(self->LocalIndex, name)) { return (i64)AmalgameMap_get(self->LocalIndex, name); } #line 709 "./src/resolver/resolver.am" return -1LL; } static void Amalgame_Compiler_FullResolver_AddCapture(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* lam, code_string name, code_string typeName, i64 line, i64 col) { #line 717 "./src/resolver/resolver.am" i64 n = AmalgameList_count(lam->Args); #line 718 "./src/resolver/resolver.am" for (i64 i = 0LL; i < n; i++) { #line 719 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* arg = (Amalgame_Compiler_AstNode*)AmalgameList_get(lam->Args, i); #line 720 "./src/resolver/resolver.am" if (code_string_equals(arg->Name, name)) { return; } } #line 722 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* id = Amalgame_Compiler_AstNode_new(Amalgame_Compiler_NodeKind_IDENTIFIER, line, col); #line 723 "./src/resolver/resolver.am" id->Name = name; #line 724 "./src/resolver/resolver.am" id->Str = typeName; #line 725 "./src/resolver/resolver.am" AmalgameList_add(lam->Args, (void*)(intptr_t)(id)); } static void Amalgame_Compiler_FullResolver_TryCaptureLocalByName(Amalgame_Compiler_FullResolver* self, code_string name, i64 line, i64 col) { #line 735 "./src/resolver/resolver.am" if (self->LambdaInProgress == NULL) { return; } #line 736 "./src/resolver/resolver.am" i64 idx = Amalgame_Compiler_FullResolver_IndexOfLocal(self, name); #line 737 "./src/resolver/resolver.am" if (idx == -1LL) { return; } #line 738 "./src/resolver/resolver.am" if (idx >= self->LambdaBoundary) { return; } #line 739 "./src/resolver/resolver.am" code_string typeName = (code_string)AmalgameList_get(self->LocalTypes, idx); #line 740 "./src/resolver/resolver.am" if ((String_Length(typeName) == 0LL) || (code_string_equals(typeName, "?"))) { #line 741 "./src/resolver/resolver.am" typeName = "int"; } #line 743 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_AddCapture(self, self->LambdaInProgress, name, typeName, line, col); } static void Amalgame_Compiler_FullResolver_CaptureIdentsInInterpExpr(Amalgame_Compiler_FullResolver* self, code_string inner, i64 line, i64 col) { #line 751 "./src/resolver/resolver.am" i64 n = String_Length(inner); #line 752 "./src/resolver/resolver.am" code_string identStart = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"; #line 753 "./src/resolver/resolver.am" code_string identCont = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; #line 754 "./src/resolver/resolver.am" i64 i = 0LL; #line 755 "./src/resolver/resolver.am" while (i < n) { #line 756 "./src/resolver/resolver.am" code_string ch = String_Substring(inner, i, 1LL); #line 757 "./src/resolver/resolver.am" if (!String_Contains(identStart, ch)) { #line 758 "./src/resolver/resolver.am" i = (i + 1LL); #line 759 "./src/resolver/resolver.am" continue; } #line 761 "./src/resolver/resolver.am" i64 j = i + 1LL; #line 762 "./src/resolver/resolver.am" while (j < n) { #line 763 "./src/resolver/resolver.am" code_string cj = String_Substring(inner, j, 1LL); #line 764 "./src/resolver/resolver.am" if (!String_Contains(identCont, cj)) { break; } #line 765 "./src/resolver/resolver.am" j = (j + 1LL); } #line 771 "./src/resolver/resolver.am" code_bool skip = 0; #line 772 "./src/resolver/resolver.am" if (i > 0LL) { #line 773 "./src/resolver/resolver.am" code_string prev = String_Substring(inner, i - 1LL, 1LL); #line 774 "./src/resolver/resolver.am" if (code_string_equals(prev, ".")) { skip = 1; } } #line 776 "./src/resolver/resolver.am" if (!skip) { #line 777 "./src/resolver/resolver.am" code_string name = String_Substring(inner, i, j - i); #line 778 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_TryCaptureLocalByName(self, name, line, col); } #line 780 "./src/resolver/resolver.am" i = j; } } static void Amalgame_Compiler_FullResolver_Error(Amalgame_Compiler_FullResolver* self, code_string msg, Amalgame_Compiler_AstNode* node) { #line 787 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_EmitError(self, msg, node->Line, node->Column); } static void Amalgame_Compiler_FullResolver_ErrorMsg(Amalgame_Compiler_FullResolver* self, code_string msg) { #line 791 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_EmitError(self, msg, 0LL, 0LL); } static void Amalgame_Compiler_FullResolver_EmitError(Amalgame_Compiler_FullResolver* self, code_string msg, i64 line, i64 col) { #line 795 "./src/resolver/resolver.am" code_string file = self->CurrentFile; #line 796 "./src/resolver/resolver.am" code_string ln = String_FromInt(line); #line 797 "./src/resolver/resolver.am" code_string cl = String_FromInt(col); #line 798 "./src/resolver/resolver.am" code_string head = code_string_concat((code_string_concat("\nerror[resolver]: ", msg)), "\n"); #line 799 "./src/resolver/resolver.am" if ((String_Length(file) > 0LL) && (line > 0LL)) { #line 800 "./src/resolver/resolver.am" head = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(head, " --> ")), file)), ":")), ln)), ":")), cl)), "\n")); #line 801 "./src/resolver/resolver.am" void* snip = Amalgame_Compiler_SourceMap_GetLine(self->Sources, file, line); #line 802 "./src/resolver/resolver.am" head = (code_string_concat(head, Amalgame_Compiler_SourceSnippet_Format(snip, line, col))); } #line 804 "./src/resolver/resolver.am" AmalgameList_add(self->Errors, (void*)(intptr_t)(head)); #line 808 "./src/resolver/resolver.am" Amalgame_Compiler_ResolverError* raw = Amalgame_Compiler_ResolverError_new(msg, file, line, col); #line 809 "./src/resolver/resolver.am" AmalgameList_add(self->RawErrors, (void*)(intptr_t)(raw)); } code_bool Amalgame_Compiler_FullResolver_HasErrors(Amalgame_Compiler_FullResolver* self) { #line 813 "./src/resolver/resolver.am" return AmalgameList_count(self->Errors) > 0LL; } code_string Amalgame_Compiler_FullResolver_GetErrors(Amalgame_Compiler_FullResolver* self) { #line 817 "./src/resolver/resolver.am" code_string result = ""; #line 818 "./src/resolver/resolver.am" i64 count = AmalgameList_count(self->Errors); #line 819 "./src/resolver/resolver.am" for (i64 i = 0LL; i < count; i++) { #line 820 "./src/resolver/resolver.am" result = (code_string_concat(result, (code_string)AmalgameList_get(self->Errors, i))); } #line 822 "./src/resolver/resolver.am" return result; } i64 Amalgame_Compiler_FullResolver_ProgramCount(Amalgame_Compiler_FullResolver* self) { #line 831 "./src/resolver/resolver.am" return AmalgameList_count(self->Programs); } Amalgame_Compiler_AstNode* Amalgame_Compiler_FullResolver_ProgramAt(Amalgame_Compiler_FullResolver* self, i64 i) { #line 835 "./src/resolver/resolver.am" return (Amalgame_Compiler_AstNode*)AmalgameList_get(self->Programs, i); } i64 Amalgame_Compiler_FullResolver_GlobalCount(Amalgame_Compiler_FullResolver* self) { #line 842 "./src/resolver/resolver.am" return AmalgameList_count(self->GlobalNames); } code_string Amalgame_Compiler_FullResolver_GlobalNameAt(Amalgame_Compiler_FullResolver* self, i64 i) { #line 846 "./src/resolver/resolver.am" return (code_string)AmalgameList_get(self->GlobalNames, i); } code_string Amalgame_Compiler_FullResolver_GlobalTypeAt(Amalgame_Compiler_FullResolver* self, i64 i) { #line 850 "./src/resolver/resolver.am" return (code_string)AmalgameList_get(self->GlobalTypes, i); } void Amalgame_Compiler_FullResolver_ResolvePrograms(Amalgame_Compiler_FullResolver* self) { #line 854 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_CollectAll(self); #line 855 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveAll(self); } void Amalgame_Compiler_FullResolver_CollectAll(Amalgame_Compiler_FullResolver* self) { #line 864 "./src/resolver/resolver.am" i64 progCount = AmalgameList_count(self->Programs); #line 865 "./src/resolver/resolver.am" for (i64 p = 0LL; p < progCount; p++) { #line 866 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_CollectProgram(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(self->Programs, p)); } } void Amalgame_Compiler_FullResolver_ResolveAll(Amalgame_Compiler_FullResolver* self) { #line 876 "./src/resolver/resolver.am" i64 progCount = AmalgameList_count(self->Programs); #line 877 "./src/resolver/resolver.am" for (i64 p = 0LL; p < progCount; p++) { #line 878 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveProgram(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(self->Programs, p)); } } static void Amalgame_Compiler_FullResolver_CollectProgram(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* prog) { #line 885 "./src/resolver/resolver.am" i64 count = AmalgameList_count(prog->Children); #line 886 "./src/resolver/resolver.am" for (i64 i = 0LL; i < count; i++) { #line 887 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_CollectDecl(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i)); } } static void Amalgame_Compiler_FullResolver_CollectDecl(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* decl) { #line 892 "./src/resolver/resolver.am" Amalgame_Compiler_NodeKind k = decl->Kind; #line 893 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { #line 894 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, decl->Name, decl->Name, 0); #line 895 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_CollectClassMembers(self, decl); } #line 897 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) { #line 898 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, decl->Name, decl->Name, 0); #line 899 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_CollectEnumMembers(self, decl); } } static void Amalgame_Compiler_FullResolver_CollectClassMembers(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* cls) { #line 904 "./src/resolver/resolver.am" code_string name = cls->Name; #line 905 "./src/resolver/resolver.am" AmalgameList* kids = cls->Children; #line 906 "./src/resolver/resolver.am" i64 members = AmalgameList_count(kids); #line 907 "./src/resolver/resolver.am" for (i64 i = 0LL; i < members; i++) { #line 908 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_CollectClassMember(self, name, (Amalgame_Compiler_AstNode*)AmalgameList_get(kids, i)); } } static void Amalgame_Compiler_FullResolver_CollectClassMember(Amalgame_Compiler_FullResolver* self, code_string className, Amalgame_Compiler_AstNode* m) { #line 913 "./src/resolver/resolver.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 914 "./src/resolver/resolver.am" if (mk == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 915 "./src/resolver/resolver.am" Amalgame_Compiler_MemberTable_Set(self->Members, className, m->Name, m->Str); } #line 917 "./src/resolver/resolver.am" if (mk == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 918 "./src/resolver/resolver.am" Amalgame_Compiler_MemberTable_Set(self->Members, className, m->Name, m->Str); #line 922 "./src/resolver/resolver.am" AmalgameMap_set(self->MethodNodeIndex, code_string_concat((code_string_concat(className, ".")), m->Name), (void*)(intptr_t)(m)); } } static void Amalgame_Compiler_FullResolver_CollectEnumMembers(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* en) { #line 927 "./src/resolver/resolver.am" code_string name = en->Name; #line 928 "./src/resolver/resolver.am" AmalgameList* kids = en->Children; #line 929 "./src/resolver/resolver.am" i64 count = AmalgameList_count(kids); #line 930 "./src/resolver/resolver.am" for (i64 i = 0LL; i < count; i++) { #line 931 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_CollectEnumMember(self, name, (Amalgame_Compiler_AstNode*)AmalgameList_get(kids, i)); } } static void Amalgame_Compiler_FullResolver_CollectEnumMember(Amalgame_Compiler_FullResolver* self, code_string enumName, Amalgame_Compiler_AstNode* m) { #line 936 "./src/resolver/resolver.am" Amalgame_Compiler_MemberTable_Set(self->Members, enumName, m->Name, enumName); #line 937 "./src/resolver/resolver.am" code_string qualName = code_string_concat((code_string_concat(enumName, "_")), m->Name); #line 938 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareGlobal(self, qualName, enumName, 0); } static void Amalgame_Compiler_FullResolver_ResolveEnumChild(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* m) { #line 944 "./src/resolver/resolver.am" if (m->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 945 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveMethod(self, m); } } static void Amalgame_Compiler_FullResolver_ResolveProgram(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* prog) { #line 952 "./src/resolver/resolver.am" self->CurrentFile = prog->Str2; #line 953 "./src/resolver/resolver.am" i64 count = AmalgameList_count(prog->Children); #line 954 "./src/resolver/resolver.am" for (i64 i = 0LL; i < count; i++) { #line 955 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveDecl(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i)); } } static void Amalgame_Compiler_FullResolver_ResolveDecl(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* decl) { #line 960 "./src/resolver/resolver.am" Amalgame_Compiler_NodeKind k = decl->Kind; #line 961 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { #line 962 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveClass(self, decl); } #line 964 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) { #line 965 "./src/resolver/resolver.am" AmalgameList* enumKids = decl->Children; #line 966 "./src/resolver/resolver.am" i64 methods = AmalgameList_count(enumKids); #line 967 "./src/resolver/resolver.am" for (i64 i = 0LL; i < methods; i++) { #line 968 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveEnumChild(self, (void*)AmalgameList_get(enumKids, i)); } } } static void Amalgame_Compiler_FullResolver_ResolveClass(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* cls) { #line 974 "./src/resolver/resolver.am" code_string prevClass = self->CurrentClass; #line 975 "./src/resolver/resolver.am" self->CurrentClass = cls->Name; #line 976 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PushScope(self, code_string_concat("class:", cls->Name)); #line 979 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareCurrent(self, "this", cls->Name, 0); #line 982 "./src/resolver/resolver.am" AmalgameList* classKids = cls->Children; #line 983 "./src/resolver/resolver.am" i64 members = AmalgameList_count(classKids); #line 984 "./src/resolver/resolver.am" for (i64 i = 0LL; i < members; i++) { #line 985 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PreRegisterMember(self, (void*)AmalgameList_get(classKids, i)); } #line 989 "./src/resolver/resolver.am" for (i64 j = 0LL; j < members; j++) { #line 990 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveMember(self, (void*)AmalgameList_get(classKids, j)); } #line 993 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PopScope(self); #line 994 "./src/resolver/resolver.am" self->CurrentClass = prevClass; } static void Amalgame_Compiler_FullResolver_PreRegisterMember(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* m) { #line 998 "./src/resolver/resolver.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 999 "./src/resolver/resolver.am" if (mk == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 1000 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareCurrent(self, m->Name, m->Str, 0); } #line 1002 "./src/resolver/resolver.am" if (mk == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 1003 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareCurrent(self, m->Name, m->Str, 0); } } static void Amalgame_Compiler_FullResolver_ResolveMember(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* m) { #line 1008 "./src/resolver/resolver.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 1009 "./src/resolver/resolver.am" if (mk == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 1010 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveMethod(self, m); } #line 1012 "./src/resolver/resolver.am" if (mk == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 1013 "./src/resolver/resolver.am" if (m->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, m->Left); } } } static void Amalgame_Compiler_FullResolver_ResolveMethod(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* method) { #line 1018 "./src/resolver/resolver.am" code_string prevReturn = self->CurrentReturn; #line 1019 "./src/resolver/resolver.am" self->CurrentReturn = method->Str; #line 1020 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PushScope(self, code_string_concat("method:", method->Name)); #line 1023 "./src/resolver/resolver.am" i64 params = AmalgameList_count(method->Params); #line 1024 "./src/resolver/resolver.am" for (i64 i = 0LL; i < params; i++) { #line 1025 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 1026 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareCurrent(self, p->Name, p->Str, 1); } #line 1030 "./src/resolver/resolver.am" if (method->Body != NULL) { #line 1031 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveBlock(self, method->Body); } #line 1034 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PopScope(self); #line 1035 "./src/resolver/resolver.am" self->CurrentReturn = prevReturn; } static void Amalgame_Compiler_FullResolver_ResolveBlock(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* block) { #line 1039 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PushScope(self, "block"); #line 1040 "./src/resolver/resolver.am" i64 stmts = AmalgameList_count(block->Children); #line 1041 "./src/resolver/resolver.am" for (i64 i = 0LL; i < stmts; i++) { #line 1042 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveStmt(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(block->Children, i)); } #line 1044 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PopScope(self); } static void Amalgame_Compiler_FullResolver_ResolveStmt(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt) { #line 1048 "./src/resolver/resolver.am" if (stmt == NULL) { return; } #line 1049 "./src/resolver/resolver.am" Amalgame_Compiler_NodeKind k = stmt->Kind; #line 1051 "./src/resolver/resolver.am" { /* match k */ if (k == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 1054 "./src/resolver/resolver.am" if (stmt->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, stmt->Left); } #line 1055 "./src/resolver/resolver.am" code_bool isLet = stmt->Flag == 0; #line 1060 "./src/resolver/resolver.am" code_string declType = stmt->Str; #line 1061 "./src/resolver/resolver.am" if ((String_Length(declType) == 0LL) && (stmt->Left != NULL)) { #line 1062 "./src/resolver/resolver.am" declType = Amalgame_Compiler_FullResolver_InferExprType(self, stmt->Left); } #line 1064 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareCurrent(self, stmt->Name, declType, isLet); #line 1065 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_RETURN_STMT) { #line 1068 "./src/resolver/resolver.am" if (stmt->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, stmt->Left); } #line 1069 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_IF_STMT) { #line 1072 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveIf(self, stmt); #line 1073 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_WHILE_STMT) { #line 1076 "./src/resolver/resolver.am" if (stmt->Cond != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, stmt->Cond); } #line 1077 "./src/resolver/resolver.am" self->LoopDepth = (self->LoopDepth + 1LL); #line 1078 "./src/resolver/resolver.am" if (stmt->Body != NULL) { Amalgame_Compiler_FullResolver_ResolveBlock(self, stmt->Body); } #line 1079 "./src/resolver/resolver.am" self->LoopDepth = (self->LoopDepth - 1LL); #line 1080 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_FOR_IN_STMT) { #line 1083 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveForIn(self, stmt); #line 1084 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_BREAK_STMT) { #line 1087 "./src/resolver/resolver.am" if (self->LoopDepth == 0LL) { Amalgame_Compiler_FullResolver_Error(self, "'break' outside loop", stmt); } #line 1088 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_CONTINUE_STMT) { #line 1091 "./src/resolver/resolver.am" if (self->LoopDepth == 0LL) { Amalgame_Compiler_FullResolver_Error(self, "'continue' outside loop", stmt); } #line 1092 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_TRY_STMT) { #line 1095 "./src/resolver/resolver.am" if (stmt->Body != NULL) { Amalgame_Compiler_FullResolver_ResolveBlock(self, stmt->Body); } #line 1096 "./src/resolver/resolver.am" if (stmt->Else != NULL) { #line 1097 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PushScope(self, "catch"); #line 1098 "./src/resolver/resolver.am" if (String_Length(stmt->Name) > 0LL) { #line 1099 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareCurrent(self, stmt->Name, "void*", 1); } #line 1101 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveBlock(self, stmt->Else); #line 1102 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PopScope(self); } #line 1104 "./src/resolver/resolver.am" if (stmt->Cond != NULL) { Amalgame_Compiler_FullResolver_ResolveBlock(self, stmt->Cond); } #line 1105 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_THROW_STMT) { #line 1108 "./src/resolver/resolver.am" if (stmt->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, stmt->Left); } #line 1109 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_INLINE_C) { #line 1113 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_ASSIGN) { #line 1116 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveAssign(self, stmt); #line 1117 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_BLOCK) { #line 1121 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveBlock(self, stmt); #line 1122 "./src/resolver/resolver.am" return; } else { } } #line 1129 "./src/resolver/resolver.am" if (code_string_equals(stmt->Name, "__match__")) { #line 1130 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveMatch(self, stmt); #line 1131 "./src/resolver/resolver.am" return; } #line 1134 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveExpr(self, stmt); } static void Amalgame_Compiler_FullResolver_ResolveIf(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt) { #line 1138 "./src/resolver/resolver.am" if (stmt->Cond != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, stmt->Cond); } #line 1139 "./src/resolver/resolver.am" if (stmt->Body != NULL) { Amalgame_Compiler_FullResolver_ResolveBlock(self, stmt->Body); } #line 1140 "./src/resolver/resolver.am" if (stmt->Else != NULL) { #line 1141 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveElseBranch(self, stmt->Else); } } static void Amalgame_Compiler_FullResolver_ResolveElseBranch(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* branch) { #line 1146 "./src/resolver/resolver.am" if (branch == NULL) { return; } #line 1147 "./src/resolver/resolver.am" Amalgame_Compiler_NodeKind bk = branch->Kind; #line 1148 "./src/resolver/resolver.am" if (bk == Amalgame_Compiler_NodeKind_IF_STMT) { #line 1149 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveIf(self, branch); } else { #line 1151 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveBlock(self, branch); } } static void Amalgame_Compiler_FullResolver_ResolveForIn(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt) { #line 1157 "./src/resolver/resolver.am" if (stmt->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, stmt->Left); } #line 1158 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PushScope(self, "for-in"); #line 1160 "./src/resolver/resolver.am" code_string elemType = "?"; #line 1161 "./src/resolver/resolver.am" if (stmt->Left != NULL) { #line 1162 "./src/resolver/resolver.am" code_string colType = Amalgame_Compiler_FullResolver_InferExprType(self, stmt->Left); #line 1163 "./src/resolver/resolver.am" elemType = Amalgame_Compiler_FullResolver_CollectionElemType(self, colType); } #line 1165 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareCurrent(self, stmt->Name, elemType, 1); #line 1166 "./src/resolver/resolver.am" self->LoopDepth = (self->LoopDepth + 1LL); #line 1167 "./src/resolver/resolver.am" if (stmt->Body != NULL) { Amalgame_Compiler_FullResolver_ResolveBlock(self, stmt->Body); } #line 1168 "./src/resolver/resolver.am" self->LoopDepth = (self->LoopDepth - 1LL); #line 1169 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PopScope(self); } static void Amalgame_Compiler_FullResolver_ResolveAssign(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt) { #line 1173 "./src/resolver/resolver.am" if (stmt->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, stmt->Left); } #line 1174 "./src/resolver/resolver.am" if (stmt->Right != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, stmt->Right); } #line 1176 "./src/resolver/resolver.am" if ((stmt->Left != NULL) && (stmt->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 1177 "./src/resolver/resolver.am" code_string varName = stmt->Left->Name; #line 1178 "./src/resolver/resolver.am" if (Amalgame_Compiler_FullResolver_LookupIsLet(self, varName)) { #line 1179 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_Error(self, code_string_concat((code_string_concat("Cannot assign to immutable binding '", varName)), "'"), stmt->Left); } } } static void Amalgame_Compiler_FullResolver_ResolveMatch(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* stmt) { #line 1185 "./src/resolver/resolver.am" if (stmt->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, stmt->Left); } #line 1186 "./src/resolver/resolver.am" i64 armCount = AmalgameList_count(stmt->Children); #line 1187 "./src/resolver/resolver.am" for (i64 i = 0LL; i < armCount; i++) { #line 1188 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveMatchArm(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(stmt->Children, i)); } } static void Amalgame_Compiler_FullResolver_ResolveMatchArm(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* arm) { #line 1193 "./src/resolver/resolver.am" if (arm == NULL) { return; } #line 1194 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PushScope(self, "match-arm"); #line 1196 "./src/resolver/resolver.am" if (arm->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, arm->Left); } #line 1197 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* armBody = arm->Right; #line 1198 "./src/resolver/resolver.am" if (armBody != NULL) { #line 1199 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveArmBody(self, armBody); } #line 1201 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PopScope(self); } static void Amalgame_Compiler_FullResolver_ResolveArmBody(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* body) { #line 1205 "./src/resolver/resolver.am" Amalgame_Compiler_NodeKind bk = body->Kind; #line 1206 "./src/resolver/resolver.am" if (bk == Amalgame_Compiler_NodeKind_BLOCK) { #line 1207 "./src/resolver/resolver.am" AmalgameList* kids = body->Children; #line 1208 "./src/resolver/resolver.am" i64 count = AmalgameList_count(kids); #line 1209 "./src/resolver/resolver.am" for (i64 i = 0LL; i < count; i++) { #line 1210 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveStmt(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(kids, i)); } } else { #line 1213 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveStmt(self, body); } } static code_bool Amalgame_Compiler_FullResolver_HasLambdaArg(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* call) { #line 1239 "./src/resolver/resolver.am" i64 argc = AmalgameList_count(call->Args); #line 1240 "./src/resolver/resolver.am" for (i64 i = 0LL; i < argc; i++) { #line 1241 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* arg = (Amalgame_Compiler_AstNode*)AmalgameList_get(call->Args, i); #line 1242 "./src/resolver/resolver.am" if ((arg->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) && (code_string_equals(arg->Name, "__lambda__"))) { #line 1243 "./src/resolver/resolver.am" return 1; } } #line 1246 "./src/resolver/resolver.am" return 0; } static void Amalgame_Compiler_FullResolver_PatchLambdaParamTypes(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* call) { #line 1250 "./src/resolver/resolver.am" if (call->Left == NULL) { return; } #line 1251 "./src/resolver/resolver.am" if (call->Left->Kind != Amalgame_Compiler_NodeKind_MEMBER) { return; } #line 1252 "./src/resolver/resolver.am" code_string methodName = call->Left->Name; #line 1253 "./src/resolver/resolver.am" code_bool isSingleT = 0; #line 1254 "./src/resolver/resolver.am" if (code_string_equals(methodName, "Map")) { isSingleT = 1; } else if (code_string_equals(methodName, "Filter")) { #line 1255 "./src/resolver/resolver.am" isSingleT = 1; } else if (code_string_equals(methodName, "ForEach")) { #line 1256 "./src/resolver/resolver.am" isSingleT = 1; } else if (code_string_equals(methodName, "Any")) { #line 1257 "./src/resolver/resolver.am" isSingleT = 1; } else if (code_string_equals(methodName, "All")) { #line 1258 "./src/resolver/resolver.am" isSingleT = 1; } else if (code_string_equals(methodName, "CountIf")) { #line 1259 "./src/resolver/resolver.am" isSingleT = 1; } #line 1260 "./src/resolver/resolver.am" if (!isSingleT) { return; } #line 1261 "./src/resolver/resolver.am" if (call->Left->Left == NULL) { return; } #line 1265 "./src/resolver/resolver.am" if (!Amalgame_Compiler_FullResolver_HasLambdaArg(self, call)) { return; } #line 1266 "./src/resolver/resolver.am" code_string recvType = Amalgame_Compiler_FullResolver_InferExprType(self, call->Left->Left); #line 1267 "./src/resolver/resolver.am" code_string elem = Amalgame_Compiler_FullResolver_CollectionElemType(self, recvType); #line 1268 "./src/resolver/resolver.am" if (String_Length(elem) == 0LL) { return; } #line 1269 "./src/resolver/resolver.am" if (code_string_equals(elem, "?")) { return; } #line 1270 "./src/resolver/resolver.am" i64 argc = AmalgameList_count(call->Args); #line 1271 "./src/resolver/resolver.am" for (i64 i = 0LL; i < argc; i++) { #line 1272 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* arg = (Amalgame_Compiler_AstNode*)AmalgameList_get(call->Args, i); #line 1273 "./src/resolver/resolver.am" if ((arg->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) && (code_string_equals(arg->Name, "__lambda__"))) { #line 1274 "./src/resolver/resolver.am" i64 pn = AmalgameList_count(arg->Params); #line 1275 "./src/resolver/resolver.am" if (pn >= 1LL) { #line 1276 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(arg->Params, 0LL); #line 1277 "./src/resolver/resolver.am" if ((String_Length(p->Str) == 0LL) || (code_string_equals(p->Str, "?"))) { #line 1278 "./src/resolver/resolver.am" p->Str = elem; } } } } } static Amalgame_Compiler_AstNode* Amalgame_Compiler_FullResolver_FindMethodInPrograms(Amalgame_Compiler_FullResolver* self, code_string className, code_string methodName) { #line 1309 "./src/resolver/resolver.am" code_string key = code_string_concat((code_string_concat(className, ".")), methodName); #line 1310 "./src/resolver/resolver.am" if (!AmalgameMap_has(self->MethodNodeIndex, key)) { return NULL; } #line 1311 "./src/resolver/resolver.am" return (Amalgame_Compiler_AstNode*)AmalgameMap_get(self->MethodNodeIndex, key); } static void Amalgame_Compiler_FullResolver_PatchLambdasFromTypedClosureParams(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* call, Amalgame_Compiler_AstNode* methodDecl) { #line 1315 "./src/resolver/resolver.am" if (methodDecl == NULL) { return; } #line 1316 "./src/resolver/resolver.am" i64 pn = AmalgameList_count(methodDecl->Params); #line 1317 "./src/resolver/resolver.am" i64 argc = AmalgameList_count(call->Args); #line 1318 "./src/resolver/resolver.am" i64 lim = (pn < argc ? pn : argc); #line 1319 "./src/resolver/resolver.am" for (i64 ai = 0LL; ai < lim; ai++) { #line 1320 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* arg = (Amalgame_Compiler_AstNode*)AmalgameList_get(call->Args, ai); #line 1321 "./src/resolver/resolver.am" if (arg->Kind != Amalgame_Compiler_NodeKind_METHOD_DECL) { continue; } #line 1322 "./src/resolver/resolver.am" if (!code_string_equals(arg->Name, "__lambda__")) { continue; } #line 1323 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* param = (Amalgame_Compiler_AstNode*)AmalgameList_get(methodDecl->Params, ai); #line 1324 "./src/resolver/resolver.am" code_string paramT = param->Str; #line 1325 "./src/resolver/resolver.am" if (!String_StartsWith(paramT, "Closure<")) { continue; } #line 1326 "./src/resolver/resolver.am" if (!String_EndsWith(paramT, ">")) { continue; } #line 1327 "./src/resolver/resolver.am" code_string inner = String_Substring(paramT, 8LL, String_Length(paramT) - 9LL); #line 1328 "./src/resolver/resolver.am" AmalgameList* parts = Amalgame_Compiler_FullResolver_SplitTopLevelCommasResolver(self, inner); #line 1329 "./src/resolver/resolver.am" i64 pc = AmalgameList_count(parts); #line 1330 "./src/resolver/resolver.am" if (pc < 1LL) { continue; } #line 1332 "./src/resolver/resolver.am" i64 argTypeCount = pc - 1LL; #line 1333 "./src/resolver/resolver.am" i64 lamPn = AmalgameList_count(arg->Params); #line 1334 "./src/resolver/resolver.am" i64 toPatch = (argTypeCount < lamPn ? argTypeCount : lamPn); #line 1335 "./src/resolver/resolver.am" for (i64 li = 0LL; li < toPatch; li++) { #line 1336 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* lp = (Amalgame_Compiler_AstNode*)AmalgameList_get(arg->Params, li); #line 1337 "./src/resolver/resolver.am" if ((String_Length(lp->Str) == 0LL) || (code_string_equals(lp->Str, "?"))) { #line 1338 "./src/resolver/resolver.am" lp->Str = String_Trim((code_string)AmalgameList_get(parts, li)); } } } } static AmalgameList* Amalgame_Compiler_FullResolver_SplitTopLevelCommasResolver(Amalgame_Compiler_FullResolver* self, code_string s) { #line 1347 "./src/resolver/resolver.am" AmalgameList* parts = AmalgameList_new(); #line 1348 "./src/resolver/resolver.am" i64 n = String_Length(s); #line 1349 "./src/resolver/resolver.am" i64 depth = 0LL; #line 1350 "./src/resolver/resolver.am" code_string cur = ""; #line 1351 "./src/resolver/resolver.am" for (i64 i = 0LL; i < n; i++) { #line 1352 "./src/resolver/resolver.am" code_string ch = String_Substring(s, i, 1LL); #line 1353 "./src/resolver/resolver.am" if (code_string_equals(ch, "<")) { depth = (depth + 1LL); cur = (code_string_concat(cur, ch)); } else if (code_string_equals(ch, ">")) { #line 1354 "./src/resolver/resolver.am" depth = (depth - 1LL); cur = (code_string_concat(cur, ch)); } else if ((code_string_equals(ch, ",")) && (depth == 0LL)) { #line 1356 "./src/resolver/resolver.am" AmalgameList_add(parts, (void*)(intptr_t)(cur)); #line 1357 "./src/resolver/resolver.am" cur = ""; } else { #line 1359 "./src/resolver/resolver.am" cur = (code_string_concat(cur, ch)); } } #line 1362 "./src/resolver/resolver.am" if (String_Length(cur) > 0LL) { AmalgameList_add(parts, (void*)(intptr_t)(cur)); } #line 1363 "./src/resolver/resolver.am" return parts; } static void Amalgame_Compiler_FullResolver_PatchLambdaParamTypesGeneric(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* expr) { #line 1372 "./src/resolver/resolver.am" if (!Amalgame_Compiler_FullResolver_HasLambdaArg(self, expr)) { return; } #line 1374 "./src/resolver/resolver.am" if (expr->Kind == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 1375 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* methodDecl = Amalgame_Compiler_FullResolver_FindMethodInPrograms(self, expr->Name, expr->Name); #line 1376 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PatchLambdasFromTypedClosureParams(self, expr, methodDecl); #line 1377 "./src/resolver/resolver.am" return; } #line 1383 "./src/resolver/resolver.am" if (((expr->Kind == Amalgame_Compiler_NodeKind_CALL) && (expr->Left != NULL)) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER)) { #line 1384 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* mem = expr->Left; #line 1385 "./src/resolver/resolver.am" if (mem->Left == NULL) { return; } #line 1386 "./src/resolver/resolver.am" code_string recvClass = ""; #line 1387 "./src/resolver/resolver.am" if (mem->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 1388 "./src/resolver/resolver.am" code_string recvName = mem->Left->Name; #line 1389 "./src/resolver/resolver.am" if (Amalgame_Compiler_FullResolver_LookupInScopes(self, recvName)) { #line 1390 "./src/resolver/resolver.am" code_string t = Amalgame_Compiler_FullResolver_GetTypeName(self, recvName); #line 1391 "./src/resolver/resolver.am" if (code_string_equals(t, recvName)) { #line 1394 "./src/resolver/resolver.am" recvClass = recvName; } else if ((String_Length(t) > 0LL) && (!code_string_equals(t, "?"))) { #line 1399 "./src/resolver/resolver.am" if (String_EndsWith(t, "?")) { #line 1400 "./src/resolver/resolver.am" recvClass = String_Substring(t, 0LL, String_Length(t) - 1LL); } else { #line 1402 "./src/resolver/resolver.am" recvClass = t; } } } } #line 1407 "./src/resolver/resolver.am" if (String_Length(recvClass) == 0LL) { return; } #line 1408 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* methodDecl = Amalgame_Compiler_FullResolver_FindMethodInPrograms(self, recvClass, mem->Name); #line 1409 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PatchLambdasFromTypedClosureParams(self, expr, methodDecl); } } static void Amalgame_Compiler_FullResolver_ResolveExpr(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* expr) { #line 1416 "./src/resolver/resolver.am" if (expr == NULL) { return; } #line 1417 "./src/resolver/resolver.am" Amalgame_Compiler_NodeKind k = expr->Kind; #line 1418 "./src/resolver/resolver.am" { /* match k */ if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 1422 "./src/resolver/resolver.am" if (code_string_equals(expr->Name, "_unknown_")) { return; } #line 1426 "./src/resolver/resolver.am" if (code_string_equals(expr->Name, "_")) { return; } #line 1427 "./src/resolver/resolver.am" if (!Amalgame_Compiler_FullResolver_LookupInScopes(self, expr->Name)) { #line 1428 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_Error(self, code_string_concat((code_string_concat("Unknown symbol '", expr->Name)), "'"), expr); #line 1429 "./src/resolver/resolver.am" return; } #line 1437 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_TryCaptureLocalByName(self, expr->Name, expr->Line, expr->Column); #line 1438 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_BINARY) { #line 1441 "./src/resolver/resolver.am" if (expr->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, expr->Left); } #line 1442 "./src/resolver/resolver.am" if (expr->Right != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, expr->Right); } #line 1443 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_UNARY) { #line 1446 "./src/resolver/resolver.am" if (expr->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, expr->Left); } #line 1447 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_MEMBER) { #line 1451 "./src/resolver/resolver.am" if (expr->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, expr->Left); } #line 1452 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_CALL) { #line 1455 "./src/resolver/resolver.am" if (expr->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, expr->Left); } #line 1460 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PatchLambdaParamTypes(self, expr); #line 1466 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PatchLambdaParamTypesGeneric(self, expr); #line 1467 "./src/resolver/resolver.am" i64 argc = AmalgameList_count(expr->Args); #line 1468 "./src/resolver/resolver.am" for (i64 i = 0LL; i < argc; i++) { #line 1469 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i)); } #line 1471 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 1475 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PatchLambdaParamTypesGeneric(self, expr); #line 1476 "./src/resolver/resolver.am" i64 argc = AmalgameList_count(expr->Args); #line 1477 "./src/resolver/resolver.am" for (i64 i = 0LL; i < argc; i++) { #line 1478 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i)); } #line 1480 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_INDEX_EXPR) { #line 1483 "./src/resolver/resolver.am" if (expr->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, expr->Left); } #line 1484 "./src/resolver/resolver.am" if (expr->Right != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, expr->Right); } #line 1485 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_LIST_COMP) { #line 1492 "./src/resolver/resolver.am" if (expr->Right != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, expr->Right); } #line 1493 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PushScope(self, "list-comp"); #line 1494 "./src/resolver/resolver.am" code_string elemType = "?"; #line 1495 "./src/resolver/resolver.am" if (expr->Right != NULL) { #line 1496 "./src/resolver/resolver.am" code_string colType = Amalgame_Compiler_FullResolver_InferExprType(self, expr->Right); #line 1497 "./src/resolver/resolver.am" elemType = Amalgame_Compiler_FullResolver_CollectionElemType(self, colType); } #line 1499 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareCurrent(self, expr->Str, elemType, 1); #line 1500 "./src/resolver/resolver.am" if (expr->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, expr->Left); } #line 1501 "./src/resolver/resolver.am" if (expr->Cond != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, expr->Cond); } #line 1502 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PopScope(self); #line 1503 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_LIST_LITERAL) { #line 1508 "./src/resolver/resolver.am" i64 nc = AmalgameList_count(expr->Children); #line 1509 "./src/resolver/resolver.am" for (i64 i = 0LL; i < nc; i++) { #line 1510 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Children, i)); } #line 1512 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_ASSIGN) { #line 1515 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveAssign(self, expr); #line 1516 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_IF_STMT) { #line 1522 "./src/resolver/resolver.am" if (code_string_equals(expr->Name, "__match__")) { #line 1523 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_ResolveMatch(self, expr); #line 1524 "./src/resolver/resolver.am" return; } #line 1527 "./src/resolver/resolver.am" if (expr->Cond != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, expr->Cond); } #line 1528 "./src/resolver/resolver.am" if (expr->Body != NULL) { Amalgame_Compiler_FullResolver_ResolveBlock(self, expr->Body); } #line 1529 "./src/resolver/resolver.am" if (expr->Else != NULL) { Amalgame_Compiler_FullResolver_ResolveElseBranch(self, expr->Else); } #line 1530 "./src/resolver/resolver.am" return; } else if ((k == Amalgame_Compiler_NodeKind_METHOD_DECL) && (code_string_equals(expr->Name, "__lambda__"))) { #line 1544 "./src/resolver/resolver.am" Amalgame_Compiler_AstNode* prevLam = self->LambdaInProgress; #line 1545 "./src/resolver/resolver.am" i64 prevBoundary = self->LambdaBoundary; #line 1546 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PushScope(self, "lambda"); #line 1547 "./src/resolver/resolver.am" self->LambdaInProgress = expr; #line 1548 "./src/resolver/resolver.am" self->LambdaBoundary = AmalgameList_count(self->LocalNames); #line 1549 "./src/resolver/resolver.am" i64 pn = AmalgameList_count(expr->Params); #line 1550 "./src/resolver/resolver.am" for (i64 pi = 0LL; pi < pn; pi++) { #line 1551 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_DeclareLambdaParam(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Params, pi)); } #line 1553 "./src/resolver/resolver.am" if (expr->Left != NULL) { Amalgame_Compiler_FullResolver_ResolveExpr(self, expr->Left); } #line 1554 "./src/resolver/resolver.am" if (expr->Body != NULL) { Amalgame_Compiler_FullResolver_ResolveBlock(self, expr->Body); } #line 1555 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_PopScope(self); #line 1556 "./src/resolver/resolver.am" self->LambdaInProgress = prevLam; #line 1557 "./src/resolver/resolver.am" self->LambdaBoundary = prevBoundary; #line 1558 "./src/resolver/resolver.am" return; } else if (k == Amalgame_Compiler_NodeKind_LITERAL_STRING) { #line 1570 "./src/resolver/resolver.am" if (self->LambdaInProgress == NULL) { return; } #line 1571 "./src/resolver/resolver.am" code_string raw = expr->Str; #line 1572 "./src/resolver/resolver.am" i64 rn = String_Length(raw); #line 1573 "./src/resolver/resolver.am" i64 ri = 0LL; #line 1574 "./src/resolver/resolver.am" while (ri < rn) { #line 1575 "./src/resolver/resolver.am" code_string rch = String_Substring(raw, ri, 1LL); #line 1576 "./src/resolver/resolver.am" if (!code_string_equals(rch, "{")) { #line 1577 "./src/resolver/resolver.am" ri = (ri + 1LL); #line 1578 "./src/resolver/resolver.am" continue; } #line 1580 "./src/resolver/resolver.am" code_string rest = String_Substring(raw, ri + 1LL, (rn - ri) - 1LL); #line 1581 "./src/resolver/resolver.am" i64 close = String_IndexOf(rest, "}"); #line 1582 "./src/resolver/resolver.am" if (close <= 0LL) { #line 1583 "./src/resolver/resolver.am" ri = (ri + 1LL); #line 1584 "./src/resolver/resolver.am" continue; } #line 1586 "./src/resolver/resolver.am" code_string inner = String_Substring(raw, ri + 1LL, close); #line 1587 "./src/resolver/resolver.am" Amalgame_Compiler_FullResolver_CaptureIdentsInInterpExpr(self, inner, expr->Line, expr->Column); #line 1588 "./src/resolver/resolver.am" ri = (((ri + 1LL) + close) + 1LL); } #line 1590 "./src/resolver/resolver.am" return; } else { } } } static code_string Amalgame_Compiler_FullResolver_InferExprType(Amalgame_Compiler_FullResolver* self, Amalgame_Compiler_AstNode* expr) { #line 1600 "./src/resolver/resolver.am" if (expr == NULL) { return "?"; } #line 1601 "./src/resolver/resolver.am" Amalgame_Compiler_NodeKind k = expr->Kind; #line 1602 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { return Amalgame_Compiler_FullResolver_LookupType(self, expr->Name); } #line 1603 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_INT) { return "int"; } #line 1604 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_FLOAT) { return "float"; } #line 1605 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_STRING) { return "string"; } #line 1606 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_BOOL) { return "bool"; } #line 1607 "./src/resolver/resolver.am" if ((k == Amalgame_Compiler_NodeKind_BINARY) && (code_string_equals(expr->Str, ".."))) { return "range"; } #line 1611 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 1612 "./src/resolver/resolver.am" if (String_Length(self->CurrentClass) > 0LL) { #line 1613 "./src/resolver/resolver.am" return self->CurrentClass; } } #line 1616 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 1620 "./src/resolver/resolver.am" if (String_Length(expr->Str2) > 0LL) { #line 1621 "./src/resolver/resolver.am" return code_string_concat((code_string_concat((code_string_concat(expr->Name, "<")), expr->Str2)), ">"); } #line 1623 "./src/resolver/resolver.am" return expr->Name; } #line 1625 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_MEMBER) { #line 1626 "./src/resolver/resolver.am" if (expr->Left != NULL) { #line 1627 "./src/resolver/resolver.am" code_string targetType = Amalgame_Compiler_FullResolver_InferExprType(self, expr->Left); #line 1628 "./src/resolver/resolver.am" return Amalgame_Compiler_MemberTable_Get(self->Members, targetType, expr->Name); } } #line 1631 "./src/resolver/resolver.am" if (k == Amalgame_Compiler_NodeKind_CALL) { #line 1640 "./src/resolver/resolver.am" if ((expr->Left != NULL) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER)) { #line 1641 "./src/resolver/resolver.am" code_string mname = expr->Left->Name; #line 1642 "./src/resolver/resolver.am" if ((code_string_equals(mname, "Filter")) || (code_string_equals(mname, "ForEach"))) { #line 1643 "./src/resolver/resolver.am" if (expr->Left->Left != NULL) { #line 1644 "./src/resolver/resolver.am" return Amalgame_Compiler_FullResolver_InferExprType(self, expr->Left->Left); } } } } #line 1649 "./src/resolver/resolver.am" return "?"; } static code_string Amalgame_Compiler_FullResolver_CollectionElemType(Amalgame_Compiler_FullResolver* self, code_string typeKey) { #line 1653 "./src/resolver/resolver.am" if ((code_string_equals(typeKey, "range")) || (code_string_equals(typeKey, "int"))) { return "int"; } #line 1654 "./src/resolver/resolver.am" if (String_StartsWith(typeKey, "List<") && String_EndsWith(typeKey, ">")) { #line 1655 "./src/resolver/resolver.am" return String_Substring(typeKey, 5LL, String_Length(typeKey) - 6LL); } #line 1657 "./src/resolver/resolver.am" if (String_StartsWith(typeKey, "Set<") && String_EndsWith(typeKey, ">")) { #line 1658 "./src/resolver/resolver.am" return String_Substring(typeKey, 4LL, String_Length(typeKey) - 5LL); } #line 1660 "./src/resolver/resolver.am" if (String_EndsWith(typeKey, "[]")) { #line 1661 "./src/resolver/resolver.am" return String_Substring(typeKey, 0LL, String_Length(typeKey) - 2LL); } #line 1663 "./src/resolver/resolver.am" return "?"; } code_string Amalgame_Compiler_FullResolver_GetMemberType(Amalgame_Compiler_FullResolver* self, code_string className, code_string memberName) { #line 1669 "./src/resolver/resolver.am" return Amalgame_Compiler_MemberTable_Get(self->Members, className, memberName); } code_bool Amalgame_Compiler_FullResolver_HasMember(Amalgame_Compiler_FullResolver* self, code_string className, code_string memberName) { #line 1673 "./src/resolver/resolver.am" return Amalgame_Compiler_MemberTable_Has(self->Members, className, memberName); } code_string Amalgame_Compiler_FullResolver_GetVarType(Amalgame_Compiler_FullResolver* self, code_string name) { #line 1677 "./src/resolver/resolver.am" return Amalgame_Compiler_FullResolver_LookupType(self, name); } code_bool Amalgame_Compiler_FullResolver_HasSymbol(Amalgame_Compiler_FullResolver* self, code_string name) { #line 1685 "./src/resolver/resolver.am" return Amalgame_Compiler_FullResolver_LookupInScopes(self, name); } code_string Amalgame_Compiler_FullResolver_GetTypeName(Amalgame_Compiler_FullResolver* self, code_string name) { #line 1689 "./src/resolver/resolver.am" return Amalgame_Compiler_FullResolver_LookupType(self, name); } void Amalgame_Compiler_FullResolver_SetTypeName(Amalgame_Compiler_FullResolver* self, code_string name, code_string typeName) { #line 1693 "./src/resolver/resolver.am" i64 lc = AmalgameList_count(self->LocalNames); #line 1694 "./src/resolver/resolver.am" for (i64 i = 0LL; i < lc; i++) { #line 1695 "./src/resolver/resolver.am" if (code_string_equals((code_string)AmalgameList_get(self->LocalNames, i), name)) { #line 1696 "./src/resolver/resolver.am" AmalgameList_add(self->LocalTypes, (void*)(intptr_t)(typeName)); #line 1697 "./src/resolver/resolver.am" return; } } #line 1706 "./src/resolver/resolver.am" if (AmalgameMap_has(self->GlobalIndex, name)) { #line 1707 "./src/resolver/resolver.am" AmalgameList_add(self->GlobalTypes, (void*)(intptr_t)(typeName)); } } struct _Amalgame_Compiler_TypeError { code_string Message; code_string Filename; i64 Line; i64 Column; code_string Snippet; }; code_string Amalgame_Compiler_TypeError_ToString(Amalgame_Compiler_TypeError* self); Amalgame_Compiler_TypeError* Amalgame_Compiler_TypeError_new(code_string msg, code_string file, i64 line, i64 col) { Amalgame_Compiler_TypeError* self = (Amalgame_Compiler_TypeError*) GC_MALLOC(sizeof(Amalgame_Compiler_TypeError)); #line 28 "./src/typechecker.am" self->Message = msg; #line 29 "./src/typechecker.am" self->Filename = file; #line 30 "./src/typechecker.am" self->Line = line; #line 31 "./src/typechecker.am" self->Column = col; #line 32 "./src/typechecker.am" self->Snippet = ""; return self; } code_string Amalgame_Compiler_TypeError_ToString(Amalgame_Compiler_TypeError* self) { #line 36 "./src/typechecker.am" code_string ln = String_FromInt(self->Line); #line 37 "./src/typechecker.am" code_string col = String_FromInt(self->Column); #line 38 "./src/typechecker.am" code_string head = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("\nerror[typechecker]: ", self->Message)), "\n --> ")), self->Filename)), ":")), ln)), ":")), col)), "\n"); #line 39 "./src/typechecker.am" code_string snip = Amalgame_Compiler_SourceSnippet_Format(self->Snippet, self->Line, self->Column); #line 40 "./src/typechecker.am" return code_string_concat(head, snip); } struct _Amalgame_Compiler_TypeCheckResult { code_bool Success; AmalgameList* Errors; }; Amalgame_Compiler_TypeCheckResult* Amalgame_Compiler_TypeCheckResult_new() { Amalgame_Compiler_TypeCheckResult* self = (Amalgame_Compiler_TypeCheckResult*) GC_MALLOC(sizeof(Amalgame_Compiler_TypeCheckResult)); #line 50 "./src/typechecker.am" self->Success = 1; #line 51 "./src/typechecker.am" self->Errors = AmalgameList_new(); return self; } struct _Amalgame_Compiler_TypeChecker { AmalgameMap* ExprTypeMap; code_string CurrentReturn; code_string CurrentClass; AmalgameList* Errors; code_string Filename; Amalgame_Compiler_FullResolver* Symbols; AmalgameList* LocalNames; AmalgameList* LocalTypes; AmalgameList* ScopeStarts; AmalgameList* SubstParams; AmalgameList* SubstArgs; Amalgame_Compiler_SourceMap* Sources; code_bool Embedded; AmalgameList* PersistLocals; AmalgameList* ArenaLocals; i64 PersistDepth; }; static void Amalgame_Compiler_TypeChecker_PushScope(Amalgame_Compiler_TypeChecker* self); static void Amalgame_Compiler_TypeChecker_PopScope(Amalgame_Compiler_TypeChecker* self); static void Amalgame_Compiler_TypeChecker_DeclareLocal(Amalgame_Compiler_TypeChecker* self, code_string name, code_string typeName); static code_string Amalgame_Compiler_TypeChecker_LookupLocal(Amalgame_Compiler_TypeChecker* self, code_string name); Amalgame_Compiler_TypeCheckResult* Amalgame_Compiler_TypeChecker_Check(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* program); static code_string Amalgame_Compiler_TypeChecker_NodeKey(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node); static void Amalgame_Compiler_TypeChecker_SetType(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node, code_string typeKey); static code_string Amalgame_Compiler_TypeChecker_GetType(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node); code_string Amalgame_Compiler_TypeChecker_LookupNodeType(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node); static code_bool Amalgame_Compiler_TypeChecker_IsAssignable(Amalgame_Compiler_TypeChecker* self, code_string expected, code_string actual); static code_bool Amalgame_Compiler_TypeChecker_IsPrimitiveValue(Amalgame_Compiler_TypeChecker* self, code_string t); static code_string Amalgame_Compiler_TypeChecker_GenericBase(Amalgame_Compiler_TypeChecker* self, code_string t); static code_bool Amalgame_Compiler_TypeChecker_IsNumericWiden(Amalgame_Compiler_TypeChecker* self, code_string to, code_string from); static code_bool Amalgame_Compiler_TypeChecker_IsBool(Amalgame_Compiler_TypeChecker* self, code_string t); static code_bool Amalgame_Compiler_TypeChecker_IsNumeric(Amalgame_Compiler_TypeChecker* self, code_string t); static code_bool Amalgame_Compiler_TypeChecker_IsNullable(Amalgame_Compiler_TypeChecker* self, code_string t); static code_string Amalgame_Compiler_TypeChecker_BinaryResultType(Amalgame_Compiler_TypeChecker* self, code_string op, code_string left, code_string right); static code_string Amalgame_Compiler_TypeChecker_CollectionElementType(Amalgame_Compiler_TypeChecker* self, code_string typeKey); static code_bool Amalgame_Compiler_TypeChecker_SymbolFound(Amalgame_Compiler_TypeChecker* self, code_string name); static code_string Amalgame_Compiler_TypeChecker_SymbolTypeName(Amalgame_Compiler_TypeChecker* self, code_string name); static void Amalgame_Compiler_TypeChecker_Error(Amalgame_Compiler_TypeChecker* self, code_string msg, Amalgame_Compiler_AstNode* node); static void Amalgame_Compiler_TypeChecker_CheckBool(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node, code_string context); static code_string Amalgame_Compiler_TypeChecker_SymbolType(Amalgame_Compiler_TypeChecker* self, code_string name); static code_string Amalgame_Compiler_TypeChecker_MemberTypeOf(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* classDecl, code_string memberName); static void Amalgame_Compiler_TypeChecker_CheckProgram(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* prog); static void Amalgame_Compiler_TypeChecker_CheckDecl(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_TypeChecker_CheckClass(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* cls); static void Amalgame_Compiler_TypeChecker_CheckImplementsContract(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* cls); static void Amalgame_Compiler_TypeChecker_CheckOneInterface(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* cls, code_string iref); static void Amalgame_Compiler_TypeChecker_CheckOneInterfaceMethod(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* cls, code_string ifaceLabel, Amalgame_Compiler_AstNode* imethod); static Amalgame_Compiler_AstNode* Amalgame_Compiler_TypeChecker_FindInterface(Amalgame_Compiler_TypeChecker* self, code_string name); static Amalgame_Compiler_AstNode* Amalgame_Compiler_TypeChecker_FindInterfaceInProgram(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* prog, code_string name); static AmalgameList* Amalgame_Compiler_TypeChecker_SplitTopLevelCommas(Amalgame_Compiler_TypeChecker* self, code_string s); static code_string Amalgame_Compiler_TypeChecker_SubstType(Amalgame_Compiler_TypeChecker* self, code_string t); static code_string Amalgame_Compiler_TypeChecker_LookupParam(Amalgame_Compiler_TypeChecker* self, code_string t); static void Amalgame_Compiler_TypeChecker_CheckFieldDecl(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* field); static void Amalgame_Compiler_TypeChecker_CheckMethod(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* method); static code_bool Amalgame_Compiler_TypeChecker_HasDecorator(Amalgame_Compiler_TypeChecker* self, code_string list, code_string name); static void Amalgame_Compiler_TypeChecker_IsrCheckNoAlloc(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node); static code_bool Amalgame_Compiler_TypeChecker_NameIn(Amalgame_Compiler_TypeChecker* self, AmalgameList* xs, code_string n); static code_bool Amalgame_Compiler_TypeChecker_IsArenaOrigin(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* e); static code_bool Amalgame_Compiler_TypeChecker_IsPersistOrigin(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* e); static void Amalgame_Compiler_TypeChecker_TrackLocalOrigin(Amalgame_Compiler_TypeChecker* self, code_string name, Amalgame_Compiler_AstNode* init); static void Amalgame_Compiler_TypeChecker_CheckBlock(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* block); static void Amalgame_Compiler_TypeChecker_CheckStmt(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckVarDecl(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckReturn(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckIf(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckElseBranch(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* branch); static void Amalgame_Compiler_TypeChecker_CheckForIn(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckAssign(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckMatch(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_TypeChecker_CheckMatchArm(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* arm); static void Amalgame_Compiler_TypeChecker_CheckExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); static code_string Amalgame_Compiler_TypeChecker_CheckIfBranch(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* block); static void Amalgame_Compiler_TypeChecker_CheckBinaryExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_TypeChecker_CheckUnaryExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_TypeChecker_CheckMemberExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_TypeChecker_CheckCallExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_TypeChecker_CheckNewExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_TypeChecker_CheckIndexExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr); code_bool Amalgame_Compiler_TypeChecker_HasErrors(Amalgame_Compiler_TypeChecker* self); code_string Amalgame_Compiler_TypeChecker_FormatErrors(Amalgame_Compiler_TypeChecker* self); Amalgame_Compiler_TypeChecker* Amalgame_Compiler_TypeChecker_new(Amalgame_Compiler_FullResolver* symbols, code_string filename) { Amalgame_Compiler_TypeChecker* self = (Amalgame_Compiler_TypeChecker*) GC_MALLOC(sizeof(Amalgame_Compiler_TypeChecker)); #line 108 "./src/typechecker.am" self->ExprTypeMap = AmalgameMap_new(); #line 109 "./src/typechecker.am" self->CurrentReturn = "void"; #line 110 "./src/typechecker.am" self->CurrentClass = ""; #line 111 "./src/typechecker.am" self->Errors = AmalgameList_new(); #line 112 "./src/typechecker.am" self->Filename = filename; #line 113 "./src/typechecker.am" self->Symbols = symbols; #line 114 "./src/typechecker.am" self->LocalNames = AmalgameList_new(); #line 115 "./src/typechecker.am" self->LocalTypes = AmalgameList_new(); #line 116 "./src/typechecker.am" self->ScopeStarts = AmalgameList_new(); #line 117 "./src/typechecker.am" self->SubstParams = AmalgameList_new(); #line 118 "./src/typechecker.am" self->SubstArgs = AmalgameList_new(); #line 119 "./src/typechecker.am" self->Sources = Amalgame_Compiler_SourceMap_new(); #line 120 "./src/typechecker.am" self->Embedded = 0; #line 121 "./src/typechecker.am" self->PersistLocals = AmalgameList_new(); #line 122 "./src/typechecker.am" self->ArenaLocals = AmalgameList_new(); #line 123 "./src/typechecker.am" self->PersistDepth = 0LL; return self; } static void Amalgame_Compiler_TypeChecker_PushScope(Amalgame_Compiler_TypeChecker* self) { #line 129 "./src/typechecker.am" AmalgameList_add(self->ScopeStarts, (void*)(intptr_t)(AmalgameList_count(self->LocalNames))); } static void Amalgame_Compiler_TypeChecker_PopScope(Amalgame_Compiler_TypeChecker* self) { #line 133 "./src/typechecker.am" i64 depth = AmalgameList_count(self->ScopeStarts); #line 134 "./src/typechecker.am" if (depth == 0LL) { return; } #line 135 "./src/typechecker.am" i64 mark = (i64)(intptr_t)AmalgameList_get(self->ScopeStarts, depth - 1LL); #line 136 "./src/typechecker.am" AmalgameList_removeAt(self->ScopeStarts, depth - 1LL); #line 137 "./src/typechecker.am" while (AmalgameList_count(self->LocalNames) > mark) { #line 138 "./src/typechecker.am" i64 last = AmalgameList_count(self->LocalNames) - 1LL; #line 139 "./src/typechecker.am" AmalgameList_removeAt(self->LocalNames, last); #line 140 "./src/typechecker.am" AmalgameList_removeAt(self->LocalTypes, last); } } static void Amalgame_Compiler_TypeChecker_DeclareLocal(Amalgame_Compiler_TypeChecker* self, code_string name, code_string typeName) { #line 145 "./src/typechecker.am" AmalgameList_add(self->LocalNames, (void*)(intptr_t)(name)); #line 146 "./src/typechecker.am" AmalgameList_add(self->LocalTypes, (void*)(intptr_t)(typeName)); } static code_string Amalgame_Compiler_TypeChecker_LookupLocal(Amalgame_Compiler_TypeChecker* self, code_string name) { #line 150 "./src/typechecker.am" i64 i = AmalgameList_count(self->LocalNames) - 1LL; #line 151 "./src/typechecker.am" while (i >= 0LL) { #line 152 "./src/typechecker.am" if (code_string_equals((code_string)AmalgameList_get(self->LocalNames, i), name)) { return (code_string)AmalgameList_get(self->LocalTypes, i); } #line 153 "./src/typechecker.am" i = (i - 1LL); } #line 155 "./src/typechecker.am" return ""; } Amalgame_Compiler_TypeCheckResult* Amalgame_Compiler_TypeChecker_Check(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* program) { #line 161 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckProgram(self, program); #line 162 "./src/typechecker.am" Amalgame_Compiler_TypeCheckResult* result = Amalgame_Compiler_TypeCheckResult_new(); #line 163 "./src/typechecker.am" i64 ec = AmalgameList_count(self->Errors); #line 164 "./src/typechecker.am" result->Success = (ec == 0LL); #line 165 "./src/typechecker.am" for (i64 i = 0LL; i < ec; i++) { #line 166 "./src/typechecker.am" AmalgameList_add(result->Errors, (void*)(intptr_t)((Amalgame_Compiler_TypeError*)AmalgameList_get(self->Errors, i))); } #line 168 "./src/typechecker.am" return result; } static code_string Amalgame_Compiler_TypeChecker_NodeKey(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node) { #line 174 "./src/typechecker.am" code_string ln = String_FromInt(node->Line); #line 175 "./src/typechecker.am" code_string col = String_FromInt(node->Column); #line 176 "./src/typechecker.am" code_string knd = String_FromInt(node->Kind); #line 177 "./src/typechecker.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(knd, ":")), ln)), ":")), col)), ":")), node->Name)), ":")), node->Str); } static void Amalgame_Compiler_TypeChecker_SetType(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node, code_string typeKey) { #line 183 "./src/typechecker.am" AmalgameMap_set(self->ExprTypeMap, Amalgame_Compiler_TypeChecker_NodeKey(self, node), (void*)(intptr_t)(typeKey)); } static code_string Amalgame_Compiler_TypeChecker_GetType(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node) { #line 187 "./src/typechecker.am" code_string key = Amalgame_Compiler_TypeChecker_NodeKey(self, node); #line 188 "./src/typechecker.am" if (AmalgameMap_has(self->ExprTypeMap, key)) { #line 189 "./src/typechecker.am" return (code_string)AmalgameMap_get(self->ExprTypeMap, key); } #line 191 "./src/typechecker.am" return "?"; } code_string Amalgame_Compiler_TypeChecker_LookupNodeType(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node) { #line 199 "./src/typechecker.am" return Amalgame_Compiler_TypeChecker_GetType(self, node); } static code_bool Amalgame_Compiler_TypeChecker_IsAssignable(Amalgame_Compiler_TypeChecker* self, code_string expected, code_string actual) { #line 205 "./src/typechecker.am" if ((code_string_equals(expected, "?")) || (code_string_equals(actual, "?"))) { return 1; } #line 206 "./src/typechecker.am" if (code_string_equals(expected, actual)) { return 1; } #line 207 "./src/typechecker.am" if (code_string_equals(expected, "object")) { return 1; } #line 209 "./src/typechecker.am" code_string eBase = expected; #line 210 "./src/typechecker.am" code_string aBase = actual; #line 211 "./src/typechecker.am" if (String_EndsWith(expected, "?")) { #line 212 "./src/typechecker.am" eBase = String_Substring(expected, 0LL, String_Length(expected) - 1LL); } #line 214 "./src/typechecker.am" if (String_EndsWith(actual, "?")) { #line 215 "./src/typechecker.am" aBase = String_Substring(actual, 0LL, String_Length(actual) - 1LL); } #line 217 "./src/typechecker.am" if (code_string_equals(eBase, aBase)) { return 1; } #line 222 "./src/typechecker.am" if (code_string_equals(Amalgame_Compiler_TypeChecker_GenericBase(self, eBase), Amalgame_Compiler_TypeChecker_GenericBase(self, aBase))) { return 1; } #line 224 "./src/typechecker.am" if ((code_string_equals(actual, "null")) && String_EndsWith(expected, "?")) { return 1; } #line 229 "./src/typechecker.am" if ((code_string_equals(actual, "null")) && !Amalgame_Compiler_TypeChecker_IsPrimitiveValue(self, eBase)) { return 1; } #line 231 "./src/typechecker.am" if (Amalgame_Compiler_TypeChecker_IsNumericWiden(self, eBase, aBase)) { return 1; } #line 232 "./src/typechecker.am" return 0; } static code_bool Amalgame_Compiler_TypeChecker_IsPrimitiveValue(Amalgame_Compiler_TypeChecker* self, code_string t) { #line 240 "./src/typechecker.am" if (code_string_equals(t, "int")) { return 1; } #line 241 "./src/typechecker.am" if (code_string_equals(t, "i64")) { return 1; } #line 242 "./src/typechecker.am" if (code_string_equals(t, "i32")) { return 1; } #line 243 "./src/typechecker.am" if (code_string_equals(t, "i16")) { return 1; } #line 244 "./src/typechecker.am" if (code_string_equals(t, "i8")) { return 1; } #line 245 "./src/typechecker.am" if (code_string_equals(t, "u64")) { return 1; } #line 246 "./src/typechecker.am" if (code_string_equals(t, "u32")) { return 1; } #line 247 "./src/typechecker.am" if (code_string_equals(t, "u16")) { return 1; } #line 248 "./src/typechecker.am" if (code_string_equals(t, "u8")) { return 1; } #line 249 "./src/typechecker.am" if (code_string_equals(t, "float")) { return 1; } #line 250 "./src/typechecker.am" if (code_string_equals(t, "double")) { return 1; } #line 251 "./src/typechecker.am" if (code_string_equals(t, "f32")) { return 1; } #line 252 "./src/typechecker.am" if (code_string_equals(t, "f64")) { return 1; } #line 253 "./src/typechecker.am" if (code_string_equals(t, "bool")) { return 1; } #line 254 "./src/typechecker.am" if (code_string_equals(t, "char")) { return 1; } #line 255 "./src/typechecker.am" if (code_string_equals(t, "void")) { return 1; } #line 256 "./src/typechecker.am" return 0; } static code_string Amalgame_Compiler_TypeChecker_GenericBase(Amalgame_Compiler_TypeChecker* self, code_string t) { #line 260 "./src/typechecker.am" i64 lt = String_IndexOf(t, "<"); #line 261 "./src/typechecker.am" if (lt > 0LL) { #line 262 "./src/typechecker.am" return String_Substring(t, 0LL, lt); } #line 264 "./src/typechecker.am" return t; } static code_bool Amalgame_Compiler_TypeChecker_IsNumericWiden(Amalgame_Compiler_TypeChecker* self, code_string to, code_string from) { #line 268 "./src/typechecker.am" if (code_string_equals(to, "double")) { #line 269 "./src/typechecker.am" if (((((code_string_equals(from, "float")) || (code_string_equals(from, "int"))) || (code_string_equals(from, "i64"))) || (code_string_equals(from, "i32"))) || (code_string_equals(from, "f32"))) { #line 270 "./src/typechecker.am" return 1; } } #line 273 "./src/typechecker.am" if (code_string_equals(to, "float")) { #line 274 "./src/typechecker.am" if (((code_string_equals(from, "int")) || (code_string_equals(from, "i32"))) || (code_string_equals(from, "f32"))) { #line 275 "./src/typechecker.am" return 1; } } #line 278 "./src/typechecker.am" return 0; } static code_bool Amalgame_Compiler_TypeChecker_IsBool(Amalgame_Compiler_TypeChecker* self, code_string t) { #line 282 "./src/typechecker.am" return (code_string_equals(t, "bool")) || (code_string_equals(t, "?")); } static code_bool Amalgame_Compiler_TypeChecker_IsNumeric(Amalgame_Compiler_TypeChecker* self, code_string t) { #line 286 "./src/typechecker.am" if (code_string_equals(t, "int")) { return 1; } #line 287 "./src/typechecker.am" if (code_string_equals(t, "float")) { return 1; } #line 288 "./src/typechecker.am" if (code_string_equals(t, "double")) { return 1; } #line 289 "./src/typechecker.am" if (code_string_equals(t, "i8")) { return 1; } #line 290 "./src/typechecker.am" if (code_string_equals(t, "i16")) { return 1; } #line 291 "./src/typechecker.am" if (code_string_equals(t, "i32")) { return 1; } #line 292 "./src/typechecker.am" if (code_string_equals(t, "i64")) { return 1; } #line 293 "./src/typechecker.am" if (code_string_equals(t, "u8")) { return 1; } #line 294 "./src/typechecker.am" if (code_string_equals(t, "u16")) { return 1; } #line 295 "./src/typechecker.am" if (code_string_equals(t, "u32")) { return 1; } #line 296 "./src/typechecker.am" if (code_string_equals(t, "u64")) { return 1; } #line 297 "./src/typechecker.am" if (code_string_equals(t, "f32")) { return 1; } #line 298 "./src/typechecker.am" if (code_string_equals(t, "f64")) { return 1; } #line 299 "./src/typechecker.am" return 0; } static code_bool Amalgame_Compiler_TypeChecker_IsNullable(Amalgame_Compiler_TypeChecker* self, code_string t) { #line 303 "./src/typechecker.am" return String_EndsWith(t, "?"); } static code_string Amalgame_Compiler_TypeChecker_BinaryResultType(Amalgame_Compiler_TypeChecker* self, code_string op, code_string left, code_string right) { #line 308 "./src/typechecker.am" if ((((((code_string_equals(op, "==")) || (code_string_equals(op, "!="))) || (code_string_equals(op, "<"))) || (code_string_equals(op, ">"))) || (code_string_equals(op, "<="))) || (code_string_equals(op, ">="))) { #line 309 "./src/typechecker.am" return "bool"; } #line 312 "./src/typechecker.am" if ((code_string_equals(op, "&&")) || (code_string_equals(op, "||"))) { return "bool"; } #line 314 "./src/typechecker.am" if (code_string_equals(op, "??")) { #line 315 "./src/typechecker.am" if (String_EndsWith(left, "?")) { #line 316 "./src/typechecker.am" return String_Substring(left, 0LL, String_Length(left) - 1LL); } #line 318 "./src/typechecker.am" return left; } #line 321 "./src/typechecker.am" if ((code_string_equals(op, "..")) || (code_string_equals(op, "..."))) { return "range"; } #line 323 "./src/typechecker.am" if (code_string_equals(op, "|>")) { return right; } #line 325 "./src/typechecker.am" if ((((((code_string_equals(op, "+")) || (code_string_equals(op, "-"))) || (code_string_equals(op, "*"))) || (code_string_equals(op, "/"))) || (code_string_equals(op, "%"))) || (code_string_equals(op, "^"))) { #line 326 "./src/typechecker.am" if ((code_string_equals(left, "double")) || (code_string_equals(right, "double"))) { return "double"; } #line 327 "./src/typechecker.am" if ((code_string_equals(left, "float")) || (code_string_equals(right, "float"))) { return "float"; } #line 328 "./src/typechecker.am" if ((code_string_equals(left, "string")) || (code_string_equals(right, "string"))) { return "string"; } #line 329 "./src/typechecker.am" return left; } #line 331 "./src/typechecker.am" return "?"; } static code_string Amalgame_Compiler_TypeChecker_CollectionElementType(Amalgame_Compiler_TypeChecker* self, code_string typeKey) { #line 335 "./src/typechecker.am" if ((code_string_equals(typeKey, "?")) || (code_string_equals(typeKey, ""))) { return "?"; } #line 337 "./src/typechecker.am" if (String_StartsWith(typeKey, "List<") && String_EndsWith(typeKey, ">")) { #line 338 "./src/typechecker.am" code_string inner = String_Substring(typeKey, 5LL, String_Length(typeKey) - 6LL); #line 339 "./src/typechecker.am" return inner; } #line 342 "./src/typechecker.am" if (String_StartsWith(typeKey, "Set<") && String_EndsWith(typeKey, ">")) { #line 343 "./src/typechecker.am" code_string inner = String_Substring(typeKey, 4LL, String_Length(typeKey) - 5LL); #line 344 "./src/typechecker.am" return inner; } #line 347 "./src/typechecker.am" if (String_StartsWith(typeKey, "Map<") && String_EndsWith(typeKey, ">")) { #line 348 "./src/typechecker.am" code_string inner = String_Substring(typeKey, 4LL, String_Length(typeKey) - 5LL); #line 349 "./src/typechecker.am" i64 comma = String_IndexOf(inner, ","); #line 350 "./src/typechecker.am" if (comma >= 0LL) { #line 351 "./src/typechecker.am" code_string vt = String_Substring(inner, comma + 1LL, (String_Length(inner) - comma) - 1LL); #line 352 "./src/typechecker.am" return String_Trim(vt); } } #line 356 "./src/typechecker.am" if (String_EndsWith(typeKey, "[]")) { #line 357 "./src/typechecker.am" return String_Substring(typeKey, 0LL, String_Length(typeKey) - 2LL); } #line 359 "./src/typechecker.am" return "?"; } static code_bool Amalgame_Compiler_TypeChecker_SymbolFound(Amalgame_Compiler_TypeChecker* self, code_string name) { #line 368 "./src/typechecker.am" return Amalgame_Compiler_FullResolver_HasSymbol(self->Symbols, name); } static code_string Amalgame_Compiler_TypeChecker_SymbolTypeName(Amalgame_Compiler_TypeChecker* self, code_string name) { #line 372 "./src/typechecker.am" return Amalgame_Compiler_FullResolver_GetTypeName(self->Symbols, name); } static void Amalgame_Compiler_TypeChecker_Error(Amalgame_Compiler_TypeChecker* self, code_string msg, Amalgame_Compiler_AstNode* node) { #line 378 "./src/typechecker.am" code_string file = self->Filename; #line 379 "./src/typechecker.am" i64 line = 0LL; #line 380 "./src/typechecker.am" i64 col = 0LL; #line 381 "./src/typechecker.am" if (node != NULL) { #line 382 "./src/typechecker.am" line = node->Line; #line 383 "./src/typechecker.am" col = node->Column; } #line 385 "./src/typechecker.am" Amalgame_Compiler_TypeError* err = Amalgame_Compiler_TypeError_new(msg, file, line, col); #line 386 "./src/typechecker.am" err->Snippet = Amalgame_Compiler_SourceMap_GetLine(self->Sources, file, line); #line 387 "./src/typechecker.am" AmalgameList_add(self->Errors, (void*)(intptr_t)(err)); } static void Amalgame_Compiler_TypeChecker_CheckBool(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node, code_string context) { #line 391 "./src/typechecker.am" code_string t = Amalgame_Compiler_TypeChecker_GetType(self, node); #line 392 "./src/typechecker.am" if (!Amalgame_Compiler_TypeChecker_IsBool(self, t)) { #line 393 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat("'", context)), "' must be bool, got '")), t)), "'"), node); } } static code_string Amalgame_Compiler_TypeChecker_SymbolType(Amalgame_Compiler_TypeChecker* self, code_string name) { #line 400 "./src/typechecker.am" return Amalgame_Compiler_TypeChecker_SymbolTypeName(self, name); } static code_string Amalgame_Compiler_TypeChecker_MemberTypeOf(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* classDecl, code_string memberName) { #line 405 "./src/typechecker.am" if (classDecl == NULL) { return "?"; } #line 406 "./src/typechecker.am" Amalgame_Compiler_NodeKind k = classDecl->Kind; #line 408 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) { #line 409 "./src/typechecker.am" i64 members = AmalgameList_count(classDecl->Children); #line 410 "./src/typechecker.am" for (i64 i = 0LL; i < members; i++) { #line 411 "./src/typechecker.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(classDecl->Children, i); #line 412 "./src/typechecker.am" if (code_string_equals(m->Name, memberName)) { return classDecl->Name; } } #line 414 "./src/typechecker.am" return classDecl->Name; } #line 417 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { #line 418 "./src/typechecker.am" i64 members = AmalgameList_count(classDecl->Children); #line 419 "./src/typechecker.am" for (i64 i = 0LL; i < members; i++) { #line 420 "./src/typechecker.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(classDecl->Children, i); #line 421 "./src/typechecker.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 422 "./src/typechecker.am" if (code_string_equals(m->Name, memberName)) { #line 423 "./src/typechecker.am" if (mk == Amalgame_Compiler_NodeKind_VAR_DECL) { return m->Str; } #line 424 "./src/typechecker.am" if (mk == Amalgame_Compiler_NodeKind_METHOD_DECL) { return m->Str; } } } } #line 428 "./src/typechecker.am" return "?"; } static void Amalgame_Compiler_TypeChecker_CheckProgram(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* prog) { #line 438 "./src/typechecker.am" if (String_Length(prog->Str2) > 0LL) { #line 439 "./src/typechecker.am" self->Filename = prog->Str2; } #line 448 "./src/typechecker.am" self->ExprTypeMap = AmalgameMap_new(); #line 449 "./src/typechecker.am" self->LocalNames = AmalgameList_new(); #line 450 "./src/typechecker.am" self->LocalTypes = AmalgameList_new(); #line 451 "./src/typechecker.am" self->ScopeStarts = AmalgameList_new(); #line 452 "./src/typechecker.am" i64 count = AmalgameList_count(prog->Children); #line 453 "./src/typechecker.am" for (i64 i = 0LL; i < count; i++) { #line 454 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckDecl(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i)); } } static void Amalgame_Compiler_TypeChecker_CheckDecl(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* decl) { #line 459 "./src/typechecker.am" Amalgame_Compiler_NodeKind k = decl->Kind; #line 460 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { #line 461 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckClass(self, decl); } #line 463 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) { #line 465 "./src/typechecker.am" i64 methods = AmalgameList_count(decl->Children); #line 466 "./src/typechecker.am" for (i64 i = 0LL; i < methods; i++) { #line 467 "./src/typechecker.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(decl->Children, i); #line 468 "./src/typechecker.am" if (m->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 469 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckMethod(self, m); } } } } static void Amalgame_Compiler_TypeChecker_CheckClass(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* cls) { #line 478 "./src/typechecker.am" code_string prevClass = self->CurrentClass; #line 479 "./src/typechecker.am" self->CurrentClass = cls->Name; #line 480 "./src/typechecker.am" i64 members = AmalgameList_count(cls->Children); #line 482 "./src/typechecker.am" for (i64 i = 0LL; i < members; i++) { #line 483 "./src/typechecker.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, i); #line 484 "./src/typechecker.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 485 "./src/typechecker.am" if (mk == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 486 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckFieldDecl(self, m); } #line 488 "./src/typechecker.am" if (mk == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 489 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckMethod(self, m); } } #line 495 "./src/typechecker.am" if (!cls->Flag2 && (String_Length(cls->Str4) > 0LL)) { #line 496 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckImplementsContract(self, cls); } #line 498 "./src/typechecker.am" self->CurrentClass = prevClass; } static void Amalgame_Compiler_TypeChecker_CheckImplementsContract(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* cls) { #line 504 "./src/typechecker.am" AmalgameList* entries = Amalgame_Compiler_TypeChecker_SplitTopLevelCommas(self, cls->Str4); #line 505 "./src/typechecker.am" i64 nEntries = AmalgameList_count(entries); #line 506 "./src/typechecker.am" for (i64 ie = 0LL; ie < nEntries; ie++) { #line 507 "./src/typechecker.am" void* iref = (void*)AmalgameList_get(entries, ie); #line 508 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckOneInterface(self, cls, iref); } } static void Amalgame_Compiler_TypeChecker_CheckOneInterface(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* cls, code_string iref) { #line 513 "./src/typechecker.am" code_string ibase = iref; #line 515 "./src/typechecker.am" self->SubstParams = AmalgameList_new(); #line 516 "./src/typechecker.am" self->SubstArgs = AmalgameList_new(); #line 517 "./src/typechecker.am" i64 lt = String_IndexOf(iref, "<"); #line 518 "./src/typechecker.am" if (lt > 0LL) { #line 519 "./src/typechecker.am" ibase = String_Substring(iref, 0LL, lt); #line 520 "./src/typechecker.am" code_string inner = String_Substring(iref, lt + 1LL, (String_Length(iref) - lt) - 2LL); #line 521 "./src/typechecker.am" AmalgameList* parts = Amalgame_Compiler_TypeChecker_SplitTopLevelCommas(self, inner); #line 522 "./src/typechecker.am" i64 np = AmalgameList_count(parts); #line 523 "./src/typechecker.am" for (i64 ia = 0LL; ia < np; ia++) { AmalgameList_add(self->SubstArgs, (void*)(intptr_t)((code_string)AmalgameList_get(parts, ia))); } } #line 525 "./src/typechecker.am" Amalgame_Compiler_AstNode* iface = Amalgame_Compiler_TypeChecker_FindInterface(self, ibase); #line 526 "./src/typechecker.am" if (iface == NULL) { #line 527 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat("class '", cls->Name)), "' implements unknown interface '")), ibase)), "'"), cls); #line 528 "./src/typechecker.am" return; } #line 530 "./src/typechecker.am" if (String_Length(iface->Str3) > 0LL) { #line 531 "./src/typechecker.am" AmalgameList* pp = Amalgame_Compiler_TypeChecker_SplitTopLevelCommas(self, iface->Str3); #line 532 "./src/typechecker.am" i64 pn = AmalgameList_count(pp); #line 533 "./src/typechecker.am" for (i64 ip = 0LL; ip < pn; ip++) { AmalgameList_add(self->SubstParams, (void*)(intptr_t)((void*)AmalgameList_get(pp, ip))); } } #line 535 "./src/typechecker.am" if (AmalgameList_count(self->SubstParams) != AmalgameList_count(self->SubstArgs)) { #line 536 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("interface '", ibase)), "' expects ")), String_FromInt(AmalgameList_count(self->SubstParams)))), " type argument(s), got ")), String_FromInt(AmalgameList_count(self->SubstArgs))), cls); #line 537 "./src/typechecker.am" return; } #line 539 "./src/typechecker.am" i64 imethods = AmalgameList_count(iface->Children); #line 540 "./src/typechecker.am" for (i64 im = 0LL; im < imethods; im++) { #line 541 "./src/typechecker.am" Amalgame_Compiler_AstNode* imethod = (Amalgame_Compiler_AstNode*)AmalgameList_get(iface->Children, im); #line 542 "./src/typechecker.am" if (imethod->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 543 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckOneInterfaceMethod(self, cls, iref, imethod); } } } static void Amalgame_Compiler_TypeChecker_CheckOneInterfaceMethod(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* cls, code_string ifaceLabel, Amalgame_Compiler_AstNode* imethod) { #line 549 "./src/typechecker.am" i64 cmems = AmalgameList_count(cls->Children); #line 550 "./src/typechecker.am" Amalgame_Compiler_AstNode* found = NULL; #line 551 "./src/typechecker.am" for (i64 ic = 0LL; ic < cmems; ic++) { #line 552 "./src/typechecker.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, ic); #line 553 "./src/typechecker.am" if ((m->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) && (code_string_equals(m->Name, imethod->Name))) { #line 554 "./src/typechecker.am" found = m; } } #line 557 "./src/typechecker.am" if (found == NULL) { #line 558 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("class '", cls->Name)), "' does not implement interface '")), ifaceLabel)), "': missing method '")), imethod->Name)), "'"), cls); #line 559 "./src/typechecker.am" return; } #line 561 "./src/typechecker.am" Amalgame_Compiler_AstNode* cmethod = found; #line 562 "./src/typechecker.am" code_string expectedRet = Amalgame_Compiler_TypeChecker_SubstType(self, imethod->Str); #line 563 "./src/typechecker.am" if (!code_string_equals(cmethod->Str, expectedRet)) { #line 564 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("class '", cls->Name)), "' method '")), imethod->Name)), "': expected return type '")), expectedRet)), "' (from interface '")), ifaceLabel)), "'), got '")), cmethod->Str)), "'"), cmethod); #line 565 "./src/typechecker.am" return; } #line 567 "./src/typechecker.am" i64 iN = AmalgameList_count(imethod->Params); #line 568 "./src/typechecker.am" i64 cN = AmalgameList_count(cmethod->Params); #line 569 "./src/typechecker.am" if (iN != cN) { #line 570 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("class '", cls->Name)), "' method '")), imethod->Name)), "': expected ")), String_FromInt(iN))), " param(s), got ")), String_FromInt(cN)), cmethod); #line 571 "./src/typechecker.am" return; } #line 573 "./src/typechecker.am" for (i64 ip = 0LL; ip < iN; ip++) { #line 574 "./src/typechecker.am" Amalgame_Compiler_AstNode* ipar = (Amalgame_Compiler_AstNode*)AmalgameList_get(imethod->Params, ip); #line 575 "./src/typechecker.am" Amalgame_Compiler_AstNode* cpar = (Amalgame_Compiler_AstNode*)AmalgameList_get(cmethod->Params, ip); #line 576 "./src/typechecker.am" code_string expectedType = Amalgame_Compiler_TypeChecker_SubstType(self, ipar->Str); #line 577 "./src/typechecker.am" if (!code_string_equals(cpar->Str, expectedType)) { #line 578 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("class '", cls->Name)), "' method '")), imethod->Name)), "' param '")), cpar->Name)), "': expected type '")), expectedType)), "' (from interface '")), ifaceLabel)), "'), got '")), cpar->Str)), "'"), cpar); #line 579 "./src/typechecker.am" return; } } } static Amalgame_Compiler_AstNode* Amalgame_Compiler_TypeChecker_FindInterface(Amalgame_Compiler_TypeChecker* self, code_string name) { #line 589 "./src/typechecker.am" i64 pn = Amalgame_Compiler_FullResolver_ProgramCount(self->Symbols); #line 590 "./src/typechecker.am" for (i64 ip = 0LL; ip < pn; ip++) { #line 591 "./src/typechecker.am" void* prog = Amalgame_Compiler_FullResolver_ProgramAt(self->Symbols, ip); #line 592 "./src/typechecker.am" Amalgame_Compiler_AstNode* hit = Amalgame_Compiler_TypeChecker_FindInterfaceInProgram(self, prog, name); #line 593 "./src/typechecker.am" if (hit != NULL) { return hit; } } #line 595 "./src/typechecker.am" return NULL; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_TypeChecker_FindInterfaceInProgram(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* prog, code_string name) { #line 599 "./src/typechecker.am" i64 cn = AmalgameList_count(prog->Children); #line 600 "./src/typechecker.am" for (i64 ic = 0LL; ic < cn; ic++) { #line 601 "./src/typechecker.am" Amalgame_Compiler_AstNode* d = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, ic); #line 602 "./src/typechecker.am" if (((d->Kind == Amalgame_Compiler_NodeKind_CLASS_DECL) && d->Flag2) && (code_string_equals(d->Name, name))) { #line 603 "./src/typechecker.am" return d; } } #line 606 "./src/typechecker.am" return NULL; } static AmalgameList* Amalgame_Compiler_TypeChecker_SplitTopLevelCommas(Amalgame_Compiler_TypeChecker* self, code_string s) { #line 612 "./src/typechecker.am" AmalgameList* result = AmalgameList_new(); #line 613 "./src/typechecker.am" i64 len = String_Length(s); #line 614 "./src/typechecker.am" if (len == 0LL) { return result; } #line 615 "./src/typechecker.am" i64 depth = 0LL; #line 616 "./src/typechecker.am" i64 start = 0LL; #line 617 "./src/typechecker.am" for (i64 i = 0LL; i < len; i++) { #line 618 "./src/typechecker.am" code_string c = String_CharAt1(s, i); #line 619 "./src/typechecker.am" if (code_string_equals(c, "<")) { #line 620 "./src/typechecker.am" depth = (depth + 1LL); } else if (code_string_equals(c, ">")) { #line 622 "./src/typechecker.am" depth = (depth - 1LL); } else if ((code_string_equals(c, ",")) && (depth == 0LL)) { #line 624 "./src/typechecker.am" code_string part = String_Trim(String_Substring(s, start, i - start)); #line 625 "./src/typechecker.am" if (String_Length(part) > 0LL) { AmalgameList_add(result, (void*)(intptr_t)(part)); } #line 626 "./src/typechecker.am" start = (i + 1LL); } } #line 629 "./src/typechecker.am" code_string last = String_Trim(String_Substring(s, start, len - start)); #line 630 "./src/typechecker.am" if (String_Length(last) > 0LL) { AmalgameList_add(result, (void*)(intptr_t)(last)); } #line 631 "./src/typechecker.am" return result; } static code_string Amalgame_Compiler_TypeChecker_SubstType(Amalgame_Compiler_TypeChecker* self, code_string t) { #line 639 "./src/typechecker.am" if (String_Length(t) == 0LL) { return t; } #line 640 "./src/typechecker.am" code_bool nullable = 0; #line 641 "./src/typechecker.am" code_string core = t; #line 642 "./src/typechecker.am" if (String_EndsWith(t, "?")) { #line 643 "./src/typechecker.am" nullable = 1; #line 644 "./src/typechecker.am" core = String_Substring(t, 0LL, String_Length(t) - 1LL); } #line 646 "./src/typechecker.am" i64 lt = String_IndexOf(core, "<"); #line 647 "./src/typechecker.am" if (lt < 0LL) { #line 648 "./src/typechecker.am" code_string resolved = Amalgame_Compiler_TypeChecker_LookupParam(self, core); #line 649 "./src/typechecker.am" if (nullable) { return code_string_concat(resolved, "?"); } #line 650 "./src/typechecker.am" return resolved; } #line 652 "./src/typechecker.am" code_string base = String_Substring(core, 0LL, lt); #line 653 "./src/typechecker.am" code_string inner = String_Substring(core, lt + 1LL, (String_Length(core) - lt) - 2LL); #line 654 "./src/typechecker.am" AmalgameList* parts = Amalgame_Compiler_TypeChecker_SplitTopLevelCommas(self, inner); #line 655 "./src/typechecker.am" code_string newInner = ""; #line 656 "./src/typechecker.am" i64 n = AmalgameList_count(parts); #line 657 "./src/typechecker.am" for (i64 i = 0LL; i < n; i++) { #line 658 "./src/typechecker.am" if (i > 0LL) { newInner = (code_string_concat(newInner, ",")); } #line 659 "./src/typechecker.am" newInner = (code_string_concat(newInner, Amalgame_Compiler_TypeChecker_SubstType(self, (code_string)AmalgameList_get(parts, i)))); } #line 661 "./src/typechecker.am" code_string result = code_string_concat((code_string_concat((code_string_concat(base, "<")), newInner)), ">"); #line 662 "./src/typechecker.am" if (nullable) { return code_string_concat(result, "?"); } #line 663 "./src/typechecker.am" return result; } static code_string Amalgame_Compiler_TypeChecker_LookupParam(Amalgame_Compiler_TypeChecker* self, code_string t) { #line 667 "./src/typechecker.am" i64 n = AmalgameList_count(self->SubstParams); #line 668 "./src/typechecker.am" for (i64 i = 0LL; i < n; i++) { #line 669 "./src/typechecker.am" if (code_string_equals((code_string)AmalgameList_get(self->SubstParams, i), t)) { return (code_string)AmalgameList_get(self->SubstArgs, i); } } #line 671 "./src/typechecker.am" return t; } static void Amalgame_Compiler_TypeChecker_CheckFieldDecl(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* field) { #line 675 "./src/typechecker.am" code_string fieldType = field->Str; #line 676 "./src/typechecker.am" if (field->Left != NULL) { #line 677 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, field->Left); #line 678 "./src/typechecker.am" code_string initType = Amalgame_Compiler_TypeChecker_GetType(self, field->Left); #line 679 "./src/typechecker.am" if (!Amalgame_Compiler_TypeChecker_IsAssignable(self, fieldType, initType)) { #line 680 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("Field '", field->Name)), "' declared as '")), fieldType)), "' but initialised with '")), initType)), "'"), field->Left); } } } static void Amalgame_Compiler_TypeChecker_CheckMethod(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* method) { #line 688 "./src/typechecker.am" code_string retType = method->Str; #line 689 "./src/typechecker.am" code_string prevReturn = self->CurrentReturn; #line 690 "./src/typechecker.am" self->CurrentReturn = retType; #line 692 "./src/typechecker.am" self->PersistLocals = AmalgameList_new(); #line 693 "./src/typechecker.am" self->ArenaLocals = AmalgameList_new(); #line 694 "./src/typechecker.am" self->PersistDepth = 0LL; #line 696 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_PushScope(self); #line 699 "./src/typechecker.am" i64 params = AmalgameList_count(method->Params); #line 700 "./src/typechecker.am" for (i64 i = 0LL; i < params; i++) { #line 701 "./src/typechecker.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 702 "./src/typechecker.am" if (p->Left != NULL) { #line 703 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, p->Left); #line 704 "./src/typechecker.am" code_string defType = Amalgame_Compiler_TypeChecker_GetType(self, p->Left); #line 705 "./src/typechecker.am" if (!Amalgame_Compiler_TypeChecker_IsAssignable(self, p->Str, defType)) { #line 706 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("Parameter '", p->Name)), "' is '")), p->Str)), "' but default is '")), defType)), "'"), p->Left); } } #line 709 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_DeclareLocal(self, p->Name, p->Str); } #line 713 "./src/typechecker.am" if (method->Body != NULL) { #line 714 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckBlock(self, method->Body); } #line 723 "./src/typechecker.am" if ((self->Embedded && (method->Body != NULL)) && Amalgame_Compiler_TypeChecker_HasDecorator(self, method->Str2, "isr")) { #line 725 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_IsrCheckNoAlloc(self, method->Body); } #line 728 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_PopScope(self); #line 729 "./src/typechecker.am" self->CurrentReturn = prevReturn; } static code_bool Amalgame_Compiler_TypeChecker_HasDecorator(Amalgame_Compiler_TypeChecker* self, code_string list, code_string name) { #line 734 "./src/typechecker.am" if (String_Length(list) == 0LL) { return 0; } #line 735 "./src/typechecker.am" AmalgameList* parts = String_Split(list, ","); #line 736 "./src/typechecker.am" i64 n = AmalgameList_count(parts); #line 737 "./src/typechecker.am" for (i64 i = 0LL; i < n; i++) { #line 738 "./src/typechecker.am" if (code_string_equals((code_string)AmalgameList_get(parts, i), name)) { return 1; } } #line 740 "./src/typechecker.am" return 0; } static void Amalgame_Compiler_TypeChecker_IsrCheckNoAlloc(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* node) { #line 747 "./src/typechecker.am" if (node == NULL) { return; } #line 748 "./src/typechecker.am" Amalgame_Compiler_NodeKind k = node->Kind; #line 749 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 750 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, "@isr handler must be allocation-free: 'new' allocates on the arena (keep ISR state persistent/static)", node); } #line 752 "./src/typechecker.am" if ((k == Amalgame_Compiler_NodeKind_LIST_LITERAL) || (k == Amalgame_Compiler_NodeKind_LIST_COMP)) { #line 753 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, "@isr handler must be allocation-free: list literal allocates", node); } #line 755 "./src/typechecker.am" if ((k == Amalgame_Compiler_NodeKind_BINARY) && (code_string_equals(Amalgame_Compiler_TypeChecker_GetType(self, node), "code_string"))) { #line 756 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, "@isr handler must be allocation-free: string concatenation allocates", node); } #line 758 "./src/typechecker.am" if (node->Left != NULL) { Amalgame_Compiler_TypeChecker_IsrCheckNoAlloc(self, node->Left); } #line 759 "./src/typechecker.am" if (node->Right != NULL) { Amalgame_Compiler_TypeChecker_IsrCheckNoAlloc(self, node->Right); } #line 760 "./src/typechecker.am" if (node->Cond != NULL) { Amalgame_Compiler_TypeChecker_IsrCheckNoAlloc(self, node->Cond); } #line 761 "./src/typechecker.am" if (node->Body != NULL) { Amalgame_Compiler_TypeChecker_IsrCheckNoAlloc(self, node->Body); } #line 762 "./src/typechecker.am" if (node->Else != NULL) { Amalgame_Compiler_TypeChecker_IsrCheckNoAlloc(self, node->Else); } #line 763 "./src/typechecker.am" i64 na = AmalgameList_count(node->Args); #line 764 "./src/typechecker.am" for (i64 ai = 0LL; ai < na; ai++) { Amalgame_Compiler_TypeChecker_IsrCheckNoAlloc(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(node->Args, ai)); } #line 765 "./src/typechecker.am" i64 nc = AmalgameList_count(node->Children); #line 766 "./src/typechecker.am" for (i64 ci = 0LL; ci < nc; ci++) { Amalgame_Compiler_TypeChecker_IsrCheckNoAlloc(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(node->Children, ci)); } } static code_bool Amalgame_Compiler_TypeChecker_NameIn(Amalgame_Compiler_TypeChecker* self, AmalgameList* xs, code_string n) { #line 776 "./src/typechecker.am" i64 c = AmalgameList_count(xs); #line 777 "./src/typechecker.am" for (i64 i = 0LL; i < c; i++) { if (code_string_equals((code_string)AmalgameList_get(xs, i), n)) { return 1; } } #line 778 "./src/typechecker.am" return 0; } static code_bool Amalgame_Compiler_TypeChecker_IsArenaOrigin(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* e) { #line 786 "./src/typechecker.am" if (e == NULL) { return 0; } #line 787 "./src/typechecker.am" Amalgame_Compiler_NodeKind k = e->Kind; #line 788 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_NEW_EXPR) { return 1; } #line 789 "./src/typechecker.am" if ((k == Amalgame_Compiler_NodeKind_LIST_LITERAL) || (k == Amalgame_Compiler_NodeKind_LIST_COMP)) { return 1; } #line 790 "./src/typechecker.am" if ((k == Amalgame_Compiler_NodeKind_BINARY) && (code_string_equals(Amalgame_Compiler_TypeChecker_GetType(self, e), "code_string"))) { return 1; } #line 791 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { return Amalgame_Compiler_TypeChecker_NameIn(self, self->ArenaLocals, e->Name); } #line 792 "./src/typechecker.am" return 0; } static code_bool Amalgame_Compiler_TypeChecker_IsPersistOrigin(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* e) { #line 798 "./src/typechecker.am" if (e == NULL) { return 0; } #line 799 "./src/typechecker.am" Amalgame_Compiler_NodeKind k = e->Kind; #line 800 "./src/typechecker.am" if ((((k == Amalgame_Compiler_NodeKind_CALL) && (e->Left != NULL)) && (e->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) && (code_string_equals(e->Left->Name, "persist"))) { #line 802 "./src/typechecker.am" return 1; } #line 804 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { return Amalgame_Compiler_TypeChecker_NameIn(self, self->PersistLocals, e->Name); } #line 805 "./src/typechecker.am" return 0; } static void Amalgame_Compiler_TypeChecker_TrackLocalOrigin(Amalgame_Compiler_TypeChecker* self, code_string name, Amalgame_Compiler_AstNode* init) { #line 810 "./src/typechecker.am" if (!self->Embedded || (init == NULL)) { return; } #line 811 "./src/typechecker.am" if (Amalgame_Compiler_TypeChecker_IsPersistOrigin(self, init)) { AmalgameList_add(self->PersistLocals, (void*)(intptr_t)(name)); } else if ((self->PersistDepth == 0LL) && Amalgame_Compiler_TypeChecker_IsArenaOrigin(self, init)) { #line 812 "./src/typechecker.am" AmalgameList_add(self->ArenaLocals, (void*)(intptr_t)(name)); } } static void Amalgame_Compiler_TypeChecker_CheckBlock(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* block) { #line 818 "./src/typechecker.am" i64 stmts = AmalgameList_count(block->Children); #line 819 "./src/typechecker.am" for (i64 i = 0LL; i < stmts; i++) { #line 820 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckStmt(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(block->Children, i)); } } static void Amalgame_Compiler_TypeChecker_CheckStmt(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt) { #line 825 "./src/typechecker.am" Amalgame_Compiler_NodeKind k = stmt->Kind; #line 826 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 827 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckVarDecl(self, stmt); #line 828 "./src/typechecker.am" return; } #line 830 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_RETURN_STMT) { #line 831 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckReturn(self, stmt); #line 832 "./src/typechecker.am" return; } #line 834 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_IF_STMT) { #line 835 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckIf(self, stmt); #line 836 "./src/typechecker.am" return; } #line 838 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_WHILE_STMT) { #line 839 "./src/typechecker.am" if (stmt->Cond != NULL) { #line 840 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, stmt->Cond); #line 841 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckBool(self, stmt->Cond, "while condition"); } #line 843 "./src/typechecker.am" if (stmt->Body != NULL) { Amalgame_Compiler_TypeChecker_CheckBlock(self, stmt->Body); } #line 844 "./src/typechecker.am" return; } #line 846 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_FOR_IN_STMT) { #line 847 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckForIn(self, stmt); #line 848 "./src/typechecker.am" return; } #line 850 "./src/typechecker.am" if ((k == Amalgame_Compiler_NodeKind_BREAK_STMT) || (k == Amalgame_Compiler_NodeKind_CONTINUE_STMT)) { return; } #line 851 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_INLINE_C) { #line 855 "./src/typechecker.am" if (self->Embedded) { #line 856 "./src/typechecker.am" if (String_Contains(stmt->Str, "amc_persist_begin")) { self->PersistDepth = (self->PersistDepth + 1LL); } #line 857 "./src/typechecker.am" if (String_Contains(stmt->Str, "amc_persist_end")) { self->PersistDepth = (self->PersistDepth - 1LL); } } #line 859 "./src/typechecker.am" return; } #line 861 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_TRY_STMT) { #line 862 "./src/typechecker.am" if (stmt->Body != NULL) { Amalgame_Compiler_TypeChecker_CheckBlock(self, stmt->Body); } #line 863 "./src/typechecker.am" if (stmt->Else != NULL) { #line 864 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_PushScope(self); #line 865 "./src/typechecker.am" if (String_Length(stmt->Name) > 0LL) { #line 866 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_DeclareLocal(self, stmt->Name, "void*"); } #line 868 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckBlock(self, stmt->Else); #line 869 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_PopScope(self); } #line 871 "./src/typechecker.am" if (stmt->Cond != NULL) { Amalgame_Compiler_TypeChecker_CheckBlock(self, stmt->Cond); } #line 872 "./src/typechecker.am" return; } #line 874 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_THROW_STMT) { #line 875 "./src/typechecker.am" if (stmt->Left != NULL) { Amalgame_Compiler_TypeChecker_CheckExpr(self, stmt->Left); } #line 876 "./src/typechecker.am" return; } #line 879 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_ASSIGN) { #line 880 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckAssign(self, stmt); #line 881 "./src/typechecker.am" return; } #line 884 "./src/typechecker.am" if (code_string_equals(stmt->Name, "__match__")) { #line 885 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckMatch(self, stmt); #line 886 "./src/typechecker.am" return; } #line 889 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, stmt); } static void Amalgame_Compiler_TypeChecker_CheckVarDecl(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt) { #line 893 "./src/typechecker.am" code_string declaredType = stmt->Str; #line 894 "./src/typechecker.am" code_string inferredType = "?"; #line 895 "./src/typechecker.am" if (stmt->Left != NULL) { #line 896 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, stmt->Left); #line 897 "./src/typechecker.am" inferredType = Amalgame_Compiler_TypeChecker_GetType(self, stmt->Left); } #line 903 "./src/typechecker.am" if (code_string_equals(declaredType, "__tuple_destructure__")) { #line 904 "./src/typechecker.am" return; } #line 906 "./src/typechecker.am" code_string finalType = (String_Length(declaredType) > 0LL ? declaredType : inferredType); #line 907 "./src/typechecker.am" if ((String_Length(declaredType) > 0LL) && (!code_string_equals(inferredType, "?"))) { #line 908 "./src/typechecker.am" if (!Amalgame_Compiler_TypeChecker_IsAssignable(self, declaredType, inferredType)) { #line 909 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("Cannot assign '", inferredType)), "' to '")), stmt->Name)), "' of type '")), declaredType)), "'"), stmt); } } #line 913 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_DeclareLocal(self, stmt->Name, finalType); #line 916 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_TrackLocalOrigin(self, stmt->Name, stmt->Left); } static void Amalgame_Compiler_TypeChecker_CheckReturn(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt) { #line 923 "./src/typechecker.am" code_bool isBare = stmt->Left == NULL; #line 924 "./src/typechecker.am" if (!isBare && (stmt->Left != NULL)) { #line 925 "./src/typechecker.am" if ((stmt->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) && (code_string_equals(stmt->Left->Name, "_unknown_"))) { #line 926 "./src/typechecker.am" isBare = 1; } } #line 929 "./src/typechecker.am" if (isBare) { #line 931 "./src/typechecker.am" if ((!code_string_equals(self->CurrentReturn, "void")) && (!code_string_equals(self->CurrentReturn, "?"))) { #line 932 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat("Empty return in method expecting '", self->CurrentReturn)), "'"), stmt); } #line 934 "./src/typechecker.am" return; } #line 936 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, stmt->Left); #line 937 "./src/typechecker.am" code_string valType = Amalgame_Compiler_TypeChecker_GetType(self, stmt->Left); #line 938 "./src/typechecker.am" if (code_string_equals(self->CurrentReturn, "void")) { #line 939 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, "Cannot return a value from a void method", stmt); } else if (!Amalgame_Compiler_TypeChecker_IsAssignable(self, self->CurrentReturn, valType)) { #line 941 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat("Return type mismatch: expected '", self->CurrentReturn)), "', got '")), valType)), "'"), stmt); } } static void Amalgame_Compiler_TypeChecker_CheckIf(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt) { #line 946 "./src/typechecker.am" if (stmt->Cond != NULL) { #line 947 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, stmt->Cond); #line 948 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckBool(self, stmt->Cond, "if condition"); } #line 950 "./src/typechecker.am" if (stmt->Body != NULL) { Amalgame_Compiler_TypeChecker_CheckBlock(self, stmt->Body); } #line 951 "./src/typechecker.am" if (stmt->Else != NULL) { #line 952 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckElseBranch(self, stmt->Else); } } static void Amalgame_Compiler_TypeChecker_CheckElseBranch(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* branch) { #line 957 "./src/typechecker.am" if (branch == NULL) { return; } #line 958 "./src/typechecker.am" Amalgame_Compiler_NodeKind bk = branch->Kind; #line 959 "./src/typechecker.am" if (bk == Amalgame_Compiler_NodeKind_IF_STMT) { #line 960 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckIf(self, branch); } else { #line 962 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckBlock(self, branch); } } static void Amalgame_Compiler_TypeChecker_CheckForIn(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt) { #line 969 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_PushScope(self); #line 970 "./src/typechecker.am" if (stmt->Left != NULL) { #line 971 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, stmt->Left); #line 972 "./src/typechecker.am" code_string colType = Amalgame_Compiler_TypeChecker_GetType(self, stmt->Left); #line 973 "./src/typechecker.am" code_string elemType = Amalgame_Compiler_TypeChecker_CollectionElementType(self, colType); #line 974 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_DeclareLocal(self, stmt->Name, elemType); } #line 976 "./src/typechecker.am" if (stmt->Body != NULL) { Amalgame_Compiler_TypeChecker_CheckBlock(self, stmt->Body); } #line 977 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_PopScope(self); } static void Amalgame_Compiler_TypeChecker_CheckAssign(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt) { #line 981 "./src/typechecker.am" if (stmt->Left != NULL) { Amalgame_Compiler_TypeChecker_CheckExpr(self, stmt->Left); } #line 982 "./src/typechecker.am" if (stmt->Right != NULL) { Amalgame_Compiler_TypeChecker_CheckExpr(self, stmt->Right); } #line 983 "./src/typechecker.am" if ((stmt->Left != NULL) && (stmt->Right != NULL)) { #line 984 "./src/typechecker.am" code_string targetType = Amalgame_Compiler_TypeChecker_GetType(self, stmt->Left); #line 985 "./src/typechecker.am" code_string valueType = Amalgame_Compiler_TypeChecker_GetType(self, stmt->Right); #line 986 "./src/typechecker.am" if (!Amalgame_Compiler_TypeChecker_IsAssignable(self, targetType, valueType)) { #line 987 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat("Cannot assign '", valueType)), "' to '")), targetType)), "'"), stmt); } #line 992 "./src/typechecker.am" if ((((((self->Embedded && (self->PersistDepth == 0LL)) && (stmt->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER)) && (stmt->Left->Left != NULL)) && Amalgame_Compiler_TypeChecker_IsPersistOrigin(self, stmt->Left->Left)) && Amalgame_Compiler_TypeChecker_IsArenaOrigin(self, stmt->Right)) && !Amalgame_Compiler_TypeChecker_IsPersistOrigin(self, stmt->Right)) { #line 996 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, "arena value escapes into persistent state (it dies at the next loop tick) — wrap it with persist(...)", stmt); } } } static void Amalgame_Compiler_TypeChecker_CheckMatch(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* stmt) { #line 1003 "./src/typechecker.am" if (stmt->Left != NULL) { #line 1004 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, stmt->Left); } #line 1006 "./src/typechecker.am" i64 armCount = AmalgameList_count(stmt->Children); #line 1007 "./src/typechecker.am" for (i64 i = 0LL; i < armCount; i++) { #line 1008 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckMatchArm(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(stmt->Children, i)); } } static void Amalgame_Compiler_TypeChecker_CheckMatchArm(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* arm) { #line 1015 "./src/typechecker.am" if (arm == NULL) { return; } #line 1016 "./src/typechecker.am" Amalgame_Compiler_AstNode* body = arm->Right; #line 1017 "./src/typechecker.am" if (body == NULL) { return; } #line 1018 "./src/typechecker.am" Amalgame_Compiler_NodeKind bk = body->Kind; #line 1019 "./src/typechecker.am" if (bk == Amalgame_Compiler_NodeKind_BLOCK) { #line 1020 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckBlock(self, body); } else { #line 1022 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckStmt(self, body); } } static void Amalgame_Compiler_TypeChecker_CheckExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr) { #line 1027 "./src/typechecker.am" if (expr == NULL) { return; } #line 1028 "./src/typechecker.am" Amalgame_Compiler_NodeKind k = expr->Kind; #line 1030 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_INT) { #line 1031 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, "int"); #line 1032 "./src/typechecker.am" return; } #line 1034 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_FLOAT) { #line 1035 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, "float"); #line 1036 "./src/typechecker.am" return; } #line 1038 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_STRING) { #line 1039 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, "string"); #line 1040 "./src/typechecker.am" return; } #line 1042 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_BOOL) { #line 1043 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, "bool"); #line 1044 "./src/typechecker.am" return; } #line 1046 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_LITERAL_NULL) { #line 1047 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, "null"); #line 1048 "./src/typechecker.am" return; } #line 1050 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_THIS_EXPR) { #line 1051 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, self->CurrentClass); #line 1052 "./src/typechecker.am" return; } #line 1054 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 1056 "./src/typechecker.am" code_string t = Amalgame_Compiler_TypeChecker_LookupLocal(self, expr->Name); #line 1057 "./src/typechecker.am" if (String_Length(t) == 0LL) { #line 1058 "./src/typechecker.am" t = Amalgame_Compiler_TypeChecker_SymbolTypeName(self, expr->Name); } #line 1060 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, t); #line 1061 "./src/typechecker.am" return; } #line 1063 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_BINARY) { #line 1064 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckBinaryExpr(self, expr); #line 1065 "./src/typechecker.am" return; } #line 1067 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_UNARY) { #line 1068 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckUnaryExpr(self, expr); #line 1069 "./src/typechecker.am" return; } #line 1071 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_MEMBER) { #line 1072 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckMemberExpr(self, expr); #line 1073 "./src/typechecker.am" return; } #line 1075 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_CALL) { #line 1076 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckCallExpr(self, expr); #line 1077 "./src/typechecker.am" return; } #line 1079 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 1080 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckNewExpr(self, expr); #line 1081 "./src/typechecker.am" return; } #line 1083 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_INDEX_EXPR) { #line 1084 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckIndexExpr(self, expr); #line 1085 "./src/typechecker.am" return; } #line 1087 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_ASSIGN) { #line 1088 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckAssign(self, expr); #line 1089 "./src/typechecker.am" return; } #line 1091 "./src/typechecker.am" if (k == Amalgame_Compiler_NodeKind_IF_STMT) { #line 1093 "./src/typechecker.am" if (expr->Cond != NULL) { #line 1094 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, expr->Cond); #line 1095 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckBool(self, expr->Cond, "if condition"); } #line 1097 "./src/typechecker.am" code_string thenType = Amalgame_Compiler_TypeChecker_CheckIfBranch(self, expr->Body); #line 1098 "./src/typechecker.am" code_string elseType = Amalgame_Compiler_TypeChecker_CheckIfBranch(self, expr->Else); #line 1099 "./src/typechecker.am" code_string ifType = (!code_string_equals(thenType, "?") ? thenType : elseType); #line 1100 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, ifType); #line 1101 "./src/typechecker.am" return; } #line 1104 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, "?"); } static code_string Amalgame_Compiler_TypeChecker_CheckIfBranch(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* block) { #line 1110 "./src/typechecker.am" if (block == NULL) { return "?"; } #line 1111 "./src/typechecker.am" if (block->Kind == Amalgame_Compiler_NodeKind_BLOCK) { #line 1112 "./src/typechecker.am" AmalgameList* kids = block->Children; #line 1113 "./src/typechecker.am" if (AmalgameList_count(kids) > 0LL) { #line 1114 "./src/typechecker.am" Amalgame_Compiler_AstNode* first = (Amalgame_Compiler_AstNode*)AmalgameList_get(kids, 0LL); #line 1115 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, first); #line 1116 "./src/typechecker.am" return Amalgame_Compiler_TypeChecker_GetType(self, first); } #line 1118 "./src/typechecker.am" return "?"; } #line 1120 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, block); #line 1121 "./src/typechecker.am" return Amalgame_Compiler_TypeChecker_GetType(self, block); } static void Amalgame_Compiler_TypeChecker_CheckBinaryExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr) { #line 1125 "./src/typechecker.am" code_string op = expr->Str; #line 1126 "./src/typechecker.am" if (expr->Left != NULL) { Amalgame_Compiler_TypeChecker_CheckExpr(self, expr->Left); } #line 1127 "./src/typechecker.am" if (expr->Right != NULL) { Amalgame_Compiler_TypeChecker_CheckExpr(self, expr->Right); } #line 1128 "./src/typechecker.am" code_string lt = (expr->Left != NULL ? Amalgame_Compiler_TypeChecker_GetType(self, expr->Left) : "?"); #line 1129 "./src/typechecker.am" code_string rt = (expr->Right != NULL ? Amalgame_Compiler_TypeChecker_GetType(self, expr->Right) : "?"); #line 1134 "./src/typechecker.am" if ((((((((self->Embedded && (self->PersistDepth == 0LL)) && (code_string_equals(op, "="))) && (expr->Left != NULL)) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER)) && (expr->Left->Left != NULL)) && Amalgame_Compiler_TypeChecker_IsPersistOrigin(self, expr->Left->Left)) && Amalgame_Compiler_TypeChecker_IsArenaOrigin(self, expr->Right)) && !Amalgame_Compiler_TypeChecker_IsPersistOrigin(self, expr->Right)) { #line 1138 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, "arena value escapes into persistent state (it dies at the next loop tick) — wrap it with persist(...)", expr); } #line 1142 "./src/typechecker.am" if ((code_string_equals(op, "&&")) || (code_string_equals(op, "||"))) { #line 1143 "./src/typechecker.am" if (!Amalgame_Compiler_TypeChecker_IsBool(self, lt)) { #line 1144 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat("Left operand of '", op)), "' must be bool, got '")), lt)), "'"), expr->Left); } #line 1146 "./src/typechecker.am" if (!Amalgame_Compiler_TypeChecker_IsBool(self, rt)) { #line 1147 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat("Right operand of '", op)), "' must be bool, got '")), rt)), "'"), expr->Right); } } #line 1151 "./src/typechecker.am" if (((((code_string_equals(op, "-")) || (code_string_equals(op, "*"))) || (code_string_equals(op, "/"))) || (code_string_equals(op, "%"))) || (code_string_equals(op, "^"))) { #line 1152 "./src/typechecker.am" if (!Amalgame_Compiler_TypeChecker_IsNumeric(self, lt) && (!code_string_equals(lt, "?"))) { #line 1153 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat("Operator '", op)), "' requires numeric operands, got '")), lt)), "'"), expr->Left); } #line 1155 "./src/typechecker.am" if (!Amalgame_Compiler_TypeChecker_IsNumeric(self, rt) && (!code_string_equals(rt, "?"))) { #line 1156 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat("Operator '", op)), "' requires numeric operands, got '")), rt)), "'"), expr->Right); } } #line 1160 "./src/typechecker.am" if (code_string_equals(op, "??")) { #line 1161 "./src/typechecker.am" if (!Amalgame_Compiler_TypeChecker_IsNullable(self, lt) && (!code_string_equals(lt, "?"))) { #line 1162 "./src/typechecker.am" code_string qqOp = "?"; #line 1163 "./src/typechecker.am" code_string qqOp2 = "?"; #line 1164 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("Left operand of '", qqOp)), qqOp2)), "' must be nullable, got '")), lt)), "'"), expr->Left); } } #line 1167 "./src/typechecker.am" code_string result = Amalgame_Compiler_TypeChecker_BinaryResultType(self, op, lt, rt); #line 1168 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, result); } static void Amalgame_Compiler_TypeChecker_CheckUnaryExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr) { #line 1172 "./src/typechecker.am" code_string op = expr->Str; #line 1173 "./src/typechecker.am" if (expr->Left != NULL) { Amalgame_Compiler_TypeChecker_CheckExpr(self, expr->Left); } #line 1174 "./src/typechecker.am" code_string ot = (expr->Left != NULL ? Amalgame_Compiler_TypeChecker_GetType(self, expr->Left) : "?"); #line 1175 "./src/typechecker.am" if (code_string_equals(op, "!")) { #line 1176 "./src/typechecker.am" if (!Amalgame_Compiler_TypeChecker_IsBool(self, ot)) { #line 1177 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat("Operator '!' requires bool, got '", ot)), "'"), expr->Left); } #line 1179 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, "bool"); #line 1180 "./src/typechecker.am" return; } #line 1182 "./src/typechecker.am" if (code_string_equals(op, "-")) { #line 1183 "./src/typechecker.am" if (!Amalgame_Compiler_TypeChecker_IsNumeric(self, ot) && (!code_string_equals(ot, "?"))) { #line 1184 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, code_string_concat((code_string_concat("Unary '-' requires numeric, got '", ot)), "'"), expr->Left); } #line 1186 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, ot); #line 1187 "./src/typechecker.am" return; } #line 1189 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, ot); } static void Amalgame_Compiler_TypeChecker_CheckMemberExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr) { #line 1194 "./src/typechecker.am" if (expr->Left != NULL) { Amalgame_Compiler_TypeChecker_CheckExpr(self, expr->Left); } #line 1195 "./src/typechecker.am" code_string targetType = (expr->Left != NULL ? Amalgame_Compiler_TypeChecker_GetType(self, expr->Left) : "?"); #line 1196 "./src/typechecker.am" code_string baseType = targetType; #line 1198 "./src/typechecker.am" if (String_EndsWith(baseType, "?")) { #line 1199 "./src/typechecker.am" baseType = String_Substring(baseType, 0LL, String_Length(baseType) - 1LL); } #line 1202 "./src/typechecker.am" if (String_EndsWith(baseType, "*")) { #line 1203 "./src/typechecker.am" baseType = String_Substring(baseType, 0LL, String_Length(baseType) - 1LL); } #line 1205 "./src/typechecker.am" code_string memberType = "?"; #line 1206 "./src/typechecker.am" if ((String_Length(baseType) > 0LL) && (!code_string_equals(baseType, "?"))) { #line 1207 "./src/typechecker.am" memberType = Amalgame_Compiler_FullResolver_GetMemberType(self->Symbols, baseType, expr->Name); } #line 1209 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, memberType); } static void Amalgame_Compiler_TypeChecker_CheckCallExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr) { #line 1215 "./src/typechecker.am" if ((((expr->Left != NULL) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) && (code_string_equals(expr->Left->Name, "persist"))) && (AmalgameList_count(expr->Args) == 1LL)) { #line 1217 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 0LL)); #line 1218 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, Amalgame_Compiler_TypeChecker_GetType(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, 0LL))); #line 1219 "./src/typechecker.am" return; } #line 1222 "./src/typechecker.am" if (expr->Left != NULL) { Amalgame_Compiler_TypeChecker_CheckExpr(self, expr->Left); } #line 1223 "./src/typechecker.am" i64 argc = AmalgameList_count(expr->Args); #line 1224 "./src/typechecker.am" for (i64 i = 0LL; i < argc; i++) { #line 1225 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i)); } #line 1231 "./src/typechecker.am" if (((((self->Embedded && (self->PersistDepth == 0LL)) && (expr->Left != NULL)) && (expr->Left->Kind == Amalgame_Compiler_NodeKind_MEMBER)) && Amalgame_Compiler_TypeChecker_IsPersistOrigin(self, expr->Left->Left)) && (argc > 0LL)) { #line 1234 "./src/typechecker.am" code_string mname = expr->Left->Name; #line 1235 "./src/typechecker.am" if (((((code_string_equals(mname, "Add")) || (code_string_equals(mname, "Set"))) || (code_string_equals(mname, "Push"))) || (code_string_equals(mname, "Append"))) || (code_string_equals(mname, "Insert"))) { #line 1237 "./src/typechecker.am" Amalgame_Compiler_AstNode* stored = (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, argc - 1LL); #line 1238 "./src/typechecker.am" if (Amalgame_Compiler_TypeChecker_IsArenaOrigin(self, stored) && !Amalgame_Compiler_TypeChecker_IsPersistOrigin(self, stored)) { #line 1239 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_Error(self, "arena value escapes into a persistent collection (it dies at the next loop tick) — wrap it with persist(...)", expr); } } } #line 1244 "./src/typechecker.am" code_string calleeType = "?"; #line 1245 "./src/typechecker.am" Amalgame_Compiler_AstNode* callee = expr->Left; #line 1246 "./src/typechecker.am" if (callee != NULL) { #line 1247 "./src/typechecker.am" Amalgame_Compiler_NodeKind calleeKind = callee->Kind; #line 1248 "./src/typechecker.am" if (calleeKind == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 1249 "./src/typechecker.am" calleeType = Amalgame_Compiler_TypeChecker_SymbolTypeName(self, callee->Name); } else if (calleeKind == Amalgame_Compiler_NodeKind_MEMBER) { #line 1251 "./src/typechecker.am" calleeType = Amalgame_Compiler_TypeChecker_GetType(self, callee); } } #line 1263 "./src/typechecker.am" if ((code_string_equals(calleeType, "Closure")) || (code_string_equals(calleeType, "AmalgameClosure*"))) { #line 1264 "./src/typechecker.am" calleeType = "?"; } else if (String_StartsWith(calleeType, "Closure<") && String_EndsWith(calleeType, ">")) { #line 1266 "./src/typechecker.am" code_string inner = String_Substring(calleeType, 8LL, String_Length(calleeType) - 9LL); #line 1270 "./src/typechecker.am" i64 nin = String_Length(inner); #line 1271 "./src/typechecker.am" i64 depth = 0LL; #line 1272 "./src/typechecker.am" i64 lastComma = -1LL; #line 1273 "./src/typechecker.am" for (i64 i = 0LL; i < nin; i++) { #line 1274 "./src/typechecker.am" code_string ch = String_Substring(inner, i, 1LL); #line 1275 "./src/typechecker.am" if (code_string_equals(ch, "<")) { depth = (depth + 1LL); } else if (code_string_equals(ch, ">")) { #line 1276 "./src/typechecker.am" depth = (depth - 1LL); } else if ((code_string_equals(ch, ",")) && (depth == 0LL)) { #line 1277 "./src/typechecker.am" lastComma = i; } } #line 1279 "./src/typechecker.am" if (lastComma >= 0LL) { #line 1280 "./src/typechecker.am" code_string rRaw = String_Substring(inner, lastComma + 1LL, (nin - lastComma) - 1LL); #line 1281 "./src/typechecker.am" calleeType = String_Trim(rRaw); } else { #line 1284 "./src/typechecker.am" calleeType = String_Trim(inner); } } #line 1287 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, calleeType); } static void Amalgame_Compiler_TypeChecker_CheckNewExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr) { #line 1292 "./src/typechecker.am" i64 argc = AmalgameList_count(expr->Args); #line 1293 "./src/typechecker.am" for (i64 i = 0LL; i < argc; i++) { #line 1294 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_CheckExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i)); } #line 1296 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, expr->Name); } static void Amalgame_Compiler_TypeChecker_CheckIndexExpr(Amalgame_Compiler_TypeChecker* self, Amalgame_Compiler_AstNode* expr) { #line 1300 "./src/typechecker.am" if (expr->Left != NULL) { Amalgame_Compiler_TypeChecker_CheckExpr(self, expr->Left); } #line 1301 "./src/typechecker.am" if (expr->Right != NULL) { Amalgame_Compiler_TypeChecker_CheckExpr(self, expr->Right); } #line 1302 "./src/typechecker.am" code_string targetType = (expr->Left != NULL ? Amalgame_Compiler_TypeChecker_GetType(self, expr->Left) : "?"); #line 1303 "./src/typechecker.am" code_string elemType = Amalgame_Compiler_TypeChecker_CollectionElementType(self, targetType); #line 1304 "./src/typechecker.am" Amalgame_Compiler_TypeChecker_SetType(self, expr, elemType); } code_bool Amalgame_Compiler_TypeChecker_HasErrors(Amalgame_Compiler_TypeChecker* self) { #line 1310 "./src/typechecker.am" return AmalgameList_count(self->Errors) > 0LL; } code_string Amalgame_Compiler_TypeChecker_FormatErrors(Amalgame_Compiler_TypeChecker* self) { #line 1314 "./src/typechecker.am" code_string result = ""; #line 1315 "./src/typechecker.am" i64 count = AmalgameList_count(self->Errors); #line 1316 "./src/typechecker.am" for (i64 i = 0LL; i < count; i++) { #line 1317 "./src/typechecker.am" Amalgame_Compiler_TypeError* e = (Amalgame_Compiler_TypeError*)AmalgameList_get(self->Errors, i); #line 1318 "./src/typechecker.am" result = (code_string_concat(result, Amalgame_Compiler_TypeError_ToString(e))); } #line 1320 "./src/typechecker.am" return result; } struct _Amalgame_Compiler_LintWarning { code_string Message; code_string Filename; i64 Line; i64 Column; }; code_string Amalgame_Compiler_LintWarning_Format(Amalgame_Compiler_LintWarning* self); Amalgame_Compiler_LintWarning* Amalgame_Compiler_LintWarning_new(code_string msg, code_string file, i64 line, i64 col) { Amalgame_Compiler_LintWarning* self = (Amalgame_Compiler_LintWarning*) GC_MALLOC(sizeof(Amalgame_Compiler_LintWarning)); #line 35 "./src/linter.am" self->Message = msg; #line 36 "./src/linter.am" self->Filename = file; #line 37 "./src/linter.am" self->Line = line; #line 38 "./src/linter.am" self->Column = col; return self; } code_string Amalgame_Compiler_LintWarning_Format(Amalgame_Compiler_LintWarning* self) { #line 42 "./src/linter.am" code_string ln = String_FromInt(self->Line); #line 43 "./src/linter.am" code_string col = String_FromInt(self->Column); #line 44 "./src/linter.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("warning[lint]: ", self->Message)), "\n --> ")), self->Filename)), ":")), ln)), ":")), col)), "\n"); } struct _Amalgame_Compiler_Linter { AmalgameList* Warnings; code_string Filename; AmalgameList* LocalNames; AmalgameList* LocalLines; AmalgameList* LocalCols; AmalgameList* LocalIsParam; AmalgameList* LocalIsMut; AmalgameList* LocalUseSnap; AmalgameList* LocalAssignSnap; AmalgameList* ScopeStarts; AmalgameList* UsedNames; AmalgameList* AssignedNames; }; void Amalgame_Compiler_Linter_Lint(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* prog); code_bool Amalgame_Compiler_Linter_HasWarnings(Amalgame_Compiler_Linter* self); code_string Amalgame_Compiler_Linter_FormatWarnings(Amalgame_Compiler_Linter* self); static void Amalgame_Compiler_Linter_LintDecl(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* decl); static void Amalgame_Compiler_Linter_LintMethod(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* method); static void Amalgame_Compiler_Linter_LintBlock(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* block); static code_bool Amalgame_Compiler_Linter_IsTerminator(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* stmt); static void Amalgame_Compiler_Linter_LintStmt(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* stmt); static code_bool Amalgame_Compiler_Linter_IsAssignOp(Amalgame_Compiler_Linter* self, code_string op); static void Amalgame_Compiler_Linter_LintBlockOrStmt(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* n); static void Amalgame_Compiler_Linter_LintExpr(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* expr); static void Amalgame_Compiler_Linter_PushScope(Amalgame_Compiler_Linter* self); static void Amalgame_Compiler_Linter_PopScope(Amalgame_Compiler_Linter* self); static void Amalgame_Compiler_Linter_DeclareLocal(Amalgame_Compiler_Linter* self, code_string name, i64 line, i64 col, code_bool isParam); static void Amalgame_Compiler_Linter_DeclareLocalMut(Amalgame_Compiler_Linter* self, code_string name, i64 line, i64 col, code_bool isParam, code_bool isMut); static code_bool Amalgame_Compiler_Linter_IsShadowing(Amalgame_Compiler_Linter* self, code_string name); static void Amalgame_Compiler_Linter_MarkUsed(Amalgame_Compiler_Linter* self, code_string name); static code_bool Amalgame_Compiler_Linter_UsedAfter(Amalgame_Compiler_Linter* self, code_string name, i64 fromIdx); static code_bool Amalgame_Compiler_Linter_AssignedAfter(Amalgame_Compiler_Linter* self, code_string name, i64 fromIdx); static void Amalgame_Compiler_Linter_Warn(Amalgame_Compiler_Linter* self, code_string msg, Amalgame_Compiler_AstNode* node); Amalgame_Compiler_Linter* Amalgame_Compiler_Linter_new() { Amalgame_Compiler_Linter* self = (Amalgame_Compiler_Linter*) GC_MALLOC(sizeof(Amalgame_Compiler_Linter)); #line 82 "./src/linter.am" self->Warnings = AmalgameList_new(); #line 83 "./src/linter.am" self->Filename = ""; #line 84 "./src/linter.am" self->LocalNames = AmalgameList_new(); #line 85 "./src/linter.am" self->LocalLines = AmalgameList_new(); #line 86 "./src/linter.am" self->LocalCols = AmalgameList_new(); #line 87 "./src/linter.am" self->LocalIsParam = AmalgameList_new(); #line 88 "./src/linter.am" self->LocalIsMut = AmalgameList_new(); #line 89 "./src/linter.am" self->LocalUseSnap = AmalgameList_new(); #line 90 "./src/linter.am" self->LocalAssignSnap = AmalgameList_new(); #line 91 "./src/linter.am" self->ScopeStarts = AmalgameList_new(); #line 92 "./src/linter.am" self->UsedNames = AmalgameList_new(); #line 93 "./src/linter.am" self->AssignedNames = AmalgameList_new(); return self; } void Amalgame_Compiler_Linter_Lint(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* prog) { #line 99 "./src/linter.am" if (String_Length(prog->Str2) > 0LL) { self->Filename = prog->Str2; } #line 100 "./src/linter.am" i64 n = AmalgameList_count(prog->Children); #line 101 "./src/linter.am" for (i64 i = 0LL; i < n; i++) { #line 102 "./src/linter.am" Amalgame_Compiler_Linter_LintDecl(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i)); } } code_bool Amalgame_Compiler_Linter_HasWarnings(Amalgame_Compiler_Linter* self) { #line 106 "./src/linter.am" return AmalgameList_count(self->Warnings) > 0LL; } code_string Amalgame_Compiler_Linter_FormatWarnings(Amalgame_Compiler_Linter* self) { #line 109 "./src/linter.am" code_string s = ""; #line 110 "./src/linter.am" i64 n = AmalgameList_count(self->Warnings); #line 111 "./src/linter.am" for (i64 i = 0LL; i < n; i++) { #line 115 "./src/linter.am" Amalgame_Compiler_LintWarning* w = (Amalgame_Compiler_LintWarning*)AmalgameList_get(self->Warnings, i); #line 116 "./src/linter.am" s = (code_string_concat(s, Amalgame_Compiler_LintWarning_Format(w))); } #line 118 "./src/linter.am" return s; } static void Amalgame_Compiler_Linter_LintDecl(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* decl) { #line 122 "./src/linter.am" Amalgame_Compiler_NodeKind k = decl->Kind; #line 123 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { #line 124 "./src/linter.am" i64 members = AmalgameList_count(decl->Children); #line 125 "./src/linter.am" for (i64 i = 0LL; i < members; i++) { #line 126 "./src/linter.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(decl->Children, i); #line 127 "./src/linter.am" if (m->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) { Amalgame_Compiler_Linter_LintMethod(self, m); } } #line 129 "./src/linter.am" return; } #line 131 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_METHOD_DECL) { #line 132 "./src/linter.am" Amalgame_Compiler_Linter_LintMethod(self, decl); #line 133 "./src/linter.am" return; } #line 135 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) { #line 136 "./src/linter.am" i64 methods = AmalgameList_count(decl->Children); #line 137 "./src/linter.am" for (i64 i = 0LL; i < methods; i++) { #line 138 "./src/linter.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(decl->Children, i); #line 139 "./src/linter.am" if (m->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) { Amalgame_Compiler_Linter_LintMethod(self, m); } } } } static void Amalgame_Compiler_Linter_LintMethod(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* method) { #line 146 "./src/linter.am" self->UsedNames = AmalgameList_new(); #line 147 "./src/linter.am" self->AssignedNames = AmalgameList_new(); #line 148 "./src/linter.am" Amalgame_Compiler_Linter_PushScope(self); #line 149 "./src/linter.am" i64 pn = AmalgameList_count(method->Params); #line 150 "./src/linter.am" for (i64 i = 0LL; i < pn; i++) { #line 151 "./src/linter.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 152 "./src/linter.am" Amalgame_Compiler_Linter_DeclareLocal(self, p->Name, p->Line, p->Column, 1); } #line 154 "./src/linter.am" if (method->Body != NULL) { Amalgame_Compiler_Linter_LintBlock(self, method->Body); } #line 155 "./src/linter.am" Amalgame_Compiler_Linter_PopScope(self); } static void Amalgame_Compiler_Linter_LintBlock(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* block) { #line 159 "./src/linter.am" if (block == NULL) { return; } #line 160 "./src/linter.am" Amalgame_Compiler_Linter_PushScope(self); #line 161 "./src/linter.am" i64 n = AmalgameList_count(block->Children); #line 162 "./src/linter.am" code_bool dead = 0; #line 163 "./src/linter.am" for (i64 i = 0LL; i < n; i++) { #line 164 "./src/linter.am" Amalgame_Compiler_AstNode* stmt = (Amalgame_Compiler_AstNode*)AmalgameList_get(block->Children, i); #line 165 "./src/linter.am" if (dead) { #line 167 "./src/linter.am" Amalgame_Compiler_Linter_Warn(self, "unreachable code after `return` / `throw` / `break` / `continue`", stmt); #line 168 "./src/linter.am" Amalgame_Compiler_Linter_PopScope(self); #line 169 "./src/linter.am" return; } #line 171 "./src/linter.am" Amalgame_Compiler_Linter_LintStmt(self, stmt); #line 172 "./src/linter.am" if (Amalgame_Compiler_Linter_IsTerminator(self, stmt)) { dead = 1; } } #line 174 "./src/linter.am" Amalgame_Compiler_Linter_PopScope(self); } static code_bool Amalgame_Compiler_Linter_IsTerminator(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* stmt) { #line 178 "./src/linter.am" Amalgame_Compiler_NodeKind k = stmt->Kind; #line 179 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_RETURN_STMT) { return 1; } #line 180 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_BREAK_STMT) { return 1; } #line 181 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_CONTINUE_STMT) { return 1; } #line 182 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_THROW_STMT) { return 1; } #line 183 "./src/linter.am" return 0; } static void Amalgame_Compiler_Linter_LintStmt(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* stmt) { #line 193 "./src/linter.am" if (stmt == NULL) { return; } #line 194 "./src/linter.am" Amalgame_Compiler_NodeKind k = stmt->Kind; #line 195 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 197 "./src/linter.am" if (stmt->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, stmt->Left); } #line 200 "./src/linter.am" Amalgame_Compiler_Linter_DeclareLocalMut(self, stmt->Name, stmt->Line, stmt->Column, 0, stmt->Flag); #line 201 "./src/linter.am" return; } #line 203 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_ASSIGN) { #line 208 "./src/linter.am" if ((stmt->Left != NULL) && (stmt->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 209 "./src/linter.am" AmalgameList_add(self->AssignedNames, (void*)(intptr_t)(stmt->Left->Name)); } #line 211 "./src/linter.am" if (stmt->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, stmt->Left); } #line 212 "./src/linter.am" if (stmt->Right != NULL) { Amalgame_Compiler_Linter_LintExpr(self, stmt->Right); } #line 213 "./src/linter.am" return; } #line 215 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_RETURN_STMT) { #line 216 "./src/linter.am" if (stmt->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, stmt->Left); } #line 217 "./src/linter.am" return; } #line 219 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_THROW_STMT) { #line 220 "./src/linter.am" if (stmt->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, stmt->Left); } #line 221 "./src/linter.am" return; } #line 223 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_INLINE_C) { #line 225 "./src/linter.am" return; } #line 227 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_IF_STMT) { #line 229 "./src/linter.am" if (code_string_equals(stmt->Name, "__match__")) { #line 230 "./src/linter.am" if (stmt->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, stmt->Left); } #line 231 "./src/linter.am" i64 an = AmalgameList_count(stmt->Children); #line 232 "./src/linter.am" for (i64 ai = 0LL; ai < an; ai++) { #line 233 "./src/linter.am" Amalgame_Compiler_AstNode* arm = (Amalgame_Compiler_AstNode*)AmalgameList_get(stmt->Children, ai); #line 234 "./src/linter.am" if (arm->Body != NULL) { Amalgame_Compiler_Linter_LintBlockOrStmt(self, arm->Body); } } #line 236 "./src/linter.am" return; } #line 238 "./src/linter.am" if (stmt->Cond != NULL) { Amalgame_Compiler_Linter_LintExpr(self, stmt->Cond); } #line 239 "./src/linter.am" if (stmt->Body != NULL) { Amalgame_Compiler_Linter_LintBlockOrStmt(self, stmt->Body); } #line 240 "./src/linter.am" if (stmt->Else != NULL) { Amalgame_Compiler_Linter_LintBlockOrStmt(self, stmt->Else); } #line 241 "./src/linter.am" return; } #line 243 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_WHILE_STMT) { #line 244 "./src/linter.am" if (stmt->Cond != NULL) { Amalgame_Compiler_Linter_LintExpr(self, stmt->Cond); } #line 245 "./src/linter.am" if (stmt->Body != NULL) { Amalgame_Compiler_Linter_LintBlockOrStmt(self, stmt->Body); } #line 246 "./src/linter.am" return; } #line 248 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_FOR_IN_STMT) { #line 251 "./src/linter.am" if (stmt->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, stmt->Left); } #line 252 "./src/linter.am" Amalgame_Compiler_Linter_PushScope(self); #line 253 "./src/linter.am" Amalgame_Compiler_Linter_DeclareLocal(self, stmt->Name, stmt->Line, stmt->Column, 0); #line 254 "./src/linter.am" if (stmt->Body != NULL) { Amalgame_Compiler_Linter_LintBlockOrStmt(self, stmt->Body); } #line 255 "./src/linter.am" Amalgame_Compiler_Linter_PopScope(self); #line 256 "./src/linter.am" return; } #line 258 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_TRY_STMT) { #line 259 "./src/linter.am" if (stmt->Body != NULL) { Amalgame_Compiler_Linter_LintBlockOrStmt(self, stmt->Body); } #line 265 "./src/linter.am" if (stmt->Else != NULL) { #line 266 "./src/linter.am" Amalgame_Compiler_Linter_PushScope(self); #line 267 "./src/linter.am" if (String_Length(stmt->Name) > 0LL) { #line 268 "./src/linter.am" Amalgame_Compiler_Linter_DeclareLocal(self, stmt->Name, stmt->Line, stmt->Column, 0); } #line 270 "./src/linter.am" Amalgame_Compiler_Linter_LintBlockOrStmt(self, stmt->Else); #line 271 "./src/linter.am" Amalgame_Compiler_Linter_PopScope(self); } #line 273 "./src/linter.am" if (stmt->Cond != NULL) { Amalgame_Compiler_Linter_LintBlockOrStmt(self, stmt->Cond); } #line 274 "./src/linter.am" return; } #line 276 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_BLOCK) { #line 277 "./src/linter.am" Amalgame_Compiler_Linter_LintBlock(self, stmt); #line 278 "./src/linter.am" return; } #line 287 "./src/linter.am" if ((k == Amalgame_Compiler_NodeKind_BINARY) && Amalgame_Compiler_Linter_IsAssignOp(self, stmt->Str)) { #line 288 "./src/linter.am" if ((stmt->Left != NULL) && (stmt->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 289 "./src/linter.am" AmalgameList_add(self->AssignedNames, (void*)(intptr_t)(stmt->Left->Name)); } #line 291 "./src/linter.am" if (stmt->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, stmt->Left); } #line 292 "./src/linter.am" if (stmt->Right != NULL) { Amalgame_Compiler_Linter_LintExpr(self, stmt->Right); } #line 293 "./src/linter.am" return; } #line 295 "./src/linter.am" if (((((k == Amalgame_Compiler_NodeKind_CALL) || (k == Amalgame_Compiler_NodeKind_MEMBER)) || (k == Amalgame_Compiler_NodeKind_BINARY)) || (k == Amalgame_Compiler_NodeKind_UNARY)) || (k == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 296 "./src/linter.am" Amalgame_Compiler_Linter_LintExpr(self, stmt); } } static code_bool Amalgame_Compiler_Linter_IsAssignOp(Amalgame_Compiler_Linter* self, code_string op) { #line 305 "./src/linter.am" if (code_string_equals(op, "=")) { return 1; } #line 306 "./src/linter.am" if (code_string_equals(op, "+=")) { return 1; } #line 307 "./src/linter.am" if (code_string_equals(op, "-=")) { return 1; } #line 308 "./src/linter.am" if (code_string_equals(op, "*=")) { return 1; } #line 309 "./src/linter.am" if (code_string_equals(op, "/=")) { return 1; } #line 310 "./src/linter.am" if (code_string_equals(op, "%=")) { return 1; } #line 311 "./src/linter.am" if (code_string_equals(op, "&=")) { return 1; } #line 312 "./src/linter.am" if (code_string_equals(op, "|=")) { return 1; } #line 313 "./src/linter.am" if (code_string_equals(op, "^=")) { return 1; } #line 314 "./src/linter.am" if (code_string_equals(op, "<<=")) { return 1; } #line 315 "./src/linter.am" if (code_string_equals(op, ">>=")) { return 1; } #line 316 "./src/linter.am" return 0; } static void Amalgame_Compiler_Linter_LintBlockOrStmt(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* n) { #line 320 "./src/linter.am" if (n->Kind == Amalgame_Compiler_NodeKind_BLOCK) { Amalgame_Compiler_Linter_LintBlock(self, n); } else { Amalgame_Compiler_Linter_LintStmt(self, n); } } static void Amalgame_Compiler_Linter_LintExpr(Amalgame_Compiler_Linter* self, Amalgame_Compiler_AstNode* expr) { #line 325 "./src/linter.am" if (expr == NULL) { return; } #line 326 "./src/linter.am" Amalgame_Compiler_NodeKind k = expr->Kind; #line 327 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_IDENTIFIER) { #line 331 "./src/linter.am" if (code_string_equals(expr->Name, "_unknown_")) { return; } #line 332 "./src/linter.am" if (code_string_equals(expr->Name, "_")) { return; } #line 333 "./src/linter.am" Amalgame_Compiler_Linter_MarkUsed(self, expr->Name); #line 334 "./src/linter.am" return; } #line 336 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_BINARY) { #line 337 "./src/linter.am" if (expr->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Left); } #line 338 "./src/linter.am" if (expr->Right != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Right); } #line 339 "./src/linter.am" return; } #line 341 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_UNARY) { #line 342 "./src/linter.am" if (expr->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Left); } #line 343 "./src/linter.am" return; } #line 345 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_MEMBER) { #line 346 "./src/linter.am" if (expr->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Left); } #line 347 "./src/linter.am" return; } #line 349 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_CALL) { #line 350 "./src/linter.am" if (expr->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Left); } #line 351 "./src/linter.am" i64 argc = AmalgameList_count(expr->Args); #line 352 "./src/linter.am" for (i64 i = 0LL; i < argc; i++) { #line 353 "./src/linter.am" Amalgame_Compiler_Linter_LintExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i)); } #line 355 "./src/linter.am" return; } #line 357 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 358 "./src/linter.am" i64 argc = AmalgameList_count(expr->Args); #line 359 "./src/linter.am" for (i64 i = 0LL; i < argc; i++) { #line 360 "./src/linter.am" Amalgame_Compiler_Linter_LintExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Args, i)); } #line 362 "./src/linter.am" return; } #line 364 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_INDEX_EXPR) { #line 365 "./src/linter.am" if (expr->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Left); } #line 366 "./src/linter.am" if (expr->Right != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Right); } #line 367 "./src/linter.am" return; } #line 369 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_LIST_COMP) { #line 372 "./src/linter.am" if (expr->Right != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Right); } #line 373 "./src/linter.am" Amalgame_Compiler_Linter_PushScope(self); #line 374 "./src/linter.am" Amalgame_Compiler_Linter_DeclareLocal(self, expr->Str, expr->Line, expr->Column, 0); #line 375 "./src/linter.am" if (expr->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Left); } #line 376 "./src/linter.am" if (expr->Cond != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Cond); } #line 377 "./src/linter.am" Amalgame_Compiler_Linter_PopScope(self); #line 378 "./src/linter.am" return; } #line 380 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_LIST_LITERAL) { #line 381 "./src/linter.am" i64 nc = AmalgameList_count(expr->Children); #line 382 "./src/linter.am" for (i64 i = 0LL; i < nc; i++) { #line 383 "./src/linter.am" Amalgame_Compiler_Linter_LintExpr(self, (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Children, i)); } #line 385 "./src/linter.am" return; } #line 387 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_ASSIGN) { #line 388 "./src/linter.am" if (expr->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Left); } #line 389 "./src/linter.am" if (expr->Right != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Right); } #line 390 "./src/linter.am" return; } #line 392 "./src/linter.am" if (k == Amalgame_Compiler_NodeKind_IF_STMT) { #line 394 "./src/linter.am" if (code_string_equals(expr->Name, "__match__")) { #line 395 "./src/linter.am" if (expr->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Left); } #line 396 "./src/linter.am" i64 an = AmalgameList_count(expr->Children); #line 397 "./src/linter.am" for (i64 ai = 0LL; ai < an; ai++) { #line 398 "./src/linter.am" Amalgame_Compiler_AstNode* arm = (Amalgame_Compiler_AstNode*)AmalgameList_get(expr->Children, ai); #line 399 "./src/linter.am" if (arm->Body != NULL) { Amalgame_Compiler_Linter_LintBlockOrStmt(self, arm->Body); } } #line 401 "./src/linter.am" return; } #line 403 "./src/linter.am" if (expr->Cond != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Cond); } #line 404 "./src/linter.am" if (expr->Body != NULL) { Amalgame_Compiler_Linter_LintBlockOrStmt(self, expr->Body); } #line 405 "./src/linter.am" if (expr->Else != NULL) { Amalgame_Compiler_Linter_LintBlockOrStmt(self, expr->Else); } #line 406 "./src/linter.am" return; } #line 408 "./src/linter.am" if ((k == Amalgame_Compiler_NodeKind_METHOD_DECL) && (code_string_equals(expr->Name, "__lambda__"))) { #line 412 "./src/linter.am" Amalgame_Compiler_Linter_PushScope(self); #line 413 "./src/linter.am" Amalgame_Compiler_Linter_DeclareLocal(self, expr->Str, expr->Line, expr->Column, 1); #line 414 "./src/linter.am" if (expr->Left != NULL) { Amalgame_Compiler_Linter_LintExpr(self, expr->Left); } #line 415 "./src/linter.am" Amalgame_Compiler_Linter_PopScope(self); #line 416 "./src/linter.am" return; } } static void Amalgame_Compiler_Linter_PushScope(Amalgame_Compiler_Linter* self) { #line 423 "./src/linter.am" AmalgameList_add(self->ScopeStarts, (void*)(intptr_t)(AmalgameList_count(self->LocalNames))); } static void Amalgame_Compiler_Linter_PopScope(Amalgame_Compiler_Linter* self) { #line 427 "./src/linter.am" i64 depth = AmalgameList_count(self->ScopeStarts); #line 428 "./src/linter.am" if (depth == 0LL) { return; } #line 429 "./src/linter.am" i64 mark = (i64)(intptr_t)AmalgameList_get(self->ScopeStarts, depth - 1LL); #line 430 "./src/linter.am" AmalgameList_removeAt(self->ScopeStarts, depth - 1LL); #line 434 "./src/linter.am" while (AmalgameList_count(self->LocalNames) > mark) { #line 435 "./src/linter.am" i64 last = AmalgameList_count(self->LocalNames) - 1LL; #line 436 "./src/linter.am" code_string name = (code_string)AmalgameList_get(self->LocalNames, last); #line 437 "./src/linter.am" i64 line = (i64)(intptr_t)AmalgameList_get(self->LocalLines, last); #line 438 "./src/linter.am" i64 col = (i64)(intptr_t)AmalgameList_get(self->LocalCols, last); #line 439 "./src/linter.am" code_bool isParam = (code_bool)(intptr_t)AmalgameList_get(self->LocalIsParam, last); #line 440 "./src/linter.am" code_bool isMut = (code_bool)(intptr_t)AmalgameList_get(self->LocalIsMut, last); #line 441 "./src/linter.am" i64 snap = (i64)(intptr_t)AmalgameList_get(self->LocalUseSnap, last); #line 442 "./src/linter.am" i64 assignSnap = (i64)(intptr_t)AmalgameList_get(self->LocalAssignSnap, last); #line 443 "./src/linter.am" if (!isParam && !String_StartsWith(name, "_")) { #line 444 "./src/linter.am" if (!Amalgame_Compiler_Linter_UsedAfter(self, name, snap)) { #line 445 "./src/linter.am" Amalgame_Compiler_LintWarning* w = Amalgame_Compiler_LintWarning_new(code_string_concat((code_string_concat("unused local '", name)), "' (prefix with '_' to silence)"), self->Filename, line, col); #line 446 "./src/linter.am" AmalgameList_add(self->Warnings, (void*)(intptr_t)(w)); } else if (isMut && !Amalgame_Compiler_Linter_AssignedAfter(self, name, assignSnap)) { #line 452 "./src/linter.am" Amalgame_Compiler_LintWarning* w = Amalgame_Compiler_LintWarning_new(code_string_concat((code_string_concat("'", name)), "' is declared `var` but never reassigned — use `let`"), self->Filename, line, col); #line 453 "./src/linter.am" AmalgameList_add(self->Warnings, (void*)(intptr_t)(w)); } } #line 456 "./src/linter.am" AmalgameList_removeAt(self->LocalNames, last); #line 457 "./src/linter.am" AmalgameList_removeAt(self->LocalLines, last); #line 458 "./src/linter.am" AmalgameList_removeAt(self->LocalCols, last); #line 459 "./src/linter.am" AmalgameList_removeAt(self->LocalIsParam, last); #line 460 "./src/linter.am" AmalgameList_removeAt(self->LocalIsMut, last); #line 461 "./src/linter.am" AmalgameList_removeAt(self->LocalUseSnap, last); #line 462 "./src/linter.am" AmalgameList_removeAt(self->LocalAssignSnap, last); } } static void Amalgame_Compiler_Linter_DeclareLocal(Amalgame_Compiler_Linter* self, code_string name, i64 line, i64 col, code_bool isParam) { #line 471 "./src/linter.am" Amalgame_Compiler_Linter_DeclareLocalMut(self, name, line, col, isParam, 0); } static void Amalgame_Compiler_Linter_DeclareLocalMut(Amalgame_Compiler_Linter* self, code_string name, i64 line, i64 col, code_bool isParam, code_bool isMut) { #line 475 "./src/linter.am" if (Amalgame_Compiler_Linter_IsShadowing(self, name)) { #line 476 "./src/linter.am" Amalgame_Compiler_LintWarning* w = Amalgame_Compiler_LintWarning_new(code_string_concat((code_string_concat("'", name)), "' shadows an enclosing binding"), self->Filename, line, col); #line 477 "./src/linter.am" AmalgameList_add(self->Warnings, (void*)(intptr_t)(w)); } #line 479 "./src/linter.am" AmalgameList_add(self->LocalNames, (void*)(intptr_t)(name)); #line 480 "./src/linter.am" AmalgameList_add(self->LocalLines, (void*)(intptr_t)(line)); #line 481 "./src/linter.am" AmalgameList_add(self->LocalCols, (void*)(intptr_t)(col)); #line 482 "./src/linter.am" AmalgameList_add(self->LocalIsParam, (void*)(intptr_t)(isParam)); #line 483 "./src/linter.am" AmalgameList_add(self->LocalIsMut, (void*)(intptr_t)(isMut)); #line 484 "./src/linter.am" AmalgameList_add(self->LocalUseSnap, (void*)(intptr_t)(AmalgameList_count(self->UsedNames))); #line 485 "./src/linter.am" AmalgameList_add(self->LocalAssignSnap, (void*)(intptr_t)(AmalgameList_count(self->AssignedNames))); } static code_bool Amalgame_Compiler_Linter_IsShadowing(Amalgame_Compiler_Linter* self, code_string name) { #line 491 "./src/linter.am" i64 depth = AmalgameList_count(self->ScopeStarts); #line 492 "./src/linter.am" if (depth == 0LL) { return 0; } #line 493 "./src/linter.am" i64 curStart = (i64)(intptr_t)AmalgameList_get(self->ScopeStarts, depth - 1LL); #line 494 "./src/linter.am" i64 i = curStart - 1LL; #line 495 "./src/linter.am" while (i >= 0LL) { #line 496 "./src/linter.am" if (code_string_equals((code_string)AmalgameList_get(self->LocalNames, i), name)) { return 1; } #line 497 "./src/linter.am" i = (i - 1LL); } #line 499 "./src/linter.am" return 0; } static void Amalgame_Compiler_Linter_MarkUsed(Amalgame_Compiler_Linter* self, code_string name) { #line 503 "./src/linter.am" AmalgameList_add(self->UsedNames, (void*)(intptr_t)(name)); } static code_bool Amalgame_Compiler_Linter_UsedAfter(Amalgame_Compiler_Linter* self, code_string name, i64 fromIdx) { #line 508 "./src/linter.am" i64 n = AmalgameList_count(self->UsedNames); #line 509 "./src/linter.am" i64 i = fromIdx; #line 510 "./src/linter.am" while (i < n) { #line 511 "./src/linter.am" code_string u = (code_string)AmalgameList_get(self->UsedNames, i); #line 512 "./src/linter.am" if (code_string_equals(u, name)) { return 1; } #line 513 "./src/linter.am" i = (i + 1LL); } #line 515 "./src/linter.am" return 0; } static code_bool Amalgame_Compiler_Linter_AssignedAfter(Amalgame_Compiler_Linter* self, code_string name, i64 fromIdx) { #line 522 "./src/linter.am" i64 n = AmalgameList_count(self->AssignedNames); #line 523 "./src/linter.am" i64 i = fromIdx; #line 524 "./src/linter.am" while (i < n) { #line 525 "./src/linter.am" code_string a = (code_string)AmalgameList_get(self->AssignedNames, i); #line 526 "./src/linter.am" if (code_string_equals(a, name)) { return 1; } #line 527 "./src/linter.am" i = (i + 1LL); } #line 529 "./src/linter.am" return 0; } static void Amalgame_Compiler_Linter_Warn(Amalgame_Compiler_Linter* self, code_string msg, Amalgame_Compiler_AstNode* node) { #line 533 "./src/linter.am" i64 line = 0LL; #line 534 "./src/linter.am" i64 col = 0LL; #line 535 "./src/linter.am" if (node != NULL) { #line 536 "./src/linter.am" line = node->Line; #line 537 "./src/linter.am" col = node->Column; } #line 539 "./src/linter.am" Amalgame_Compiler_LintWarning* w = Amalgame_Compiler_LintWarning_new(msg, self->Filename, line, col); #line 540 "./src/linter.am" AmalgameList_add(self->Warnings, (void*)(intptr_t)(w)); } enum _Amalgame_Compiler_JsonKind { Amalgame_Compiler_JsonKind_Null, Amalgame_Compiler_JsonKind_Bool, Amalgame_Compiler_JsonKind_Int, Amalgame_Compiler_JsonKind_Float, Amalgame_Compiler_JsonKind_String, Amalgame_Compiler_JsonKind_Array, Amalgame_Compiler_JsonKind_Object }; struct _Amalgame_Compiler_JsonValue { Amalgame_Compiler_JsonKind Kind; code_bool B; i64 I; double F; code_string S; AmalgameList* Items; AmalgameList* ObjKeys; AmalgameList* ObjVals; }; code_bool Amalgame_Compiler_JsonValue_IsNull(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsBool(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsInt(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsFloat(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsNumber(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsString(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsArray(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_IsObject(Amalgame_Compiler_JsonValue* self); code_bool Amalgame_Compiler_JsonValue_AsBool(Amalgame_Compiler_JsonValue* self); i64 Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue* self); double Amalgame_Compiler_JsonValue_AsFloat(Amalgame_Compiler_JsonValue* self); code_string Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue* self); AmalgameList* Amalgame_Compiler_JsonValue_AsArray(Amalgame_Compiler_JsonValue* self); Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonValue_Get(Amalgame_Compiler_JsonValue* self, code_string key); code_bool Amalgame_Compiler_JsonValue_Has(Amalgame_Compiler_JsonValue* self, code_string key); AmalgameList* Amalgame_Compiler_JsonValue_Keys(Amalgame_Compiler_JsonValue* self); Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonValue_At(Amalgame_Compiler_JsonValue* self, i64 i); i64 Amalgame_Compiler_JsonValue_Length(Amalgame_Compiler_JsonValue* self); void Amalgame_Compiler_JsonValue_SetNull(Amalgame_Compiler_JsonValue* self); void Amalgame_Compiler_JsonValue_SetBool(Amalgame_Compiler_JsonValue* self, code_bool b); void Amalgame_Compiler_JsonValue_SetInt(Amalgame_Compiler_JsonValue* self, i64 n); void Amalgame_Compiler_JsonValue_SetFloat(Amalgame_Compiler_JsonValue* self, double f); void Amalgame_Compiler_JsonValue_SetString(Amalgame_Compiler_JsonValue* self, code_string s); void Amalgame_Compiler_JsonValue_SetArray(Amalgame_Compiler_JsonValue* self, AmalgameList* xs); void Amalgame_Compiler_JsonValue_SetObject(Amalgame_Compiler_JsonValue* self, AmalgameList* keys, AmalgameList* vals); void Amalgame_Compiler_JsonValue_AppendItem(Amalgame_Compiler_JsonValue* self, Amalgame_Compiler_JsonValue* v); void Amalgame_Compiler_JsonValue_AppendEntry(Amalgame_Compiler_JsonValue* self, code_string key, Amalgame_Compiler_JsonValue* v); Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonValue_new() { Amalgame_Compiler_JsonValue* self = (Amalgame_Compiler_JsonValue*) GC_MALLOC(sizeof(Amalgame_Compiler_JsonValue)); #line 45 "./src/stdlib/json.am" self->Kind = Amalgame_Compiler_JsonKind_Null; #line 46 "./src/stdlib/json.am" self->B = 0; #line 47 "./src/stdlib/json.am" self->I = 0LL; #line 48 "./src/stdlib/json.am" self->F = 0.0; #line 49 "./src/stdlib/json.am" self->S = ""; #line 50 "./src/stdlib/json.am" self->Items = AmalgameList_new(); #line 51 "./src/stdlib/json.am" self->ObjKeys = AmalgameList_new(); #line 52 "./src/stdlib/json.am" self->ObjVals = AmalgameList_new(); return self; } code_bool Amalgame_Compiler_JsonValue_IsNull(Amalgame_Compiler_JsonValue* self) { #line 56 "./src/stdlib/json.am" return self->Kind == Amalgame_Compiler_JsonKind_Null; } code_bool Amalgame_Compiler_JsonValue_IsBool(Amalgame_Compiler_JsonValue* self) { #line 57 "./src/stdlib/json.am" return self->Kind == Amalgame_Compiler_JsonKind_Bool; } code_bool Amalgame_Compiler_JsonValue_IsInt(Amalgame_Compiler_JsonValue* self) { #line 58 "./src/stdlib/json.am" return self->Kind == Amalgame_Compiler_JsonKind_Int; } code_bool Amalgame_Compiler_JsonValue_IsFloat(Amalgame_Compiler_JsonValue* self) { #line 59 "./src/stdlib/json.am" return self->Kind == Amalgame_Compiler_JsonKind_Float; } code_bool Amalgame_Compiler_JsonValue_IsNumber(Amalgame_Compiler_JsonValue* self) { #line 60 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_IsInt(self) || Amalgame_Compiler_JsonValue_IsFloat(self); } code_bool Amalgame_Compiler_JsonValue_IsString(Amalgame_Compiler_JsonValue* self) { #line 61 "./src/stdlib/json.am" return self->Kind == Amalgame_Compiler_JsonKind_String; } code_bool Amalgame_Compiler_JsonValue_IsArray(Amalgame_Compiler_JsonValue* self) { #line 62 "./src/stdlib/json.am" return self->Kind == Amalgame_Compiler_JsonKind_Array; } code_bool Amalgame_Compiler_JsonValue_IsObject(Amalgame_Compiler_JsonValue* self) { #line 63 "./src/stdlib/json.am" return self->Kind == Amalgame_Compiler_JsonKind_Object; } code_bool Amalgame_Compiler_JsonValue_AsBool(Amalgame_Compiler_JsonValue* self) { #line 75 "./src/stdlib/json.am" if (self->Kind == Amalgame_Compiler_JsonKind_Bool) { return self->B; } #line 76 "./src/stdlib/json.am" return 0; } i64 Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue* self) { #line 80 "./src/stdlib/json.am" if (self->Kind == Amalgame_Compiler_JsonKind_Int) { return self->I; } #line 81 "./src/stdlib/json.am" return 0LL; } double Amalgame_Compiler_JsonValue_AsFloat(Amalgame_Compiler_JsonValue* self) { #line 85 "./src/stdlib/json.am" if (self->Kind == Amalgame_Compiler_JsonKind_Float) { return self->F; } #line 86 "./src/stdlib/json.am" return 0.0; } code_string Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue* self) { #line 90 "./src/stdlib/json.am" if (self->Kind == Amalgame_Compiler_JsonKind_String) { return self->S; } #line 91 "./src/stdlib/json.am" return ""; } AmalgameList* Amalgame_Compiler_JsonValue_AsArray(Amalgame_Compiler_JsonValue* self) { #line 95 "./src/stdlib/json.am" return self->Items; } Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonValue_Get(Amalgame_Compiler_JsonValue* self, code_string key) { #line 103 "./src/stdlib/json.am" if (self->Kind != Amalgame_Compiler_JsonKind_Object) { return Amalgame_Compiler_JsonValue_new(); } #line 104 "./src/stdlib/json.am" i64 n = AmalgameList_count(self->ObjKeys); #line 105 "./src/stdlib/json.am" for (i64 i = 0LL; i < n; i++) { #line 106 "./src/stdlib/json.am" if (code_string_equals((code_string)AmalgameList_get(self->ObjKeys, i), key)) { #line 107 "./src/stdlib/json.am" return (Amalgame_Compiler_JsonValue*)AmalgameList_get(self->ObjVals, i); } } #line 110 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } code_bool Amalgame_Compiler_JsonValue_Has(Amalgame_Compiler_JsonValue* self, code_string key) { #line 114 "./src/stdlib/json.am" if (self->Kind != Amalgame_Compiler_JsonKind_Object) { return 0; } #line 115 "./src/stdlib/json.am" i64 n = AmalgameList_count(self->ObjKeys); #line 116 "./src/stdlib/json.am" for (i64 i = 0LL; i < n; i++) { #line 117 "./src/stdlib/json.am" if (code_string_equals((code_string)AmalgameList_get(self->ObjKeys, i), key)) { return 1; } } #line 119 "./src/stdlib/json.am" return 0; } AmalgameList* Amalgame_Compiler_JsonValue_Keys(Amalgame_Compiler_JsonValue* self) { #line 123 "./src/stdlib/json.am" return self->ObjKeys; } Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonValue_At(Amalgame_Compiler_JsonValue* self, i64 i) { #line 130 "./src/stdlib/json.am" if (self->Kind != Amalgame_Compiler_JsonKind_Array) { return Amalgame_Compiler_JsonValue_new(); } #line 131 "./src/stdlib/json.am" if (i < 0LL) { return Amalgame_Compiler_JsonValue_new(); } #line 132 "./src/stdlib/json.am" if (i >= AmalgameList_count(self->Items)) { return Amalgame_Compiler_JsonValue_new(); } #line 133 "./src/stdlib/json.am" return (Amalgame_Compiler_JsonValue*)AmalgameList_get(self->Items, i); } i64 Amalgame_Compiler_JsonValue_Length(Amalgame_Compiler_JsonValue* self) { #line 137 "./src/stdlib/json.am" if (self->Kind == Amalgame_Compiler_JsonKind_Array) { return AmalgameList_count(self->Items); } #line 138 "./src/stdlib/json.am" if (self->Kind == Amalgame_Compiler_JsonKind_Object) { return AmalgameList_count(self->ObjKeys); } #line 139 "./src/stdlib/json.am" if (self->Kind == Amalgame_Compiler_JsonKind_String) { return String_Length(self->S); } #line 140 "./src/stdlib/json.am" return 0LL; } void Amalgame_Compiler_JsonValue_SetNull(Amalgame_Compiler_JsonValue* self) { #line 149 "./src/stdlib/json.am" self->Kind = Amalgame_Compiler_JsonKind_Null; } void Amalgame_Compiler_JsonValue_SetBool(Amalgame_Compiler_JsonValue* self, code_bool b) { #line 153 "./src/stdlib/json.am" self->Kind = Amalgame_Compiler_JsonKind_Bool; #line 154 "./src/stdlib/json.am" self->B = b; } void Amalgame_Compiler_JsonValue_SetInt(Amalgame_Compiler_JsonValue* self, i64 n) { #line 158 "./src/stdlib/json.am" self->Kind = Amalgame_Compiler_JsonKind_Int; #line 159 "./src/stdlib/json.am" self->I = n; } void Amalgame_Compiler_JsonValue_SetFloat(Amalgame_Compiler_JsonValue* self, double f) { #line 163 "./src/stdlib/json.am" self->Kind = Amalgame_Compiler_JsonKind_Float; #line 164 "./src/stdlib/json.am" self->F = f; } void Amalgame_Compiler_JsonValue_SetString(Amalgame_Compiler_JsonValue* self, code_string s) { #line 168 "./src/stdlib/json.am" self->Kind = Amalgame_Compiler_JsonKind_String; #line 169 "./src/stdlib/json.am" self->S = s; } void Amalgame_Compiler_JsonValue_SetArray(Amalgame_Compiler_JsonValue* self, AmalgameList* xs) { #line 173 "./src/stdlib/json.am" self->Kind = Amalgame_Compiler_JsonKind_Array; #line 174 "./src/stdlib/json.am" self->Items = xs; } void Amalgame_Compiler_JsonValue_SetObject(Amalgame_Compiler_JsonValue* self, AmalgameList* keys, AmalgameList* vals) { #line 178 "./src/stdlib/json.am" self->Kind = Amalgame_Compiler_JsonKind_Object; #line 179 "./src/stdlib/json.am" self->ObjKeys = keys; #line 180 "./src/stdlib/json.am" self->ObjVals = vals; } void Amalgame_Compiler_JsonValue_AppendItem(Amalgame_Compiler_JsonValue* self, Amalgame_Compiler_JsonValue* v) { #line 184 "./src/stdlib/json.am" AmalgameList_add(self->Items, (void*)(intptr_t)(v)); } void Amalgame_Compiler_JsonValue_AppendEntry(Amalgame_Compiler_JsonValue* self, code_string key, Amalgame_Compiler_JsonValue* v) { #line 188 "./src/stdlib/json.am" AmalgameList_add(self->ObjKeys, (void*)(intptr_t)(key)); #line 189 "./src/stdlib/json.am" AmalgameList_add(self->ObjVals, (void*)(intptr_t)(v)); } struct _Amalgame_Compiler_JsonError { code_string Message; i64 Line; i64 Column; }; Amalgame_Compiler_JsonError* Amalgame_Compiler_JsonError_new(code_string msg, i64 line, i64 col) { Amalgame_Compiler_JsonError* self = (Amalgame_Compiler_JsonError*) GC_MALLOC(sizeof(Amalgame_Compiler_JsonError)); #line 201 "./src/stdlib/json.am" self->Message = msg; #line 202 "./src/stdlib/json.am" self->Line = line; #line 203 "./src/stdlib/json.am" self->Column = col; return self; } struct _Amalgame_Compiler_JsonResult { code_bool Ok; Amalgame_Compiler_JsonValue* Value; Amalgame_Compiler_JsonError* Error; }; Amalgame_Compiler_JsonResult* Amalgame_Compiler_JsonResult_new() { Amalgame_Compiler_JsonResult* self = (Amalgame_Compiler_JsonResult*) GC_MALLOC(sizeof(Amalgame_Compiler_JsonResult)); #line 215 "./src/stdlib/json.am" self->Ok = 1; #line 216 "./src/stdlib/json.am" self->Value = Amalgame_Compiler_JsonValue_new(); #line 217 "./src/stdlib/json.am" self->Error = Amalgame_Compiler_JsonError_new("", 0LL, 0LL); return self; } struct _Amalgame_Compiler_JsonParser { code_string Source; i64 Pos; i64 Line; i64 Column; code_bool Failed; code_string ErrMsg; i64 ErrLine; i64 ErrCol; }; code_bool Amalgame_Compiler_JsonParser_HasFailed(Amalgame_Compiler_JsonParser* self); code_string Amalgame_Compiler_JsonParser_ErrorMsg(Amalgame_Compiler_JsonParser* self); i64 Amalgame_Compiler_JsonParser_ErrorLine(Amalgame_Compiler_JsonParser* self); i64 Amalgame_Compiler_JsonParser_ErrorCol(Amalgame_Compiler_JsonParser* self); static void Amalgame_Compiler_JsonParser_Fail(Amalgame_Compiler_JsonParser* self, code_string msg); static code_bool Amalgame_Compiler_JsonParser_AtEnd(Amalgame_Compiler_JsonParser* self); static code_string Amalgame_Compiler_JsonParser_Peek(Amalgame_Compiler_JsonParser* self); static code_string Amalgame_Compiler_JsonParser_PeekAt(Amalgame_Compiler_JsonParser* self, i64 offset); static code_string Amalgame_Compiler_JsonParser_Advance(Amalgame_Compiler_JsonParser* self); static void Amalgame_Compiler_JsonParser_SkipWs(Amalgame_Compiler_JsonParser* self); static code_bool Amalgame_Compiler_JsonParser_MatchLit(Amalgame_Compiler_JsonParser* self, code_string lit); Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseTopLevel(Amalgame_Compiler_JsonParser* self); Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseValue(Amalgame_Compiler_JsonParser* self); static code_bool Amalgame_Compiler_JsonParser_IsDigit(code_string c); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseObject(Amalgame_Compiler_JsonParser* self); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseArray(Amalgame_Compiler_JsonParser* self); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseString(Amalgame_Compiler_JsonParser* self); static i64 Amalgame_Compiler_JsonParser_ParseHex4(Amalgame_Compiler_JsonParser* self); static i64 Amalgame_Compiler_JsonParser_HexDigit(code_string c); static code_string Amalgame_Compiler_JsonParser_Bs(); static code_string Amalgame_Compiler_JsonParser_Ff(); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseNumber(Amalgame_Compiler_JsonParser* self); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseBool(Amalgame_Compiler_JsonParser* self); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseNull(Amalgame_Compiler_JsonParser* self); Amalgame_Compiler_JsonParser* Amalgame_Compiler_JsonParser_new(code_string source) { Amalgame_Compiler_JsonParser* self = (Amalgame_Compiler_JsonParser*) GC_MALLOC(sizeof(Amalgame_Compiler_JsonParser)); #line 239 "./src/stdlib/json.am" self->Source = source; #line 240 "./src/stdlib/json.am" self->Pos = 0LL; #line 241 "./src/stdlib/json.am" self->Line = 1LL; #line 242 "./src/stdlib/json.am" self->Column = 1LL; #line 243 "./src/stdlib/json.am" self->Failed = 0; #line 244 "./src/stdlib/json.am" self->ErrMsg = ""; #line 245 "./src/stdlib/json.am" self->ErrLine = 0LL; #line 246 "./src/stdlib/json.am" self->ErrCol = 0LL; return self; } code_bool Amalgame_Compiler_JsonParser_HasFailed(Amalgame_Compiler_JsonParser* self) { #line 249 "./src/stdlib/json.am" return self->Failed; } code_string Amalgame_Compiler_JsonParser_ErrorMsg(Amalgame_Compiler_JsonParser* self) { #line 250 "./src/stdlib/json.am" return self->ErrMsg; } i64 Amalgame_Compiler_JsonParser_ErrorLine(Amalgame_Compiler_JsonParser* self) { #line 251 "./src/stdlib/json.am" return self->ErrLine; } i64 Amalgame_Compiler_JsonParser_ErrorCol(Amalgame_Compiler_JsonParser* self) { #line 252 "./src/stdlib/json.am" return self->ErrCol; } static void Amalgame_Compiler_JsonParser_Fail(Amalgame_Compiler_JsonParser* self, code_string msg) { #line 255 "./src/stdlib/json.am" if (self->Failed) { return; } #line 256 "./src/stdlib/json.am" self->Failed = 1; #line 257 "./src/stdlib/json.am" self->ErrMsg = msg; #line 258 "./src/stdlib/json.am" self->ErrLine = self->Line; #line 259 "./src/stdlib/json.am" self->ErrCol = self->Column; } static code_bool Amalgame_Compiler_JsonParser_AtEnd(Amalgame_Compiler_JsonParser* self) { #line 263 "./src/stdlib/json.am" return self->Pos >= String_Length(self->Source); } static code_string Amalgame_Compiler_JsonParser_Peek(Amalgame_Compiler_JsonParser* self) { #line 267 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_AtEnd(self)) { return ""; } #line 268 "./src/stdlib/json.am" return String_CharAt1(self->Source, self->Pos); } static code_string Amalgame_Compiler_JsonParser_PeekAt(Amalgame_Compiler_JsonParser* self, i64 offset) { #line 272 "./src/stdlib/json.am" i64 idx = self->Pos + offset; #line 273 "./src/stdlib/json.am" if (idx < 0LL) { return ""; } #line 274 "./src/stdlib/json.am" if (idx >= String_Length(self->Source)) { return ""; } #line 275 "./src/stdlib/json.am" return String_CharAt1(self->Source, idx); } static code_string Amalgame_Compiler_JsonParser_Advance(Amalgame_Compiler_JsonParser* self) { #line 279 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_AtEnd(self)) { return ""; } #line 280 "./src/stdlib/json.am" code_string ch = String_CharAt1(self->Source, self->Pos); #line 281 "./src/stdlib/json.am" self->Pos = (self->Pos + 1LL); #line 282 "./src/stdlib/json.am" if (code_string_equals(ch, "\n")) { #line 283 "./src/stdlib/json.am" self->Line = (self->Line + 1LL); #line 284 "./src/stdlib/json.am" self->Column = 1LL; } else { #line 286 "./src/stdlib/json.am" self->Column = (self->Column + 1LL); } #line 288 "./src/stdlib/json.am" return ch; } static void Amalgame_Compiler_JsonParser_SkipWs(Amalgame_Compiler_JsonParser* self) { #line 292 "./src/stdlib/json.am" while (!Amalgame_Compiler_JsonParser_AtEnd(self)) { #line 293 "./src/stdlib/json.am" code_string c = Amalgame_Compiler_JsonParser_Peek(self); #line 294 "./src/stdlib/json.am" if ((((code_string_equals(c, " ")) || (code_string_equals(c, "\t"))) || (code_string_equals(c, "\n"))) || (code_string_equals(c, "\r"))) { #line 295 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); } else { #line 296 "./src/stdlib/json.am" return; } } } static code_bool Amalgame_Compiler_JsonParser_MatchLit(Amalgame_Compiler_JsonParser* self, code_string lit) { #line 302 "./src/stdlib/json.am" i64 n = String_Length(lit); #line 303 "./src/stdlib/json.am" if ((self->Pos + n) > String_Length(self->Source)) { return 0; } #line 304 "./src/stdlib/json.am" for (i64 i = 0LL; i < n; i++) { #line 305 "./src/stdlib/json.am" code_string want = String_CharAt1(lit, i); #line 306 "./src/stdlib/json.am" code_string got = String_CharAt1(self->Source, self->Pos + i); #line 307 "./src/stdlib/json.am" if (!code_string_equals(want, got)) { return 0; } } #line 309 "./src/stdlib/json.am" for (i64 j = 0LL; j < n; j++) { #line 310 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); } #line 312 "./src/stdlib/json.am" return 1; } Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseTopLevel(Amalgame_Compiler_JsonParser* self) { #line 320 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_SkipWs(self); #line 321 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonParser_ParseValue(self); #line 322 "./src/stdlib/json.am" if (self->Failed) { return Amalgame_Compiler_JsonValue_new(); } #line 323 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_SkipWs(self); #line 324 "./src/stdlib/json.am" if (!Amalgame_Compiler_JsonParser_AtEnd(self)) { #line 325 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "trailing characters after JSON value"); #line 326 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } #line 328 "./src/stdlib/json.am" return v; } Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseValue(Amalgame_Compiler_JsonParser* self) { #line 332 "./src/stdlib/json.am" if (self->Failed) { return Amalgame_Compiler_JsonValue_new(); } #line 333 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_SkipWs(self); #line 334 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_AtEnd(self)) { #line 335 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "unexpected end of input"); #line 336 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } #line 338 "./src/stdlib/json.am" code_string c = Amalgame_Compiler_JsonParser_Peek(self); #line 339 "./src/stdlib/json.am" if (code_string_equals(c, "{")) { return Amalgame_Compiler_JsonParser_ParseObject(self); } #line 340 "./src/stdlib/json.am" if (code_string_equals(c, "[")) { return Amalgame_Compiler_JsonParser_ParseArray(self); } #line 341 "./src/stdlib/json.am" if (code_string_equals(c, "\"")) { return Amalgame_Compiler_JsonParser_ParseString(self); } #line 342 "./src/stdlib/json.am" if ((code_string_equals(c, "t")) || (code_string_equals(c, "f"))) { return Amalgame_Compiler_JsonParser_ParseBool(self); } #line 343 "./src/stdlib/json.am" if (code_string_equals(c, "n")) { return Amalgame_Compiler_JsonParser_ParseNull(self); } #line 344 "./src/stdlib/json.am" if ((code_string_equals(c, "-")) || Amalgame_Compiler_JsonParser_IsDigit(c)) { return Amalgame_Compiler_JsonParser_ParseNumber(self); } #line 345 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, code_string_concat((code_string_concat("unexpected character '", c)), "'")); #line 346 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } static code_bool Amalgame_Compiler_JsonParser_IsDigit(code_string c) { #line 355 "./src/stdlib/json.am" if (String_Length(c) == 0LL) { return 0; } #line 356 "./src/stdlib/json.am" return String_IndexOf("0123456789", c) >= 0LL; } static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseObject(Amalgame_Compiler_JsonParser* self) { #line 360 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); #line 361 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* out = Amalgame_Compiler_JsonValue_new(); #line 362 "./src/stdlib/json.am" AmalgameList* keys = AmalgameList_new(); #line 363 "./src/stdlib/json.am" AmalgameList* vals = AmalgameList_new(); #line 364 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_SetObject(out, keys, vals); #line 365 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_SkipWs(self); #line 366 "./src/stdlib/json.am" if (code_string_equals(Amalgame_Compiler_JsonParser_Peek(self), "}")) { Amalgame_Compiler_JsonParser_Advance(self); return out; } #line 367 "./src/stdlib/json.am" while (1) { #line 368 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_SkipWs(self); #line 369 "./src/stdlib/json.am" if (!code_string_equals(Amalgame_Compiler_JsonParser_Peek(self), "\"")) { #line 370 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "expected string key in object"); #line 371 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } #line 373 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* keyVal = Amalgame_Compiler_JsonParser_ParseString(self); #line 374 "./src/stdlib/json.am" if (self->Failed) { return Amalgame_Compiler_JsonValue_new(); } #line 375 "./src/stdlib/json.am" code_string key = Amalgame_Compiler_JsonValue_AsString(keyVal); #line 376 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_SkipWs(self); #line 377 "./src/stdlib/json.am" if (!code_string_equals(Amalgame_Compiler_JsonParser_Peek(self), ":")) { #line 378 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "expected ':' after object key"); #line 379 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } #line 381 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); #line 382 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonParser_ParseValue(self); #line 383 "./src/stdlib/json.am" if (self->Failed) { return Amalgame_Compiler_JsonValue_new(); } #line 384 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_AppendEntry(out, key, v); #line 385 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_SkipWs(self); #line 386 "./src/stdlib/json.am" code_string nx = Amalgame_Compiler_JsonParser_Peek(self); #line 387 "./src/stdlib/json.am" if (code_string_equals(nx, ",")) { Amalgame_Compiler_JsonParser_Advance(self); continue; } #line 388 "./src/stdlib/json.am" if (code_string_equals(nx, "}")) { Amalgame_Compiler_JsonParser_Advance(self); return out; } #line 389 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "expected ',' or '}' in object"); #line 390 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } #line 392 "./src/stdlib/json.am" return out; } static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseArray(Amalgame_Compiler_JsonParser* self) { #line 396 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); #line 397 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* out = Amalgame_Compiler_JsonValue_new(); #line 398 "./src/stdlib/json.am" AmalgameList* xs = AmalgameList_new(); #line 399 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_SetArray(out, xs); #line 400 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_SkipWs(self); #line 401 "./src/stdlib/json.am" if (code_string_equals(Amalgame_Compiler_JsonParser_Peek(self), "]")) { Amalgame_Compiler_JsonParser_Advance(self); return out; } #line 402 "./src/stdlib/json.am" while (1) { #line 403 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonParser_ParseValue(self); #line 404 "./src/stdlib/json.am" if (self->Failed) { return Amalgame_Compiler_JsonValue_new(); } #line 405 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_AppendItem(out, v); #line 406 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_SkipWs(self); #line 407 "./src/stdlib/json.am" code_string nx = Amalgame_Compiler_JsonParser_Peek(self); #line 408 "./src/stdlib/json.am" if (code_string_equals(nx, ",")) { Amalgame_Compiler_JsonParser_Advance(self); continue; } #line 409 "./src/stdlib/json.am" if (code_string_equals(nx, "]")) { Amalgame_Compiler_JsonParser_Advance(self); return out; } #line 410 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "expected ',' or ']' in array"); #line 411 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } #line 413 "./src/stdlib/json.am" return out; } static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseString(Amalgame_Compiler_JsonParser* self) { #line 417 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); #line 418 "./src/stdlib/json.am" code_string out = ""; #line 419 "./src/stdlib/json.am" while (!Amalgame_Compiler_JsonParser_AtEnd(self)) { #line 420 "./src/stdlib/json.am" code_string c = Amalgame_Compiler_JsonParser_Peek(self); #line 421 "./src/stdlib/json.am" if (code_string_equals(c, "\"")) { #line 422 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); #line 423 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 424 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_SetString(v, out); #line 425 "./src/stdlib/json.am" return v; } #line 427 "./src/stdlib/json.am" if (code_string_equals(c, "\\")) { #line 428 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); #line 429 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_AtEnd(self)) { #line 430 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "unterminated escape in string"); #line 431 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } #line 433 "./src/stdlib/json.am" code_string esc = Amalgame_Compiler_JsonParser_Advance(self); #line 434 "./src/stdlib/json.am" if (code_string_equals(esc, "\"")) { out = (code_string_concat(out, "\"")); } else if (code_string_equals(esc, "\\")) { #line 435 "./src/stdlib/json.am" out = (code_string_concat(out, "\\")); } else if (code_string_equals(esc, "/")) { #line 436 "./src/stdlib/json.am" out = (code_string_concat(out, "/")); } else if (code_string_equals(esc, "b")) { #line 437 "./src/stdlib/json.am" out = (code_string_concat(out, Amalgame_Compiler_JsonParser_Bs())); } else if (code_string_equals(esc, "f")) { #line 438 "./src/stdlib/json.am" out = (code_string_concat(out, Amalgame_Compiler_JsonParser_Ff())); } else if (code_string_equals(esc, "n")) { #line 439 "./src/stdlib/json.am" out = (code_string_concat(out, "\n")); } else if (code_string_equals(esc, "r")) { #line 440 "./src/stdlib/json.am" out = (code_string_concat(out, "\r")); } else if (code_string_equals(esc, "t")) { #line 441 "./src/stdlib/json.am" out = (code_string_concat(out, "\t")); } else if (code_string_equals(esc, "u")) { #line 443 "./src/stdlib/json.am" i64 cp = Amalgame_Compiler_JsonParser_ParseHex4(self); #line 444 "./src/stdlib/json.am" if (self->Failed) { return Amalgame_Compiler_JsonValue_new(); } #line 449 "./src/stdlib/json.am" if ((cp >= 55296LL) && (cp <= 56319LL)) { #line 450 "./src/stdlib/json.am" if ((code_string_equals(Amalgame_Compiler_JsonParser_Peek(self), "\\")) && (code_string_equals(Amalgame_Compiler_JsonParser_PeekAt(self, 1LL), "u"))) { #line 451 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); #line 452 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); #line 453 "./src/stdlib/json.am" i64 lo = Amalgame_Compiler_JsonParser_ParseHex4(self); #line 454 "./src/stdlib/json.am" if (self->Failed) { return Amalgame_Compiler_JsonValue_new(); } #line 455 "./src/stdlib/json.am" if ((lo >= 56320LL) && (lo <= 57343LL)) { #line 456 "./src/stdlib/json.am" i64 combined = (65536LL + ((cp - 55296LL) * 1024LL)) + (lo - 56320LL); #line 457 "./src/stdlib/json.am" out = (code_string_concat(out, String_FromCodepoint(combined))); } else { #line 463 "./src/stdlib/json.am" out = (code_string_concat(out, String_FromCodepoint(cp))); #line 464 "./src/stdlib/json.am" out = (code_string_concat(out, String_FromCodepoint(lo))); } } else { #line 467 "./src/stdlib/json.am" out = (code_string_concat(out, String_FromCodepoint(cp))); } } else { #line 470 "./src/stdlib/json.am" out = (code_string_concat(out, String_FromCodepoint(cp))); } } else { #line 474 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, code_string_concat((code_string_concat("invalid escape '\\", esc)), "'")); #line 475 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } } else if (code_string_equals(c, "\n")) { #line 478 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "unescaped newline in string"); #line 479 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } else { #line 481 "./src/stdlib/json.am" out = (code_string_concat(out, Amalgame_Compiler_JsonParser_Advance(self))); } } #line 484 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "unterminated string"); #line 485 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } static i64 Amalgame_Compiler_JsonParser_ParseHex4(Amalgame_Compiler_JsonParser* self) { #line 489 "./src/stdlib/json.am" i64 n = 0LL; #line 490 "./src/stdlib/json.am" for (i64 i = 0LL; i < 4LL; i++) { #line 491 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_AtEnd(self)) { #line 492 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "incomplete \\u escape"); #line 493 "./src/stdlib/json.am" return 0LL; } #line 495 "./src/stdlib/json.am" code_string ch = Amalgame_Compiler_JsonParser_Advance(self); #line 496 "./src/stdlib/json.am" i64 d = Amalgame_Compiler_JsonParser_HexDigit(ch); #line 497 "./src/stdlib/json.am" if (d < 0LL) { #line 498 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, code_string_concat((code_string_concat("invalid hex digit '", ch)), "' in \\u escape")); #line 499 "./src/stdlib/json.am" return 0LL; } #line 501 "./src/stdlib/json.am" n = ((n * 16LL) + d); } #line 503 "./src/stdlib/json.am" return n; } static i64 Amalgame_Compiler_JsonParser_HexDigit(code_string c) { #line 507 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_IsDigit(c)) { return String_ToInt(c); } #line 508 "./src/stdlib/json.am" if ((code_string_equals(c, "a")) || (code_string_equals(c, "A"))) { return 10LL; } #line 509 "./src/stdlib/json.am" if ((code_string_equals(c, "b")) || (code_string_equals(c, "B"))) { return 11LL; } #line 510 "./src/stdlib/json.am" if ((code_string_equals(c, "c")) || (code_string_equals(c, "C"))) { return 12LL; } #line 511 "./src/stdlib/json.am" if ((code_string_equals(c, "d")) || (code_string_equals(c, "D"))) { return 13LL; } #line 512 "./src/stdlib/json.am" if ((code_string_equals(c, "e")) || (code_string_equals(c, "E"))) { return 14LL; } #line 513 "./src/stdlib/json.am" if ((code_string_equals(c, "f")) || (code_string_equals(c, "F"))) { return 15LL; } #line 514 "./src/stdlib/json.am" return -1LL; } static code_string Amalgame_Compiler_JsonParser_Bs() { #line 520 "./src/stdlib/json.am" return String_FromCodepoint(8LL); } static code_string Amalgame_Compiler_JsonParser_Ff() { #line 521 "./src/stdlib/json.am" return String_FromCodepoint(12LL); } static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseNumber(Amalgame_Compiler_JsonParser* self) { #line 524 "./src/stdlib/json.am" i64 start = self->Pos; #line 525 "./src/stdlib/json.am" code_bool isFloat = 0; #line 526 "./src/stdlib/json.am" if (code_string_equals(Amalgame_Compiler_JsonParser_Peek(self), "-")) { Amalgame_Compiler_JsonParser_Advance(self); } #line 528 "./src/stdlib/json.am" if (code_string_equals(Amalgame_Compiler_JsonParser_Peek(self), "0")) { #line 529 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); } else { #line 531 "./src/stdlib/json.am" code_string c = Amalgame_Compiler_JsonParser_Peek(self); #line 532 "./src/stdlib/json.am" if (!Amalgame_Compiler_JsonParser_IsDigit(c) || (code_string_equals(c, "0"))) { #line 535 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "expected digit in number"); #line 536 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } #line 538 "./src/stdlib/json.am" while (1) { #line 539 "./src/stdlib/json.am" code_string d = Amalgame_Compiler_JsonParser_Peek(self); #line 540 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_IsDigit(d)) { Amalgame_Compiler_JsonParser_Advance(self); } else { #line 541 "./src/stdlib/json.am" break; } } } #line 545 "./src/stdlib/json.am" if (code_string_equals(Amalgame_Compiler_JsonParser_Peek(self), ".")) { #line 546 "./src/stdlib/json.am" isFloat = 1; #line 547 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); #line 548 "./src/stdlib/json.am" code_string c = Amalgame_Compiler_JsonParser_Peek(self); #line 549 "./src/stdlib/json.am" if (!Amalgame_Compiler_JsonParser_IsDigit(c)) { #line 550 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "expected digit after '.'"); #line 551 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } #line 553 "./src/stdlib/json.am" while (1) { #line 554 "./src/stdlib/json.am" code_string d = Amalgame_Compiler_JsonParser_Peek(self); #line 555 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_IsDigit(d)) { Amalgame_Compiler_JsonParser_Advance(self); } else { #line 556 "./src/stdlib/json.am" break; } } } #line 560 "./src/stdlib/json.am" code_string e = Amalgame_Compiler_JsonParser_Peek(self); #line 561 "./src/stdlib/json.am" if ((code_string_equals(e, "e")) || (code_string_equals(e, "E"))) { #line 562 "./src/stdlib/json.am" isFloat = 1; #line 563 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Advance(self); #line 564 "./src/stdlib/json.am" code_string s = Amalgame_Compiler_JsonParser_Peek(self); #line 565 "./src/stdlib/json.am" if ((code_string_equals(s, "+")) || (code_string_equals(s, "-"))) { Amalgame_Compiler_JsonParser_Advance(self); } #line 566 "./src/stdlib/json.am" code_string c2 = Amalgame_Compiler_JsonParser_Peek(self); #line 567 "./src/stdlib/json.am" if (!Amalgame_Compiler_JsonParser_IsDigit(c2)) { #line 568 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "expected digit in exponent"); #line 569 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } #line 571 "./src/stdlib/json.am" while (1) { #line 572 "./src/stdlib/json.am" code_string d = Amalgame_Compiler_JsonParser_Peek(self); #line 573 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_IsDigit(d)) { Amalgame_Compiler_JsonParser_Advance(self); } else { #line 574 "./src/stdlib/json.am" break; } } } #line 577 "./src/stdlib/json.am" code_string raw = String_Substring(self->Source, start, self->Pos - start); #line 578 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* out = Amalgame_Compiler_JsonValue_new(); #line 579 "./src/stdlib/json.am" if (isFloat) { #line 580 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_SetFloat(out, String_ToFloat(raw)); } else { #line 582 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_SetInt(out, String_ToInt(raw)); } #line 584 "./src/stdlib/json.am" return out; } static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseBool(Amalgame_Compiler_JsonParser* self) { #line 588 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_MatchLit(self, "true")) { #line 589 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 590 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_SetBool(v, 1); #line 591 "./src/stdlib/json.am" return v; } #line 593 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_MatchLit(self, "false")) { #line 594 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 595 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_SetBool(v, 0); #line 596 "./src/stdlib/json.am" return v; } #line 598 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "invalid literal (expected true / false)"); #line 599 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } static Amalgame_Compiler_JsonValue* Amalgame_Compiler_JsonParser_ParseNull(Amalgame_Compiler_JsonParser* self) { #line 603 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_MatchLit(self, "null")) { #line 604 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } #line 606 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser_Fail(self, "invalid literal (expected null)"); #line 607 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } struct _Amalgame_Compiler_Json { }; Amalgame_Compiler_JsonResult* Amalgame_Compiler_Json_Parse(code_string source); code_string Amalgame_Compiler_Json_Encode(Amalgame_Compiler_JsonValue* v); static code_string Amalgame_Compiler_Json_EncodeArray(Amalgame_Compiler_JsonValue* v); static code_string Amalgame_Compiler_Json_EncodeObject(Amalgame_Compiler_JsonValue* v); code_string Amalgame_Compiler_Json_EscapeString(code_string s); Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_NullValue(); Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfBool(code_bool b); Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfInt(i64 n); Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfFloat(double f); Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfString(code_string s); Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfArray(AmalgameList* xs); Amalgame_Compiler_Json* Amalgame_Compiler_Json_new() { Amalgame_Compiler_Json* self = (Amalgame_Compiler_Json*) GC_MALLOC(sizeof(Amalgame_Compiler_Json)); return self; } Amalgame_Compiler_JsonResult* Amalgame_Compiler_Json_Parse(code_string source) { #line 619 "./src/stdlib/json.am" Amalgame_Compiler_JsonResult* res = Amalgame_Compiler_JsonResult_new(); #line 620 "./src/stdlib/json.am" Amalgame_Compiler_JsonParser* p = Amalgame_Compiler_JsonParser_new(source); #line 621 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonParser_ParseTopLevel(p); #line 622 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonParser_HasFailed(p)) { #line 623 "./src/stdlib/json.am" res->Ok = 0; #line 624 "./src/stdlib/json.am" res->Value = Amalgame_Compiler_JsonValue_new(); #line 625 "./src/stdlib/json.am" res->Error = Amalgame_Compiler_JsonError_new(Amalgame_Compiler_JsonParser_ErrorMsg(p), Amalgame_Compiler_JsonParser_ErrorLine(p), Amalgame_Compiler_JsonParser_ErrorCol(p)); #line 626 "./src/stdlib/json.am" return res; } #line 628 "./src/stdlib/json.am" res->Ok = 1; #line 629 "./src/stdlib/json.am" res->Value = v; #line 630 "./src/stdlib/json.am" return res; } code_string Amalgame_Compiler_Json_Encode(Amalgame_Compiler_JsonValue* v) { #line 638 "./src/stdlib/json.am" Amalgame_Compiler_JsonKind k = v->Kind; #line 639 "./src/stdlib/json.am" if (k == Amalgame_Compiler_JsonKind_Null) { return "null"; } #line 640 "./src/stdlib/json.am" if (k == Amalgame_Compiler_JsonKind_Bool) { #line 641 "./src/stdlib/json.am" if (Amalgame_Compiler_JsonValue_AsBool(v)) { return "true"; } #line 642 "./src/stdlib/json.am" return "false"; } #line 644 "./src/stdlib/json.am" if (k == Amalgame_Compiler_JsonKind_Int) { return String_FromInt(Amalgame_Compiler_JsonValue_AsInt(v)); } #line 645 "./src/stdlib/json.am" if (k == Amalgame_Compiler_JsonKind_Float) { return String_FromFloat(Amalgame_Compiler_JsonValue_AsFloat(v)); } #line 646 "./src/stdlib/json.am" if (k == Amalgame_Compiler_JsonKind_String) { return code_string_concat((code_string_concat("\"", Amalgame_Compiler_Json_EscapeString(Amalgame_Compiler_JsonValue_AsString(v)))), "\""); } #line 647 "./src/stdlib/json.am" if (k == Amalgame_Compiler_JsonKind_Array) { return Amalgame_Compiler_Json_EncodeArray(v); } #line 648 "./src/stdlib/json.am" if (k == Amalgame_Compiler_JsonKind_Object) { return Amalgame_Compiler_Json_EncodeObject(v); } #line 649 "./src/stdlib/json.am" return "null"; } static code_string Amalgame_Compiler_Json_EncodeArray(Amalgame_Compiler_JsonValue* v) { #line 653 "./src/stdlib/json.am" AmalgameList* xs = Amalgame_Compiler_JsonValue_AsArray(v); #line 654 "./src/stdlib/json.am" i64 n = AmalgameList_count(xs); #line 655 "./src/stdlib/json.am" code_string out = "["; #line 656 "./src/stdlib/json.am" for (i64 i = 0LL; i < n; i++) { #line 657 "./src/stdlib/json.am" if (i > 0LL) { out = (code_string_concat(out, ",")); } #line 658 "./src/stdlib/json.am" out = (code_string_concat(out, Amalgame_Compiler_Json_Encode((Amalgame_Compiler_JsonValue*)AmalgameList_get(xs, i)))); } #line 660 "./src/stdlib/json.am" out = (code_string_concat(out, "]")); #line 661 "./src/stdlib/json.am" return out; } static code_string Amalgame_Compiler_Json_EncodeObject(Amalgame_Compiler_JsonValue* v) { #line 665 "./src/stdlib/json.am" AmalgameList* keys = Amalgame_Compiler_JsonValue_Keys(v); #line 666 "./src/stdlib/json.am" i64 n = AmalgameList_count(keys); #line 667 "./src/stdlib/json.am" code_string out = "{"; #line 668 "./src/stdlib/json.am" for (i64 i = 0LL; i < n; i++) { #line 669 "./src/stdlib/json.am" if (i > 0LL) { out = (code_string_concat(out, ",")); } #line 670 "./src/stdlib/json.am" code_string key = (code_string)AmalgameList_get(keys, i); #line 671 "./src/stdlib/json.am" out = (code_string_concat((code_string_concat((code_string_concat(out, "\"")), Amalgame_Compiler_Json_EscapeString(key))), "\":")); #line 672 "./src/stdlib/json.am" out = (code_string_concat(out, Amalgame_Compiler_Json_Encode(Amalgame_Compiler_JsonValue_Get(v, key)))); } #line 674 "./src/stdlib/json.am" out = (code_string_concat(out, "}")); #line 675 "./src/stdlib/json.am" return out; } code_string Amalgame_Compiler_Json_EscapeString(code_string s) { #line 683 "./src/stdlib/json.am" i64 n = String_Length(s); #line 684 "./src/stdlib/json.am" code_string out = ""; #line 685 "./src/stdlib/json.am" for (i64 i = 0LL; i < n; i++) { #line 686 "./src/stdlib/json.am" code_string c = String_CharAt1(s, i); #line 687 "./src/stdlib/json.am" if (code_string_equals(c, "\"")) { out = (code_string_concat(out, "\\\"")); } else if (code_string_equals(c, "\\")) { #line 688 "./src/stdlib/json.am" out = (code_string_concat(out, "\\\\")); } else if (code_string_equals(c, "\n")) { #line 689 "./src/stdlib/json.am" out = (code_string_concat(out, "\\n")); } else if (code_string_equals(c, String_FromByte(13LL))) { #line 690 "./src/stdlib/json.am" out = (code_string_concat(out, "\\r")); } else if (code_string_equals(c, "\t")) { #line 691 "./src/stdlib/json.am" out = (code_string_concat(out, "\\t")); } else if (code_string_equals(c, String_FromCodepoint(8LL))) { #line 692 "./src/stdlib/json.am" out = (code_string_concat(out, "\\b")); } else if (code_string_equals(c, String_FromCodepoint(12LL))) { #line 693 "./src/stdlib/json.am" out = (code_string_concat(out, "\\f")); } else { #line 694 "./src/stdlib/json.am" out = (code_string_concat(out, c)); } } #line 696 "./src/stdlib/json.am" return out; } Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_NullValue() { #line 701 "./src/stdlib/json.am" return Amalgame_Compiler_JsonValue_new(); } Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfBool(code_bool b) { #line 705 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 706 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_SetBool(v, b); #line 707 "./src/stdlib/json.am" return v; } Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfInt(i64 n) { #line 711 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 712 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_SetInt(v, n); #line 713 "./src/stdlib/json.am" return v; } Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfFloat(double f) { #line 717 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 718 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_SetFloat(v, f); #line 719 "./src/stdlib/json.am" return v; } Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfString(code_string s) { #line 723 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 724 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_SetString(v, s); #line 725 "./src/stdlib/json.am" return v; } Amalgame_Compiler_JsonValue* Amalgame_Compiler_Json_OfArray(AmalgameList* xs) { #line 729 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 730 "./src/stdlib/json.am" Amalgame_Compiler_JsonValue_SetArray(v, xs); #line 731 "./src/stdlib/json.am" return v; } struct _Amalgame_Compiler_MsgPackCursor { AmalgameList* Bytes; i64 Pos; }; code_bool Amalgame_Compiler_MsgPackCursor_AtEnd(Amalgame_Compiler_MsgPackCursor* self); i64 Amalgame_Compiler_MsgPackCursor_Read(Amalgame_Compiler_MsgPackCursor* self); Amalgame_Compiler_MsgPackCursor* Amalgame_Compiler_MsgPackCursor_new(AmalgameList* bytes) { Amalgame_Compiler_MsgPackCursor* self = (Amalgame_Compiler_MsgPackCursor*) GC_MALLOC(sizeof(Amalgame_Compiler_MsgPackCursor)); #line 52 "./src/stdlib/msgpack.am" self->Bytes = bytes; #line 53 "./src/stdlib/msgpack.am" self->Pos = 0LL; return self; } code_bool Amalgame_Compiler_MsgPackCursor_AtEnd(Amalgame_Compiler_MsgPackCursor* self) { #line 57 "./src/stdlib/msgpack.am" return self->Pos >= AmalgameList_count(self->Bytes); } i64 Amalgame_Compiler_MsgPackCursor_Read(Amalgame_Compiler_MsgPackCursor* self) { #line 61 "./src/stdlib/msgpack.am" if (Amalgame_Compiler_MsgPackCursor_AtEnd(self)) { return 0LL; } #line 62 "./src/stdlib/msgpack.am" i64 b = (i64)(intptr_t)AmalgameList_get(self->Bytes, self->Pos); #line 63 "./src/stdlib/msgpack.am" self->Pos = (self->Pos + 1LL); #line 64 "./src/stdlib/msgpack.am" return b; } struct _Amalgame_Compiler_MsgPack { }; AmalgameList* Amalgame_Compiler_MsgPack_EncodeJson(Amalgame_Compiler_JsonValue* value); static void Amalgame_Compiler_MsgPack_EncodeJsonInto(Amalgame_Compiler_JsonValue* value, AmalgameList* out); static void Amalgame_Compiler_MsgPack_EncodeInt(i64 v, AmalgameList* out); static void Amalgame_Compiler_MsgPack_EncodeString(code_string s, AmalgameList* out); static void Amalgame_Compiler_MsgPack_EncodeArrayHeader(i64 n, AmalgameList* out); static void Amalgame_Compiler_MsgPack_EncodeMapHeader(i64 n, AmalgameList* out); static i64 Amalgame_Compiler_MsgPack_ByteOf(i64 v, i64 byteIdx); static i64 Amalgame_Compiler_MsgPack_ByteOfI64(i64 v, i64 byteIdx); static i64 Amalgame_Compiler_MsgPack_Pow256(i64 n); static i64 Amalgame_Compiler_MsgPack_ByteOfChar(code_string c); static code_string Amalgame_Compiler_MsgPack_AsciiTable(); Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_DecodeJson(AmalgameList* bytes); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_DecodeOne(Amalgame_Compiler_MsgPackCursor* c); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_ReadStrInto(Amalgame_Compiler_MsgPackCursor* c, i64 n); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_ReadArrayInto(Amalgame_Compiler_MsgPackCursor* c, i64 n); static Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_ReadMapInto(Amalgame_Compiler_MsgPackCursor* c, i64 n); Amalgame_Compiler_MsgPack* Amalgame_Compiler_MsgPack_new() { Amalgame_Compiler_MsgPack* self = (Amalgame_Compiler_MsgPack*) GC_MALLOC(sizeof(Amalgame_Compiler_MsgPack)); return self; } AmalgameList* Amalgame_Compiler_MsgPack_EncodeJson(Amalgame_Compiler_JsonValue* value) { #line 74 "./src/stdlib/msgpack.am" AmalgameList* out = AmalgameList_new(); #line 75 "./src/stdlib/msgpack.am" Amalgame_Compiler_MsgPack_EncodeJsonInto(value, out); #line 76 "./src/stdlib/msgpack.am" return out; } static void Amalgame_Compiler_MsgPack_EncodeJsonInto(Amalgame_Compiler_JsonValue* value, AmalgameList* out) { #line 80 "./src/stdlib/msgpack.am" if (Amalgame_Compiler_JsonValue_IsNull(value)) { #line 81 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(192LL)); #line 82 "./src/stdlib/msgpack.am" return; } #line 84 "./src/stdlib/msgpack.am" if (Amalgame_Compiler_JsonValue_IsBool(value)) { #line 85 "./src/stdlib/msgpack.am" if (Amalgame_Compiler_JsonValue_AsBool(value)) { AmalgameList_add(out, (void*)(intptr_t)(195LL)); } else { AmalgameList_add(out, (void*)(intptr_t)(194LL)); } #line 86 "./src/stdlib/msgpack.am" return; } #line 88 "./src/stdlib/msgpack.am" if (Amalgame_Compiler_JsonValue_IsInt(value)) { #line 89 "./src/stdlib/msgpack.am" Amalgame_Compiler_MsgPack_EncodeInt(Amalgame_Compiler_JsonValue_AsInt(value), out); #line 90 "./src/stdlib/msgpack.am" return; } #line 92 "./src/stdlib/msgpack.am" if (Amalgame_Compiler_JsonValue_IsString(value)) { #line 93 "./src/stdlib/msgpack.am" Amalgame_Compiler_MsgPack_EncodeString(Amalgame_Compiler_JsonValue_AsString(value), out); #line 94 "./src/stdlib/msgpack.am" return; } #line 96 "./src/stdlib/msgpack.am" if (Amalgame_Compiler_JsonValue_IsArray(value)) { #line 97 "./src/stdlib/msgpack.am" AmalgameList* items = Amalgame_Compiler_JsonValue_AsArray(value); #line 98 "./src/stdlib/msgpack.am" i64 n = AmalgameList_count(items); #line 99 "./src/stdlib/msgpack.am" Amalgame_Compiler_MsgPack_EncodeArrayHeader(n, out); #line 100 "./src/stdlib/msgpack.am" for (i64 i = 0LL; i < n; i++) { #line 101 "./src/stdlib/msgpack.am" Amalgame_Compiler_MsgPack_EncodeJsonInto((Amalgame_Compiler_JsonValue*)AmalgameList_get(items, i), out); } #line 103 "./src/stdlib/msgpack.am" return; } #line 105 "./src/stdlib/msgpack.am" if (Amalgame_Compiler_JsonValue_IsObject(value)) { #line 106 "./src/stdlib/msgpack.am" AmalgameList* keys = Amalgame_Compiler_JsonValue_Keys(value); #line 107 "./src/stdlib/msgpack.am" i64 n = AmalgameList_count(keys); #line 108 "./src/stdlib/msgpack.am" Amalgame_Compiler_MsgPack_EncodeMapHeader(n, out); #line 109 "./src/stdlib/msgpack.am" for (i64 i = 0LL; i < n; i++) { #line 110 "./src/stdlib/msgpack.am" code_string k = (code_string)AmalgameList_get(keys, i); #line 111 "./src/stdlib/msgpack.am" Amalgame_Compiler_MsgPack_EncodeString(k, out); #line 112 "./src/stdlib/msgpack.am" Amalgame_Compiler_MsgPack_EncodeJsonInto(Amalgame_Compiler_JsonValue_Get(value, k), out); } #line 114 "./src/stdlib/msgpack.am" return; } #line 117 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(192LL)); } static void Amalgame_Compiler_MsgPack_EncodeInt(i64 v, AmalgameList* out) { #line 121 "./src/stdlib/msgpack.am" if ((v >= 0LL) && (v <= 127LL)) { #line 122 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(v)); #line 123 "./src/stdlib/msgpack.am" return; } #line 125 "./src/stdlib/msgpack.am" if ((v < 0LL) && (v >= -32LL)) { #line 127 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(256LL + v)); #line 128 "./src/stdlib/msgpack.am" return; } #line 131 "./src/stdlib/msgpack.am" if ((v >= -128LL) && (v <= 127LL)) { #line 132 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(208LL)); #line 133 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOf(v, 0LL))); #line 134 "./src/stdlib/msgpack.am" return; } #line 136 "./src/stdlib/msgpack.am" if ((v >= -32768LL) && (v <= 32767LL)) { #line 137 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(209LL)); #line 138 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOf(v, 1LL))); #line 139 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOf(v, 0LL))); #line 140 "./src/stdlib/msgpack.am" return; } #line 142 "./src/stdlib/msgpack.am" if ((v >= -2147483648LL) && (v <= 2147483647LL)) { #line 143 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(210LL)); #line 144 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOf(v, 3LL))); #line 145 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOf(v, 2LL))); #line 146 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOf(v, 1LL))); #line 147 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOf(v, 0LL))); #line 148 "./src/stdlib/msgpack.am" return; } #line 153 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(211LL)); #line 154 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOfI64(v, 7LL))); #line 155 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOfI64(v, 6LL))); #line 156 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOfI64(v, 5LL))); #line 157 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOfI64(v, 4LL))); #line 158 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOfI64(v, 3LL))); #line 159 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOfI64(v, 2LL))); #line 160 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOfI64(v, 1LL))); #line 161 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOfI64(v, 0LL))); } static void Amalgame_Compiler_MsgPack_EncodeString(code_string s, AmalgameList* out) { #line 165 "./src/stdlib/msgpack.am" i64 n = String_Length(s); #line 166 "./src/stdlib/msgpack.am" if (n <= 31LL) { #line 167 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(160LL + n)); } else if (n <= 255LL) { #line 169 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(217LL)); #line 170 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(n)); } else if (n <= 65535LL) { #line 173 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(218LL)); #line 174 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)((n / 256LL) % 256LL)); #line 175 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(n % 256LL)); } else { #line 178 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(218LL)); #line 179 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(255LL)); #line 180 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(255LL)); } #line 182 "./src/stdlib/msgpack.am" i64 cap = n; #line 183 "./src/stdlib/msgpack.am" if (cap > 65535LL) { cap = 65535LL; } #line 184 "./src/stdlib/msgpack.am" for (i64 i = 0LL; i < cap; i++) { #line 185 "./src/stdlib/msgpack.am" code_string ch = String_Substring(s, i, 1LL); #line 186 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_MsgPack_ByteOfChar(ch))); } } static void Amalgame_Compiler_MsgPack_EncodeArrayHeader(i64 n, AmalgameList* out) { #line 191 "./src/stdlib/msgpack.am" if (n <= 15LL) { #line 192 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(144LL + n)); #line 193 "./src/stdlib/msgpack.am" return; } #line 195 "./src/stdlib/msgpack.am" if (n <= 65535LL) { #line 196 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(220LL)); #line 197 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)((n / 256LL) % 256LL)); #line 198 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(n % 256LL)); #line 199 "./src/stdlib/msgpack.am" return; } #line 202 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(220LL)); #line 203 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(255LL)); #line 204 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(255LL)); } static void Amalgame_Compiler_MsgPack_EncodeMapHeader(i64 n, AmalgameList* out) { #line 208 "./src/stdlib/msgpack.am" if (n <= 15LL) { #line 209 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(128LL + n)); #line 210 "./src/stdlib/msgpack.am" return; } #line 212 "./src/stdlib/msgpack.am" if (n <= 65535LL) { #line 213 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(222LL)); #line 214 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)((n / 256LL) % 256LL)); #line 215 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(n % 256LL)); #line 216 "./src/stdlib/msgpack.am" return; } #line 218 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(222LL)); #line 219 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(255LL)); #line 220 "./src/stdlib/msgpack.am" AmalgameList_add(out, (void*)(intptr_t)(255LL)); } static i64 Amalgame_Compiler_MsgPack_ByteOf(i64 v, i64 byteIdx) { #line 229 "./src/stdlib/msgpack.am" i64 shifted = v / Amalgame_Compiler_MsgPack_Pow256(byteIdx); #line 230 "./src/stdlib/msgpack.am" i64 withOffset = shifted + 16777216LL; #line 231 "./src/stdlib/msgpack.am" return withOffset % 256LL; } static i64 Amalgame_Compiler_MsgPack_ByteOfI64(i64 v, i64 byteIdx) { #line 239 "./src/stdlib/msgpack.am" i64 shifted = v >> (byteIdx * 8LL); #line 240 "./src/stdlib/msgpack.am" return shifted & 255LL; } static i64 Amalgame_Compiler_MsgPack_Pow256(i64 n) { #line 244 "./src/stdlib/msgpack.am" i64 r = 1LL; #line 245 "./src/stdlib/msgpack.am" i64 i = 0LL; #line 246 "./src/stdlib/msgpack.am" while (i < n) { r = (r * 256LL); i = (i + 1LL); } #line 247 "./src/stdlib/msgpack.am" return r; } static i64 Amalgame_Compiler_MsgPack_ByteOfChar(code_string c) { #line 255 "./src/stdlib/msgpack.am" code_string table = Amalgame_Compiler_MsgPack_AsciiTable(); #line 256 "./src/stdlib/msgpack.am" i64 idx = String_IndexOf(table, c); #line 257 "./src/stdlib/msgpack.am" if (idx < 0LL) { return 63LL; } #line 258 "./src/stdlib/msgpack.am" return idx + 32LL; } static code_string Amalgame_Compiler_MsgPack_AsciiTable() { #line 267 "./src/stdlib/msgpack.am" return " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; } Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_DecodeJson(AmalgameList* bytes) { #line 273 "./src/stdlib/msgpack.am" Amalgame_Compiler_MsgPackCursor* cursor = Amalgame_Compiler_MsgPackCursor_new(bytes); #line 274 "./src/stdlib/msgpack.am" return Amalgame_Compiler_MsgPack_DecodeOne(cursor); } static Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_DecodeOne(Amalgame_Compiler_MsgPackCursor* c) { #line 278 "./src/stdlib/msgpack.am" if (Amalgame_Compiler_MsgPackCursor_AtEnd(c)) { return Amalgame_Compiler_JsonValue_new(); } #line 279 "./src/stdlib/msgpack.am" i64 b = Amalgame_Compiler_MsgPackCursor_Read(c); #line 281 "./src/stdlib/msgpack.am" if (b == 192LL) { return Amalgame_Compiler_JsonValue_new(); } #line 283 "./src/stdlib/msgpack.am" if (b == 194LL) { Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); Amalgame_Compiler_JsonValue_SetBool(v, 0); return v; } #line 284 "./src/stdlib/msgpack.am" if (b == 195LL) { Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); Amalgame_Compiler_JsonValue_SetBool(v, 1); return v; } #line 286 "./src/stdlib/msgpack.am" if ((b >= 0LL) && (b <= 127LL)) { #line 287 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); Amalgame_Compiler_JsonValue_SetInt(v, b); return v; } #line 290 "./src/stdlib/msgpack.am" if (b >= 224LL) { #line 291 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); Amalgame_Compiler_JsonValue_SetInt(v, b - 256LL); return v; } #line 294 "./src/stdlib/msgpack.am" if ((b >= 160LL) && (b <= 191LL)) { #line 295 "./src/stdlib/msgpack.am" i64 n = b - 160LL; #line 296 "./src/stdlib/msgpack.am" return Amalgame_Compiler_MsgPack_ReadStrInto(c, n); } #line 299 "./src/stdlib/msgpack.am" if ((b >= 144LL) && (b <= 159LL)) { #line 300 "./src/stdlib/msgpack.am" i64 n = b - 144LL; #line 301 "./src/stdlib/msgpack.am" return Amalgame_Compiler_MsgPack_ReadArrayInto(c, n); } #line 304 "./src/stdlib/msgpack.am" if ((b >= 128LL) && (b <= 143LL)) { #line 305 "./src/stdlib/msgpack.am" i64 n = b - 128LL; #line 306 "./src/stdlib/msgpack.am" return Amalgame_Compiler_MsgPack_ReadMapInto(c, n); } #line 309 "./src/stdlib/msgpack.am" if (b == 208LL) { #line 310 "./src/stdlib/msgpack.am" i64 raw = Amalgame_Compiler_MsgPackCursor_Read(c); #line 311 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 312 "./src/stdlib/msgpack.am" if (raw >= 128LL) { Amalgame_Compiler_JsonValue_SetInt(v, raw - 256LL); } else { Amalgame_Compiler_JsonValue_SetInt(v, raw); } #line 313 "./src/stdlib/msgpack.am" return v; } #line 315 "./src/stdlib/msgpack.am" if (b == 209LL) { #line 316 "./src/stdlib/msgpack.am" i64 hi = Amalgame_Compiler_MsgPackCursor_Read(c); #line 317 "./src/stdlib/msgpack.am" i64 lo = Amalgame_Compiler_MsgPackCursor_Read(c); #line 318 "./src/stdlib/msgpack.am" i64 raw = (hi * 256LL) + lo; #line 319 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 320 "./src/stdlib/msgpack.am" if (raw >= 32768LL) { Amalgame_Compiler_JsonValue_SetInt(v, raw - 65536LL); } else { Amalgame_Compiler_JsonValue_SetInt(v, raw); } #line 321 "./src/stdlib/msgpack.am" return v; } #line 323 "./src/stdlib/msgpack.am" if (b == 210LL) { #line 324 "./src/stdlib/msgpack.am" i64 b3 = Amalgame_Compiler_MsgPackCursor_Read(c); #line 325 "./src/stdlib/msgpack.am" i64 b2 = Amalgame_Compiler_MsgPackCursor_Read(c); #line 326 "./src/stdlib/msgpack.am" i64 b1 = Amalgame_Compiler_MsgPackCursor_Read(c); #line 327 "./src/stdlib/msgpack.am" i64 b0 = Amalgame_Compiler_MsgPackCursor_Read(c); #line 328 "./src/stdlib/msgpack.am" i64 raw = (((b3 * 16777216LL) + (b2 * 65536LL)) + (b1 * 256LL)) + b0; #line 329 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 330 "./src/stdlib/msgpack.am" if (raw >= 2147483648LL) { Amalgame_Compiler_JsonValue_SetInt(v, raw - 4294967296LL); } else { Amalgame_Compiler_JsonValue_SetInt(v, raw); } #line 331 "./src/stdlib/msgpack.am" return v; } #line 338 "./src/stdlib/msgpack.am" if (b == 211LL) { #line 339 "./src/stdlib/msgpack.am" i64 b7 = Amalgame_Compiler_MsgPackCursor_Read(c); #line 340 "./src/stdlib/msgpack.am" i64 b6 = Amalgame_Compiler_MsgPackCursor_Read(c); #line 341 "./src/stdlib/msgpack.am" i64 b5 = Amalgame_Compiler_MsgPackCursor_Read(c); #line 342 "./src/stdlib/msgpack.am" i64 b4 = Amalgame_Compiler_MsgPackCursor_Read(c); #line 343 "./src/stdlib/msgpack.am" i64 b3 = Amalgame_Compiler_MsgPackCursor_Read(c); #line 344 "./src/stdlib/msgpack.am" i64 b2 = Amalgame_Compiler_MsgPackCursor_Read(c); #line 345 "./src/stdlib/msgpack.am" i64 b1 = Amalgame_Compiler_MsgPackCursor_Read(c); #line 346 "./src/stdlib/msgpack.am" i64 b0 = Amalgame_Compiler_MsgPackCursor_Read(c); #line 347 "./src/stdlib/msgpack.am" i64 raw = (((((((b7 << 56LL) | (b6 << 48LL)) | (b5 << 40LL)) | (b4 << 32LL)) | (b3 << 24LL)) | (b2 << 16LL)) | (b1 << 8LL)) | b0; #line 348 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 349 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue_SetInt(v, raw); #line 350 "./src/stdlib/msgpack.am" return v; } #line 353 "./src/stdlib/msgpack.am" if (b == 217LL) { #line 354 "./src/stdlib/msgpack.am" i64 n = Amalgame_Compiler_MsgPackCursor_Read(c); #line 355 "./src/stdlib/msgpack.am" return Amalgame_Compiler_MsgPack_ReadStrInto(c, n); } #line 357 "./src/stdlib/msgpack.am" if (b == 218LL) { #line 358 "./src/stdlib/msgpack.am" i64 hi = Amalgame_Compiler_MsgPackCursor_Read(c); #line 359 "./src/stdlib/msgpack.am" i64 lo = Amalgame_Compiler_MsgPackCursor_Read(c); #line 360 "./src/stdlib/msgpack.am" return Amalgame_Compiler_MsgPack_ReadStrInto(c, (hi * 256LL) + lo); } #line 363 "./src/stdlib/msgpack.am" if (b == 220LL) { #line 364 "./src/stdlib/msgpack.am" i64 hi = Amalgame_Compiler_MsgPackCursor_Read(c); #line 365 "./src/stdlib/msgpack.am" i64 lo = Amalgame_Compiler_MsgPackCursor_Read(c); #line 366 "./src/stdlib/msgpack.am" return Amalgame_Compiler_MsgPack_ReadArrayInto(c, (hi * 256LL) + lo); } #line 369 "./src/stdlib/msgpack.am" if (b == 222LL) { #line 370 "./src/stdlib/msgpack.am" i64 hi = Amalgame_Compiler_MsgPackCursor_Read(c); #line 371 "./src/stdlib/msgpack.am" i64 lo = Amalgame_Compiler_MsgPackCursor_Read(c); #line 372 "./src/stdlib/msgpack.am" return Amalgame_Compiler_MsgPack_ReadMapInto(c, (hi * 256LL) + lo); } #line 375 "./src/stdlib/msgpack.am" return Amalgame_Compiler_JsonValue_new(); } static Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_ReadStrInto(Amalgame_Compiler_MsgPackCursor* c, i64 n) { #line 379 "./src/stdlib/msgpack.am" code_string table = Amalgame_Compiler_MsgPack_AsciiTable(); #line 380 "./src/stdlib/msgpack.am" code_string s = ""; #line 381 "./src/stdlib/msgpack.am" for (i64 i = 0LL; i < n; i++) { #line 382 "./src/stdlib/msgpack.am" i64 b = Amalgame_Compiler_MsgPackCursor_Read(c); #line 383 "./src/stdlib/msgpack.am" if ((b >= 32LL) && (b <= 126LL)) { #line 384 "./src/stdlib/msgpack.am" s = (code_string_concat(s, String_Substring(table, b - 32LL, 1LL))); } else { #line 386 "./src/stdlib/msgpack.am" s = (code_string_concat(s, "?")); } } #line 389 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 390 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue_SetString(v, s); #line 391 "./src/stdlib/msgpack.am" return v; } static Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_ReadArrayInto(Amalgame_Compiler_MsgPackCursor* c, i64 n) { #line 395 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 396 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue_SetArray(v, AmalgameList_new()); #line 397 "./src/stdlib/msgpack.am" for (i64 i = 0LL; i < n; i++) { #line 398 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue* elem = Amalgame_Compiler_MsgPack_DecodeOne(c); #line 399 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue_AppendItem(v, elem); } #line 401 "./src/stdlib/msgpack.am" return v; } static Amalgame_Compiler_JsonValue* Amalgame_Compiler_MsgPack_ReadMapInto(Amalgame_Compiler_MsgPackCursor* c, i64 n) { #line 405 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue* v = Amalgame_Compiler_JsonValue_new(); #line 406 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue_SetObject(v, AmalgameList_new(), AmalgameList_new()); #line 407 "./src/stdlib/msgpack.am" for (i64 i = 0LL; i < n; i++) { #line 408 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue* k = Amalgame_Compiler_MsgPack_DecodeOne(c); #line 409 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue* val = Amalgame_Compiler_MsgPack_DecodeOne(c); #line 410 "./src/stdlib/msgpack.am" Amalgame_Compiler_JsonValue_AppendEntry(v, Amalgame_Compiler_JsonValue_AsString(k), val); } #line 412 "./src/stdlib/msgpack.am" return v; } struct _Amalgame_Compiler_BuildInfo { }; code_string Amalgame_Compiler_BuildInfo_GitRev(); code_string Amalgame_Compiler_BuildInfo_BuildDate(); Amalgame_Compiler_BuildInfo* Amalgame_Compiler_BuildInfo_new() { Amalgame_Compiler_BuildInfo* self = (Amalgame_Compiler_BuildInfo*) GC_MALLOC(sizeof(Amalgame_Compiler_BuildInfo)); return self; } code_string Amalgame_Compiler_BuildInfo_GitRev() { #line 26 "./src/stdlib/amc_buildinfo.am" return "fd80bc5f"; } code_string Amalgame_Compiler_BuildInfo_BuildDate() { #line 30 "./src/stdlib/amc_buildinfo.am" return "2026-06-22T23:20:44Z"; } struct _Amalgame_Compiler_LspServer { AmalgameList* DocUris; AmalgameList* Docs; code_string CachedRoot; AmalgameList* CachedSiblingPaths; AmalgameList* CachedSiblingProgs; Amalgame_Compiler_FullResolver* CachedResolver; code_string CachedResolverPath; }; static void Amalgame_Compiler_LspServer_InvalidateResolverCache(Amalgame_Compiler_LspServer* self); i64 Amalgame_Compiler_LspServer_Run(Amalgame_Compiler_LspServer* self); static void Amalgame_Compiler_LspServer_UpsertDoc(Amalgame_Compiler_LspServer* self, code_string uri, code_string text); static void Amalgame_Compiler_LspServer_RemoveDoc(Amalgame_Compiler_LspServer* self, code_string uri); static code_string Amalgame_Compiler_LspServer_LookupDoc(Amalgame_Compiler_LspServer* self, code_string uri); static code_string Amalgame_Compiler_LspServer_ReadMessage(Amalgame_Compiler_LspServer* self); code_string Amalgame_Compiler_LspServer_Cr(); static void Amalgame_Compiler_LspServer_Send(Amalgame_Compiler_LspServer* self, code_string body); static void Amalgame_Compiler_LspServer_SendInit(Amalgame_Compiler_LspServer* self, i64 id); static void Amalgame_Compiler_LspServer_SendShutdown(Amalgame_Compiler_LspServer* self, i64 id); static void Amalgame_Compiler_LspServer_PublishDiagnostics(Amalgame_Compiler_LspServer* self, code_string uri, code_string source); static Amalgame_Compiler_FullResolver* Amalgame_Compiler_LspServer_BuildWorkspaceResolver(Amalgame_Compiler_LspServer* self, code_string path, Amalgame_Compiler_AstNode* prog); code_string Amalgame_Compiler_LspServer_DetectLocalPackageClass(code_string root); static void Amalgame_Compiler_LspServer_DeclareDependencyClasses(Amalgame_Compiler_FullResolver* resolver, code_string root); static code_string Amalgame_Compiler_LspServer_TomlFirstString(code_string line); static void Amalgame_Compiler_LspServer_DeclareManifestClasses(Amalgame_Compiler_FullResolver* resolver, code_string manifestPath); static void Amalgame_Compiler_LspServer_DeclareQuotedNames(Amalgame_Compiler_FullResolver* resolver, code_string line); static code_bool Amalgame_Compiler_LspServer_HasCachedSibling(Amalgame_Compiler_LspServer* self, code_string path); static void Amalgame_Compiler_LspServer_EnsureWorkspaceCache(Amalgame_Compiler_LspServer* self, code_string currentPath); code_string Amalgame_Compiler_LspServer_FindWorkspaceRoot(code_string startPath); code_string Amalgame_Compiler_LspServer_Dirname(code_string path); code_bool Amalgame_Compiler_LspServer_ProjectIsEmbedded(code_string startPath); static code_string Amalgame_Compiler_LspServer_Compile(Amalgame_Compiler_LspServer* self, code_string uri, code_string source); static void Amalgame_Compiler_LspServer_HandleHover(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static void Amalgame_Compiler_LspServer_HandleSignatureHelp(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static void Amalgame_Compiler_LspServer_SendNullResult(Amalgame_Compiler_LspServer* self, i64 id); static void Amalgame_Compiler_LspServer_HandleDefinition(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static code_string Amalgame_Compiler_LspServer_BareTypeName(code_string raw); static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindEnclosingMethod(Amalgame_Compiler_AstNode* prog, i64 targetLine); static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_LookupLocalInMethod(Amalgame_Compiler_AstNode* method, code_string name); static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindLocalVarDecl(Amalgame_Compiler_AstNode* node, code_string name); static void Amalgame_Compiler_LspServer_HandleDocumentSymbol(Amalgame_Compiler_LspServer* self, i64 id, code_string uri); static code_string Amalgame_Compiler_LspServer_SymbolForDecl(Amalgame_Compiler_AstNode* decl); static code_string Amalgame_Compiler_LspServer_SymbolEntry(code_string name, i64 kind, i64 line, i64 col, code_string childrenJson); static void Amalgame_Compiler_LspServer_HandleReferences(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static void Amalgame_Compiler_LspServer_CollectReferences(Amalgame_Compiler_AstNode* node, code_string target, code_string filePath, AmalgameList* out); static code_string Amalgame_Compiler_LspServer_LocationJson(code_string filePath, i64 line, i64 col, code_string name); static void Amalgame_Compiler_LspServer_HandleDocumentHighlight(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static void Amalgame_Compiler_LspServer_CollectHighlights(Amalgame_Compiler_AstNode* node, code_string target, AmalgameList* out); static code_string Amalgame_Compiler_LspServer_HighlightJson(i64 line, i64 col, code_string name); static void Amalgame_Compiler_LspServer_HandleRename(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character, code_string newName); static void Amalgame_Compiler_LspServer_CollectRenameEdits(Amalgame_Compiler_AstNode* node, code_string target, code_string newName, AmalgameList* out); static code_string Amalgame_Compiler_LspServer_TextEditJson(i64 line, i64 col, code_string oldName, code_string newName); static void Amalgame_Compiler_LspServer_HandlePrepareRename(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static void Amalgame_Compiler_LspServer_HandlePrepareCallHierarchy(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character); static void Amalgame_Compiler_LspServer_HandleIncomingCalls(Amalgame_Compiler_LspServer* self, i64 id, Amalgame_Compiler_JsonValue* item); static void Amalgame_Compiler_LspServer_HandleOutgoingCalls(Amalgame_Compiler_LspServer* self, i64 id, Amalgame_Compiler_JsonValue* item); static void Amalgame_Compiler_LspServer_CollectCallSitesForName(Amalgame_Compiler_AstNode* node, code_string target, AmalgameList* out); static void Amalgame_Compiler_LspServer_CollectOutgoingCalls(Amalgame_Compiler_AstNode* node, AmalgameList* names, AmalgameList* rangesOut); static code_string Amalgame_Compiler_LspServer_CallHierarchyItemJson(Amalgame_Compiler_AstNode* method, code_string filePath); static code_string Amalgame_Compiler_LspServer_RangeJsonForName(i64 line, i64 col, code_string name); static void Amalgame_Compiler_LspServer_HandleInlayHint(Amalgame_Compiler_LspServer* self, i64 id, code_string uri); static void Amalgame_Compiler_LspServer_CollectInlayHints(Amalgame_Compiler_AstNode* node, Amalgame_Compiler_TypeChecker* tc, AmalgameList* out); static code_string Amalgame_Compiler_LspServer_InlayHintJson(i64 line, i64 col, code_string name, code_string typeStr); static void Amalgame_Compiler_LspServer_HandleCodeAction(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 startLine, i64 startChr, i64 endLine, i64 endChr); static void Amalgame_Compiler_LspServer_CollectPackageInstallSuggestions(Amalgame_Compiler_LspServer* self, Amalgame_Compiler_FullResolver* resolver, code_string uri, code_string path, i64 sLine, i64 eLine, AmalgameList* out); static code_string Amalgame_Compiler_LspServer_AmcBinaryPath(); static code_string Amalgame_Compiler_LspServer_PackageInstallActionJson(code_string pkgName, code_string pkgTag, code_string pkgDesc, code_string symName); static code_string Amalgame_Compiler_LspServer_SegmentToNamespacePart(code_string seg); static code_string Amalgame_Compiler_LspServer_InferNamespaceFromUrl(code_string url); static i64 Amalgame_Compiler_LspServer_FindImportInsertionLine(code_string source); static code_bool Amalgame_Compiler_LspServer_HasImport(code_string source, code_string ns); static code_string Amalgame_Compiler_LspServer_PackageImportActionJson(code_string uri, i64 insertLine, code_string ns, code_string symName); static void Amalgame_Compiler_LspServer_CollectAnnotationFixes(Amalgame_Compiler_AstNode* node, Amalgame_Compiler_TypeChecker* tc, code_string uri, i64 sLine, i64 eLine, AmalgameList* out); static code_string Amalgame_Compiler_LspServer_AnnotationFixJson(code_string uri, i64 line, i64 col, code_string name, code_string typeStr); static void Amalgame_Compiler_LspServer_HandleFoldingRange(Amalgame_Compiler_LspServer* self, i64 id, code_string uri); static code_string Amalgame_Compiler_LspServer_FoldEntry(i64 startLine, i64 endLine, code_string kind); static void Amalgame_Compiler_LspServer_HandleWorkspaceSymbol(Amalgame_Compiler_LspServer* self, i64 id, code_string query); static code_string Amalgame_Compiler_LspServer_WorkspaceSymbolEntry(Amalgame_Compiler_AstNode* decl, code_string path, code_string lowerQuery); static void Amalgame_Compiler_LspServer_SendDefinitionLocation(Amalgame_Compiler_LspServer* self, i64 id, code_string path, i64 line, i64 col, code_string name); static code_string Amalgame_Compiler_LspServer_PercentEncodePath(code_string path); static code_bool Amalgame_Compiler_LspServer_IsUriSafeChar(code_string c); static i64 Amalgame_Compiler_LspServer_AsciiCodeOf(code_string c); static void Amalgame_Compiler_LspServer_HandleCompletion(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 chr); static code_bool Amalgame_Compiler_LspServer_IsImportLine(code_string source, i64 line); static void Amalgame_Compiler_LspServer_SendImportCompletion(Amalgame_Compiler_LspServer* self, i64 id); static code_bool Amalgame_Compiler_LspServer_ContainsString(AmalgameList* xs, code_string needle); static AmalgameList* Amalgame_Compiler_LspServer_BundledNamespaces(); static void Amalgame_Compiler_LspServer_SendGlobalCompletion(Amalgame_Compiler_LspServer* self, i64 id, Amalgame_Compiler_FullResolver* resolver); static void Amalgame_Compiler_LspServer_SendMemberCompletion(Amalgame_Compiler_LspServer* self, i64 id, Amalgame_Compiler_FullResolver* resolver, code_string typeName); code_string Amalgame_Compiler_LspServer_ReceiverTypeAt(code_string source, i64 line, i64 chr, Amalgame_Compiler_FullResolver* resolver); static code_string Amalgame_Compiler_LspServer_EnclosingClassAt(code_string source, i64 before); static code_bool Amalgame_Compiler_LspServer_MatchKeywordAt(code_string source, i64 pos, code_string kw); static code_string Amalgame_Compiler_LspServer_ScanLocalDeclType(code_string source, i64 before, code_string ident); static code_string Amalgame_Compiler_LspServer_ExtractTypeAfterDecl(code_string source, i64 start, i64 n); static code_bool Amalgame_Compiler_LspServer_IsIdentChar(code_string c); static void Amalgame_Compiler_LspServer_SendEmptyCompletion(Amalgame_Compiler_LspServer* self, i64 id); code_string Amalgame_Compiler_LspServer_DiagnosticFromResolver(code_string source, Amalgame_Compiler_ResolverError* e); code_string Amalgame_Compiler_LspServer_DiagnosticFromTc(code_string source, Amalgame_Compiler_TypeError* e); static code_string Amalgame_Compiler_LspServer_DiagnosticBody(code_string source, i64 line, i64 col, code_string msg); static i64 Amalgame_Compiler_LspServer_TokenEndCol(code_string source, i64 line, i64 col); static code_bool Amalgame_Compiler_LspServer_IsWordChar(code_string ch); code_string Amalgame_Compiler_LspServer_UriToPath(code_string uri); static code_string Amalgame_Compiler_LspServer_PercentDecode(code_string s); static i64 Amalgame_Compiler_LspServer_HexDigit(code_string c); Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindNodeAtPosition(Amalgame_Compiler_AstNode* root, i64 line, i64 col); code_string Amalgame_Compiler_LspServer_FormatMethodSignatureMarkdown(Amalgame_Compiler_AstNode* method); Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindMethodDeclByName(Amalgame_Compiler_AstNode* prog, code_string methodName); Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindCallAtPosition(Amalgame_Compiler_AstNode* root, i64 line, i64 col); static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindCallWalk(Amalgame_Compiler_AstNode* node, i64 line, i64 col, Amalgame_Compiler_AstNode* best); code_string Amalgame_Compiler_LspServer_CallCalleeName(Amalgame_Compiler_AstNode* call); static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindNodeWalk(Amalgame_Compiler_AstNode* node, i64 line, i64 col, Amalgame_Compiler_AstNode* best); static code_bool Amalgame_Compiler_LspServer_NodeCovers(Amalgame_Compiler_AstNode* node, i64 line, i64 col); Amalgame_Compiler_LspServer* Amalgame_Compiler_LspServer_new() { Amalgame_Compiler_LspServer* self = (Amalgame_Compiler_LspServer*) GC_MALLOC(sizeof(Amalgame_Compiler_LspServer)); #line 73 "./src/lsp.am" self->DocUris = AmalgameList_new(); #line 74 "./src/lsp.am" self->Docs = AmalgameList_new(); #line 75 "./src/lsp.am" self->CachedRoot = ""; #line 76 "./src/lsp.am" self->CachedSiblingPaths = AmalgameList_new(); #line 77 "./src/lsp.am" self->CachedSiblingProgs = AmalgameList_new(); #line 78 "./src/lsp.am" self->CachedResolver = NULL; #line 79 "./src/lsp.am" self->CachedResolverPath = ""; return self; } static void Amalgame_Compiler_LspServer_InvalidateResolverCache(Amalgame_Compiler_LspServer* self) { #line 86 "./src/lsp.am" self->CachedResolver = NULL; #line 87 "./src/lsp.am" self->CachedResolverPath = ""; } i64 Amalgame_Compiler_LspServer_Run(Amalgame_Compiler_LspServer* self) { #line 97 "./src/lsp.am" while (1) { #line 98 "./src/lsp.am" code_string body = Amalgame_Compiler_LspServer_ReadMessage(self); #line 99 "./src/lsp.am" if (String_Length(body) == 0LL) { return 0LL; } #line 100 "./src/lsp.am" Amalgame_Compiler_JsonResult* parsed = Amalgame_Compiler_Json_Parse(body); #line 101 "./src/lsp.am" if (!parsed->Ok) { continue; } #line 102 "./src/lsp.am" Amalgame_Compiler_JsonValue* root = parsed->Value; #line 103 "./src/lsp.am" code_string method = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(root, "method")); #line 104 "./src/lsp.am" i64 id = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(root, "id")); #line 105 "./src/lsp.am" Amalgame_Compiler_JsonValue* params = Amalgame_Compiler_JsonValue_Get(root, "params"); #line 106 "./src/lsp.am" Amalgame_Compiler_JsonValue* td = Amalgame_Compiler_JsonValue_Get(params, "textDocument"); #line 107 "./src/lsp.am" Amalgame_Compiler_JsonValue* pos = Amalgame_Compiler_JsonValue_Get(params, "position"); #line 109 "./src/lsp.am" if (code_string_equals(method, "initialize")) { #line 110 "./src/lsp.am" Amalgame_Compiler_LspServer_SendInit(self, id); } else if (code_string_equals(method, "shutdown")) { #line 112 "./src/lsp.am" Amalgame_Compiler_LspServer_SendShutdown(self, id); } else if (code_string_equals(method, "exit")) { #line 114 "./src/lsp.am" return 0LL; } else if (code_string_equals(method, "textDocument/didOpen")) { #line 116 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 117 "./src/lsp.am" code_string txt = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "text")); #line 118 "./src/lsp.am" Amalgame_Compiler_LspServer_UpsertDoc(self, uri, txt); #line 129 "./src/lsp.am" code_string opened = Amalgame_Compiler_LspServer_UriToPath(uri); #line 130 "./src/lsp.am" if (((String_Length(self->CachedRoot) > 0LL) && String_StartsWith(opened, self->CachedRoot)) && !Amalgame_Compiler_LspServer_HasCachedSibling(self, opened)) { #line 133 "./src/lsp.am" self->CachedRoot = ""; #line 134 "./src/lsp.am" self->CachedSiblingPaths = AmalgameList_new(); #line 135 "./src/lsp.am" self->CachedSiblingProgs = AmalgameList_new(); } #line 137 "./src/lsp.am" Amalgame_Compiler_LspServer_InvalidateResolverCache(self); #line 138 "./src/lsp.am" Amalgame_Compiler_LspServer_PublishDiagnostics(self, uri, txt); } else if (code_string_equals(method, "textDocument/didChange")) { #line 142 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 143 "./src/lsp.am" Amalgame_Compiler_JsonValue* changes = Amalgame_Compiler_JsonValue_Get(params, "contentChanges"); #line 144 "./src/lsp.am" code_string txt = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(Amalgame_Compiler_JsonValue_At(changes, 0LL), "text")); #line 145 "./src/lsp.am" Amalgame_Compiler_LspServer_UpsertDoc(self, uri, txt); #line 146 "./src/lsp.am" Amalgame_Compiler_LspServer_InvalidateResolverCache(self); #line 147 "./src/lsp.am" Amalgame_Compiler_LspServer_PublishDiagnostics(self, uri, txt); } else if (code_string_equals(method, "textDocument/didClose")) { #line 149 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 150 "./src/lsp.am" Amalgame_Compiler_LspServer_RemoveDoc(self, uri); #line 151 "./src/lsp.am" Amalgame_Compiler_LspServer_InvalidateResolverCache(self); } else if (((code_string_equals(method, "workspace/didCreateFiles")) || (code_string_equals(method, "workspace/didDeleteFiles"))) || (code_string_equals(method, "workspace/didRenameFiles"))) { #line 157 "./src/lsp.am" self->CachedRoot = ""; #line 158 "./src/lsp.am" self->CachedSiblingPaths = AmalgameList_new(); #line 159 "./src/lsp.am" self->CachedSiblingProgs = AmalgameList_new(); #line 160 "./src/lsp.am" Amalgame_Compiler_LspServer_InvalidateResolverCache(self); } else if (code_string_equals(method, "textDocument/hover")) { #line 162 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 163 "./src/lsp.am" i64 line = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "line")); #line 164 "./src/lsp.am" i64 chr = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "character")); #line 165 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleHover(self, id, uri, line, chr); } else if (code_string_equals(method, "textDocument/signatureHelp")) { #line 167 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 168 "./src/lsp.am" i64 line = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "line")); #line 169 "./src/lsp.am" i64 chr = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "character")); #line 170 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleSignatureHelp(self, id, uri, line, chr); } else if (code_string_equals(method, "textDocument/completion")) { #line 172 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 173 "./src/lsp.am" i64 line = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "line")); #line 174 "./src/lsp.am" i64 chr = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "character")); #line 175 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleCompletion(self, id, uri, line, chr); } else if (((code_string_equals(method, "textDocument/definition")) || (code_string_equals(method, "textDocument/declaration"))) || (code_string_equals(method, "textDocument/typeDefinition"))) { #line 182 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 183 "./src/lsp.am" i64 line = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "line")); #line 184 "./src/lsp.am" i64 chr = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "character")); #line 185 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleDefinition(self, id, uri, line, chr); } else if (code_string_equals(method, "textDocument/documentSymbol")) { #line 187 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 188 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleDocumentSymbol(self, id, uri); } else if (code_string_equals(method, "workspace/symbol")) { #line 190 "./src/lsp.am" code_string q = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(params, "query")); #line 191 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleWorkspaceSymbol(self, id, q); } else if (code_string_equals(method, "textDocument/references")) { #line 193 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 194 "./src/lsp.am" i64 line = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "line")); #line 195 "./src/lsp.am" i64 chr = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "character")); #line 196 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleReferences(self, id, uri, line, chr); } else if (code_string_equals(method, "textDocument/documentHighlight")) { #line 198 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 199 "./src/lsp.am" i64 line = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "line")); #line 200 "./src/lsp.am" i64 chr = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "character")); #line 201 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleDocumentHighlight(self, id, uri, line, chr); } else if (code_string_equals(method, "textDocument/rename")) { #line 203 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 204 "./src/lsp.am" i64 line = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "line")); #line 205 "./src/lsp.am" i64 chr = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "character")); #line 206 "./src/lsp.am" code_string newName = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(params, "newName")); #line 207 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleRename(self, id, uri, line, chr, newName); } else if (code_string_equals(method, "textDocument/prepareRename")) { #line 209 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 210 "./src/lsp.am" i64 line = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "line")); #line 211 "./src/lsp.am" i64 chr = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "character")); #line 212 "./src/lsp.am" Amalgame_Compiler_LspServer_HandlePrepareRename(self, id, uri, line, chr); } else if (code_string_equals(method, "textDocument/prepareCallHierarchy")) { #line 214 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 215 "./src/lsp.am" i64 line = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "line")); #line 216 "./src/lsp.am" i64 chr = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(pos, "character")); #line 217 "./src/lsp.am" Amalgame_Compiler_LspServer_HandlePrepareCallHierarchy(self, id, uri, line, chr); } else if (code_string_equals(method, "callHierarchy/incomingCalls")) { #line 219 "./src/lsp.am" Amalgame_Compiler_JsonValue* item = Amalgame_Compiler_JsonValue_Get(params, "item"); #line 220 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleIncomingCalls(self, id, item); } else if (code_string_equals(method, "callHierarchy/outgoingCalls")) { #line 222 "./src/lsp.am" Amalgame_Compiler_JsonValue* item = Amalgame_Compiler_JsonValue_Get(params, "item"); #line 223 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleOutgoingCalls(self, id, item); } else if (code_string_equals(method, "textDocument/inlayHint")) { #line 225 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 226 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleInlayHint(self, id, uri); } else if (code_string_equals(method, "textDocument/codeAction")) { #line 228 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 229 "./src/lsp.am" Amalgame_Compiler_JsonValue* range = Amalgame_Compiler_JsonValue_Get(params, "range"); #line 230 "./src/lsp.am" Amalgame_Compiler_JsonValue* rs = Amalgame_Compiler_JsonValue_Get(range, "start"); #line 231 "./src/lsp.am" Amalgame_Compiler_JsonValue* re = Amalgame_Compiler_JsonValue_Get(range, "end"); #line 232 "./src/lsp.am" i64 sl = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(rs, "line")); #line 233 "./src/lsp.am" i64 sc = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(rs, "character")); #line 234 "./src/lsp.am" i64 el = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(re, "line")); #line 235 "./src/lsp.am" i64 ec = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(re, "character")); #line 236 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleCodeAction(self, id, uri, sl, sc, el, ec); } else if (code_string_equals(method, "textDocument/foldingRange")) { #line 238 "./src/lsp.am" code_string uri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(td, "uri")); #line 239 "./src/lsp.am" Amalgame_Compiler_LspServer_HandleFoldingRange(self, id, uri); } } #line 245 "./src/lsp.am" return 0LL; } static void Amalgame_Compiler_LspServer_UpsertDoc(Amalgame_Compiler_LspServer* self, code_string uri, code_string text) { #line 253 "./src/lsp.am" i64 n = AmalgameList_count(self->DocUris); #line 254 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 255 "./src/lsp.am" code_string u = (code_string)AmalgameList_get(self->DocUris, i); #line 256 "./src/lsp.am" if (code_string_equals(u, uri)) { #line 257 "./src/lsp.am" AmalgameList_removeAt(self->DocUris, i); #line 258 "./src/lsp.am" AmalgameList_removeAt(self->Docs, i); #line 259 "./src/lsp.am" AmalgameList_add(self->DocUris, (void*)(intptr_t)(uri)); #line 260 "./src/lsp.am" AmalgameList_add(self->Docs, (void*)(intptr_t)(text)); #line 261 "./src/lsp.am" return; } } #line 264 "./src/lsp.am" AmalgameList_add(self->DocUris, (void*)(intptr_t)(uri)); #line 265 "./src/lsp.am" AmalgameList_add(self->Docs, (void*)(intptr_t)(text)); } static void Amalgame_Compiler_LspServer_RemoveDoc(Amalgame_Compiler_LspServer* self, code_string uri) { #line 269 "./src/lsp.am" i64 n = AmalgameList_count(self->DocUris); #line 270 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 271 "./src/lsp.am" code_string u = (code_string)AmalgameList_get(self->DocUris, i); #line 272 "./src/lsp.am" if (code_string_equals(u, uri)) { #line 273 "./src/lsp.am" AmalgameList_removeAt(self->DocUris, i); #line 274 "./src/lsp.am" AmalgameList_removeAt(self->Docs, i); #line 275 "./src/lsp.am" return; } } } static code_string Amalgame_Compiler_LspServer_LookupDoc(Amalgame_Compiler_LspServer* self, code_string uri) { #line 284 "./src/lsp.am" i64 n = AmalgameList_count(self->DocUris); #line 285 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 286 "./src/lsp.am" code_string u = (code_string)AmalgameList_get(self->DocUris, i); #line 287 "./src/lsp.am" if (code_string_equals(u, uri)) { return (code_string)AmalgameList_get(self->Docs, i); } } #line 289 "./src/lsp.am" return ""; } static code_string Amalgame_Compiler_LspServer_ReadMessage(Amalgame_Compiler_LspServer* self) { #line 296 "./src/lsp.am" i64 contentLen = 0LL; #line 297 "./src/lsp.am" code_bool sawAnyHeader = 0; #line 298 "./src/lsp.am" while (1) { #line 299 "./src/lsp.am" code_string raw = Console_ReadLine(); #line 300 "./src/lsp.am" code_string line = String_TrimEnd(raw); #line 301 "./src/lsp.am" if (String_Length(line) == 0LL) { #line 303 "./src/lsp.am" if ((String_Length(raw) == 0LL) && !sawAnyHeader) { #line 304 "./src/lsp.am" return ""; } #line 307 "./src/lsp.am" break; } #line 309 "./src/lsp.am" sawAnyHeader = 1; #line 310 "./src/lsp.am" if (String_StartsWith(line, "Content-Length:")) { #line 311 "./src/lsp.am" i64 lineLen = String_Length(line); #line 312 "./src/lsp.am" code_string rest = String_Substring(line, 15LL, lineLen - 15LL); #line 313 "./src/lsp.am" contentLen = String_ToInt(String_Trim(rest)); } } #line 316 "./src/lsp.am" if (contentLen <= 0LL) { return ""; } #line 317 "./src/lsp.am" return Console_ReadBytes(contentLen); } code_string Amalgame_Compiler_LspServer_Cr() { #line 324 "./src/lsp.am" return String_FromByte(13LL); } static void Amalgame_Compiler_LspServer_Send(Amalgame_Compiler_LspServer* self, code_string body) { #line 330 "./src/lsp.am" i64 n = String_Length(body); #line 331 "./src/lsp.am" code_string crlf = code_string_concat(Amalgame_Compiler_LspServer_Cr(), "\n"); #line 332 "./src/lsp.am" Console_Write(code_string_concat((code_string_concat((code_string_concat("Content-Length: ", String_FromInt(n))), crlf)), crlf)); #line 333 "./src/lsp.am" Console_Write(body); #line 334 "./src/lsp.am" Console_Flush(); } static void Amalgame_Compiler_LspServer_SendInit(Amalgame_Compiler_LspServer* self, i64 id) { #line 376 "./src/lsp.am" code_string body = code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"capabilities\":{\"textDocumentSync\":1,\"hoverProvider\":true,\"definitionProvider\":true,\"declarationProvider\":true,\"typeDefinitionProvider\":true,\"documentSymbolProvider\":true,\"workspaceSymbolProvider\":true,\"referencesProvider\":true,\"documentHighlightProvider\":true,\"renameProvider\":{\"prepareProvider\":true},\"callHierarchyProvider\":true,\"inlayHintProvider\":true,\"codeActionProvider\":true,\"foldingRangeProvider\":true,\"completionProvider\":{\"triggerCharacters\":[\".\"]},\"signatureHelpProvider\":{\"triggerCharacters\":[\"(\",\",\"]},\"workspace\":{\"fileOperations\":{\"didCreate\":{\"filters\":[{\"pattern\":{\"glob\":\"**/*.am\"}}]},\"didDelete\":{\"filters\":[{\"pattern\":{\"glob\":\"**/*.am\"}}]},\"didRename\":{\"filters\":[{\"pattern\":{\"glob\":\"**/*.am\"}}]}}}}}}"); #line 377 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_SendShutdown(Amalgame_Compiler_LspServer* self, i64 id) { #line 381 "./src/lsp.am" code_string body = code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":null}"); #line 382 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_PublishDiagnostics(Amalgame_Compiler_LspServer* self, code_string uri, code_string source) { #line 386 "./src/lsp.am" code_string diags = Amalgame_Compiler_LspServer_Compile(self, uri, source); #line 387 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"uri\":\"", Amalgame_Compiler_Json_EscapeString(uri))), "\",\"diagnostics\":")), diags)), "}}"); #line 388 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static Amalgame_Compiler_FullResolver* Amalgame_Compiler_LspServer_BuildWorkspaceResolver(Amalgame_Compiler_LspServer* self, code_string path, Amalgame_Compiler_AstNode* prog) { #line 412 "./src/lsp.am" if ((self->CachedResolver != NULL) && (code_string_equals(self->CachedResolverPath, path))) { #line 413 "./src/lsp.am" return self->CachedResolver; } #line 415 "./src/lsp.am" Amalgame_Compiler_FullResolver* resolver = Amalgame_Compiler_FullResolver_new(); #line 416 "./src/lsp.am" AmalgameList_add(resolver->Programs, (void*)(intptr_t)(prog)); #line 417 "./src/lsp.am" Amalgame_Compiler_LspServer_EnsureWorkspaceCache(self, path); #line 425 "./src/lsp.am" i64 n = AmalgameList_count(self->CachedSiblingPaths); #line 426 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 427 "./src/lsp.am" code_string cachedPath = (code_string)AmalgameList_get(self->CachedSiblingPaths, i); #line 428 "./src/lsp.am" if (code_string_equals(cachedPath, path)) { continue; } #line 429 "./src/lsp.am" AmalgameList_add(resolver->Programs, (void*)(intptr_t)((Amalgame_Compiler_AstNode*)AmalgameList_get(self->CachedSiblingProgs, i))); } #line 441 "./src/lsp.am" code_string pkgClass = Amalgame_Compiler_LspServer_DetectLocalPackageClass(self->CachedRoot); #line 442 "./src/lsp.am" if (String_Length(pkgClass) > 0LL) { #line 443 "./src/lsp.am" Amalgame_Compiler_FullResolver_DeclareGlobal(resolver, pkgClass, "type", 0); } #line 452 "./src/lsp.am" Amalgame_Compiler_LspServer_DeclareDependencyClasses(resolver, self->CachedRoot); #line 453 "./src/lsp.am" Amalgame_Compiler_FullResolver_ResolvePrograms(resolver); #line 455 "./src/lsp.am" self->CachedResolver = resolver; #line 456 "./src/lsp.am" self->CachedResolverPath = path; #line 457 "./src/lsp.am" return resolver; } code_string Amalgame_Compiler_LspServer_DetectLocalPackageClass(code_string root) { #line 468 "./src/lsp.am" if (String_Length(root) == 0LL) { return ""; } #line 469 "./src/lsp.am" code_string manifestPath = code_string_concat(root, "/amalgame.toml"); #line 470 "./src/lsp.am" if (!File_Exists(manifestPath)) { return ""; } #line 471 "./src/lsp.am" code_string src = File_ReadAll(manifestPath); #line 472 "./src/lsp.am" AmalgameList* lines = String_Split(src, "\n"); #line 473 "./src/lsp.am" i64 nLines = AmalgameList_count(lines); #line 474 "./src/lsp.am" code_bool inStdlib = 0; #line 475 "./src/lsp.am" i64 li = 0LL; #line 476 "./src/lsp.am" while (li < nLines) { #line 477 "./src/lsp.am" code_string line = (code_string)AmalgameList_get(lines, li); #line 478 "./src/lsp.am" code_string trimmed = String_TrimStart(line); #line 480 "./src/lsp.am" if (String_StartsWith(trimmed, "[stdlib]")) { #line 481 "./src/lsp.am" inStdlib = 1; } else if (String_StartsWith(trimmed, "[") && !String_StartsWith(trimmed, "[stdlib.")) { #line 483 "./src/lsp.am" inStdlib = 0; } #line 485 "./src/lsp.am" if (inStdlib && String_StartsWith(trimmed, "class")) { #line 487 "./src/lsp.am" i64 eq = String_IndexOf(trimmed, "="); #line 488 "./src/lsp.am" if (eq > 0LL) { #line 489 "./src/lsp.am" code_string rhs = String_Trim(String_From(trimmed, eq + 1LL)); #line 490 "./src/lsp.am" i64 q1 = String_IndexOf(rhs, "\""); #line 491 "./src/lsp.am" if (q1 >= 0LL) { #line 492 "./src/lsp.am" code_string after = String_From(rhs, q1 + 1LL); #line 493 "./src/lsp.am" i64 q2 = String_IndexOf(after, "\""); #line 494 "./src/lsp.am" if (q2 > 0LL) { #line 495 "./src/lsp.am" return String_Substring(after, 0LL, q2); } } } } #line 500 "./src/lsp.am" li = (li + 1LL); } #line 502 "./src/lsp.am" return ""; } static void Amalgame_Compiler_LspServer_DeclareDependencyClasses(Amalgame_Compiler_FullResolver* resolver, code_string root) { #line 512 "./src/lsp.am" if (String_Length(root) == 0LL) { return; } #line 513 "./src/lsp.am" code_string lockPath = code_string_concat(root, "/amalgame.lock"); #line 514 "./src/lsp.am" if (!File_Exists(lockPath)) { return; } #line 515 "./src/lsp.am" code_string home = Amalgame_Compiler_PackageRegistry_AmalgameHome(); #line 516 "./src/lsp.am" AmalgameList* lines = String_Split(File_ReadAll(lockPath), "\n"); #line 517 "./src/lsp.am" i64 n = AmalgameList_count(lines); #line 518 "./src/lsp.am" code_string git = ""; #line 519 "./src/lsp.am" code_string tag = ""; #line 520 "./src/lsp.am" code_string rev = ""; #line 521 "./src/lsp.am" i64 li = 0LL; #line 522 "./src/lsp.am" while (li < n) { #line 523 "./src/lsp.am" code_string t = String_Trim((code_string)AmalgameList_get(lines, li)); #line 524 "./src/lsp.am" if (String_StartsWith(t, "git")) { #line 525 "./src/lsp.am" git = Amalgame_Compiler_LspServer_TomlFirstString(t); } else if (String_StartsWith(t, "tag")) { #line 527 "./src/lsp.am" tag = Amalgame_Compiler_LspServer_TomlFirstString(t); } else if (String_StartsWith(t, "rev")) { #line 530 "./src/lsp.am" rev = Amalgame_Compiler_LspServer_TomlFirstString(t); #line 531 "./src/lsp.am" if (((String_Length(git) > 0LL) && (String_Length(tag) > 0LL)) && (String_Length(rev) > 0LL)) { #line 532 "./src/lsp.am" code_string manifest = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(home, "/.amalgame/packages/")), git)), "/")), tag)), "_")), rev)), "/amalgame.toml"); #line 533 "./src/lsp.am" Amalgame_Compiler_LspServer_DeclareManifestClasses(resolver, manifest); } #line 535 "./src/lsp.am" git = ""; #line 536 "./src/lsp.am" tag = ""; #line 537 "./src/lsp.am" rev = ""; } #line 539 "./src/lsp.am" li = (li + 1LL); } } static code_string Amalgame_Compiler_LspServer_TomlFirstString(code_string line) { #line 546 "./src/lsp.am" i64 q1 = String_IndexOf(line, "\""); #line 547 "./src/lsp.am" if (q1 < 0LL) { return ""; } #line 548 "./src/lsp.am" code_string after = String_From(line, q1 + 1LL); #line 549 "./src/lsp.am" i64 q2 = String_IndexOf(after, "\""); #line 550 "./src/lsp.am" if (q2 < 0LL) { return ""; } #line 551 "./src/lsp.am" return String_Substring(after, 0LL, q2); } static void Amalgame_Compiler_LspServer_DeclareManifestClasses(Amalgame_Compiler_FullResolver* resolver, code_string manifestPath) { #line 558 "./src/lsp.am" if (!File_Exists(manifestPath)) { return; } #line 559 "./src/lsp.am" AmalgameList* lines = String_Split(File_ReadAll(manifestPath), "\n"); #line 560 "./src/lsp.am" i64 n = AmalgameList_count(lines); #line 561 "./src/lsp.am" code_bool inStdlib = 0; #line 562 "./src/lsp.am" code_bool inArray = 0; #line 563 "./src/lsp.am" i64 li = 0LL; #line 564 "./src/lsp.am" while (li < n) { #line 565 "./src/lsp.am" code_string t = String_TrimStart((code_string)AmalgameList_get(lines, li)); #line 566 "./src/lsp.am" if (inArray) { #line 567 "./src/lsp.am" Amalgame_Compiler_LspServer_DeclareQuotedNames(resolver, t); #line 568 "./src/lsp.am" if (String_IndexOf(t, "]") >= 0LL) { inArray = 0; } #line 569 "./src/lsp.am" li = (li + 1LL); #line 570 "./src/lsp.am" continue; } #line 572 "./src/lsp.am" if (String_StartsWith(t, "[")) { #line 573 "./src/lsp.am" inStdlib = String_StartsWith(t, "[stdlib]"); } else if (inStdlib && String_StartsWith(t, "classes")) { #line 575 "./src/lsp.am" Amalgame_Compiler_LspServer_DeclareQuotedNames(resolver, t); #line 576 "./src/lsp.am" if (String_IndexOf(t, "]") < 0LL) { inArray = 1; } } else if (inStdlib && String_StartsWith(t, "class")) { #line 578 "./src/lsp.am" Amalgame_Compiler_LspServer_DeclareQuotedNames(resolver, t); } #line 580 "./src/lsp.am" li = (li + 1LL); } } static void Amalgame_Compiler_LspServer_DeclareQuotedNames(Amalgame_Compiler_FullResolver* resolver, code_string line) { #line 586 "./src/lsp.am" code_string s = line; #line 587 "./src/lsp.am" while (1) { #line 588 "./src/lsp.am" i64 q1 = String_IndexOf(s, "\""); #line 589 "./src/lsp.am" if (q1 < 0LL) { return; } #line 590 "./src/lsp.am" code_string after = String_From(s, q1 + 1LL); #line 591 "./src/lsp.am" i64 q2 = String_IndexOf(after, "\""); #line 592 "./src/lsp.am" if (q2 < 0LL) { return; } #line 593 "./src/lsp.am" code_string name = String_Substring(after, 0LL, q2); #line 594 "./src/lsp.am" if (String_Length(name) > 0LL) { Amalgame_Compiler_FullResolver_DeclareGlobal(resolver, name, "type", 0); } #line 595 "./src/lsp.am" s = String_From(after, q2 + 1LL); } } static code_bool Amalgame_Compiler_LspServer_HasCachedSibling(Amalgame_Compiler_LspServer* self, code_string path) { #line 603 "./src/lsp.am" i64 n = AmalgameList_count(self->CachedSiblingPaths); #line 604 "./src/lsp.am" code_bool found = 0; #line 605 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 606 "./src/lsp.am" if (code_string_equals((code_string)AmalgameList_get(self->CachedSiblingPaths, i), path)) { found = 1; } } #line 608 "./src/lsp.am" return found; } static void Amalgame_Compiler_LspServer_EnsureWorkspaceCache(Amalgame_Compiler_LspServer* self, code_string currentPath) { #line 621 "./src/lsp.am" code_string root = Amalgame_Compiler_LspServer_FindWorkspaceRoot(currentPath); #line 622 "./src/lsp.am" if (String_Length(root) == 0LL) { return; } #line 623 "./src/lsp.am" if ((code_string_equals(root, self->CachedRoot)) && (AmalgameList_count(self->CachedSiblingPaths) > 0LL)) { return; } #line 624 "./src/lsp.am" self->CachedRoot = root; #line 625 "./src/lsp.am" self->CachedSiblingPaths = AmalgameList_new(); #line 626 "./src/lsp.am" self->CachedSiblingProgs = AmalgameList_new(); #line 630 "./src/lsp.am" code_string findCmd = code_string_concat((code_string_concat("find ", root)), " -name '*.am' -type f 2>/dev/null"); #line 631 "./src/lsp.am" AmalgameProcessResult* result = Process_RunCapture(findCmd); #line 632 "./src/lsp.am" if (result->Exit != 0LL) { return; } #line 633 "./src/lsp.am" AmalgameList* lines = String_Split(String_Trim(result->Stdout), "\n"); #line 634 "./src/lsp.am" i64 n = AmalgameList_count(lines); #line 635 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 636 "./src/lsp.am" code_string path = String_Trim((code_string)AmalgameList_get(lines, i)); #line 637 "./src/lsp.am" if (String_Length(path) == 0LL) { continue; } #line 638 "./src/lsp.am" if (!File_Exists(path)) { continue; } #line 639 "./src/lsp.am" code_string src = File_ReadAll(path); #line 640 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(src, path); #line 641 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 642 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 643 "./src/lsp.am" Amalgame_Compiler_AstNode* p = Amalgame_Compiler_Parser_Parse(par); #line 644 "./src/lsp.am" p->Str2 = path; #line 645 "./src/lsp.am" AmalgameList_add(self->CachedSiblingPaths, (void*)(intptr_t)(path)); #line 646 "./src/lsp.am" AmalgameList_add(self->CachedSiblingProgs, (void*)(intptr_t)(p)); } } code_string Amalgame_Compiler_LspServer_FindWorkspaceRoot(code_string startPath) { #line 671 "./src/lsp.am" code_string dir = Amalgame_Compiler_LspServer_Dirname(startPath); #line 672 "./src/lsp.am" code_string initialDir = dir; #line 673 "./src/lsp.am" for (i64 i = 0LL; i < 8LL; i++) { #line 674 "./src/lsp.am" if (String_Length(dir) == 0LL) { return initialDir; } #line 675 "./src/lsp.am" if (File_Exists(code_string_concat(dir, "/.git"))) { return dir; } #line 676 "./src/lsp.am" if (File_Exists(code_string_concat(dir, "/amalgame.toml"))) { return dir; } #line 677 "./src/lsp.am" if (File_Exists(code_string_concat(dir, "/build_amc.sh"))) { return dir; } #line 678 "./src/lsp.am" if (File_Exists(code_string_concat(dir, "/package.json"))) { return dir; } #line 679 "./src/lsp.am" code_string parent = Amalgame_Compiler_LspServer_Dirname(dir); #line 680 "./src/lsp.am" if (code_string_equals(parent, dir)) { return initialDir; } #line 681 "./src/lsp.am" dir = parent; } #line 683 "./src/lsp.am" return initialDir; } code_string Amalgame_Compiler_LspServer_Dirname(code_string path) { #line 687 "./src/lsp.am" i64 last = String_LastIndexOf(path, "/"); #line 688 "./src/lsp.am" if (last <= 0LL) { return ""; } #line 689 "./src/lsp.am" return String_Substring(path, 0LL, last); } code_bool Amalgame_Compiler_LspServer_ProjectIsEmbedded(code_string startPath) { #line 698 "./src/lsp.am" code_string root = Amalgame_Compiler_LspServer_FindWorkspaceRoot(startPath); #line 699 "./src/lsp.am" code_string manifest = code_string_concat(root, "/amalgame.toml"); #line 700 "./src/lsp.am" if (!File_Exists(manifest)) { return 0; } #line 701 "./src/lsp.am" return String_Contains(File_ReadAll(manifest), "[target]"); } static code_string Amalgame_Compiler_LspServer_Compile(Amalgame_Compiler_LspServer* self, code_string uri, code_string source) { #line 711 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 712 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 713 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 714 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 715 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 716 "./src/lsp.am" prog->Str2 = path; #line 718 "./src/lsp.am" Amalgame_Compiler_FullResolver* resolver = Amalgame_Compiler_LspServer_BuildWorkspaceResolver(self, path, prog); #line 720 "./src/lsp.am" Amalgame_Compiler_TypeChecker* tc = Amalgame_Compiler_TypeChecker_new(resolver, path); #line 721 "./src/lsp.am" tc->Embedded = Amalgame_Compiler_LspServer_ProjectIsEmbedded(path); #line 722 "./src/lsp.am" Amalgame_Compiler_TypeChecker_Check(tc, prog); #line 724 "./src/lsp.am" code_string arr = "["; #line 725 "./src/lsp.am" code_bool first = 1; #line 726 "./src/lsp.am" i64 rn = AmalgameList_count(resolver->RawErrors); #line 727 "./src/lsp.am" for (i64 ri = 0LL; ri < rn; ri++) { #line 728 "./src/lsp.am" Amalgame_Compiler_ResolverError* e = (Amalgame_Compiler_ResolverError*)AmalgameList_get(resolver->RawErrors, ri); #line 729 "./src/lsp.am" if (!code_string_equals(e->Filename, path)) { continue; } #line 730 "./src/lsp.am" if (!first) { arr = (code_string_concat(arr, ",")); } #line 731 "./src/lsp.am" arr = (code_string_concat(arr, Amalgame_Compiler_LspServer_DiagnosticFromResolver(source, e))); #line 732 "./src/lsp.am" first = 0; } #line 734 "./src/lsp.am" i64 tn = AmalgameList_count(tc->Errors); #line 735 "./src/lsp.am" for (i64 ti = 0LL; ti < tn; ti++) { #line 736 "./src/lsp.am" Amalgame_Compiler_TypeError* te = (Amalgame_Compiler_TypeError*)AmalgameList_get(tc->Errors, ti); #line 737 "./src/lsp.am" if (!code_string_equals(te->Filename, path)) { continue; } #line 738 "./src/lsp.am" if (!first) { arr = (code_string_concat(arr, ",")); } #line 739 "./src/lsp.am" arr = (code_string_concat(arr, Amalgame_Compiler_LspServer_DiagnosticFromTc(source, te))); #line 740 "./src/lsp.am" first = 0; } #line 742 "./src/lsp.am" arr = (code_string_concat(arr, "]")); #line 743 "./src/lsp.am" return arr; } static void Amalgame_Compiler_LspServer_HandleHover(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character) { #line 749 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 750 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 751 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 752 "./src/lsp.am" return; } #line 754 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 755 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 756 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 757 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 758 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 759 "./src/lsp.am" prog->Str2 = path; #line 760 "./src/lsp.am" Amalgame_Compiler_FullResolver* resolver = Amalgame_Compiler_LspServer_BuildWorkspaceResolver(self, path, prog); #line 761 "./src/lsp.am" Amalgame_Compiler_TypeChecker* tc = Amalgame_Compiler_TypeChecker_new(resolver, path); #line 762 "./src/lsp.am" Amalgame_Compiler_TypeChecker_Check(tc, prog); #line 765 "./src/lsp.am" i64 targetLine = line + 1LL; #line 766 "./src/lsp.am" i64 targetCol = character + 1LL; #line 767 "./src/lsp.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_LspServer_FindNodeAtPosition(prog, targetLine, targetCol); #line 768 "./src/lsp.am" if (node == NULL) { #line 769 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 770 "./src/lsp.am" return; } #line 783 "./src/lsp.am" if (((String_Length(node->Name) > 0LL) && (node->Kind != Amalgame_Compiler_NodeKind_LITERAL_STRING)) && (node->Kind != Amalgame_Compiler_NodeKind_LITERAL_INT)) { #line 784 "./src/lsp.am" Amalgame_Compiler_AstNode* method = Amalgame_Compiler_LspServer_FindMethodDeclByName(prog, node->Name); #line 785 "./src/lsp.am" if (method != NULL) { #line 786 "./src/lsp.am" code_string sigMd = Amalgame_Compiler_LspServer_FormatMethodSignatureMarkdown(method); #line 787 "./src/lsp.am" code_string bodySig = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"contents\":{\"kind\":\"markdown\",\"value\":\"")), Amalgame_Compiler_Json_EscapeString(sigMd))), "\"}}}"); #line 788 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, bodySig); #line 789 "./src/lsp.am" return; } } #line 793 "./src/lsp.am" code_string typeStr = Amalgame_Compiler_TypeChecker_LookupNodeType(tc, node); #line 794 "./src/lsp.am" if ((code_string_equals(typeStr, "?")) || (String_Length(typeStr) == 0LL)) { #line 798 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 799 "./src/lsp.am" return; } #line 801 "./src/lsp.am" code_string content = code_string_concat((code_string_concat((code_string_concat((code_string_concat("**", node->Name)), "**: `")), typeStr)), "`"); #line 802 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"contents\":{\"kind\":\"markdown\",\"value\":\"")), Amalgame_Compiler_Json_EscapeString(content))), "\"}}}"); #line 803 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_HandleSignatureHelp(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character) { #line 827 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 828 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 829 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 830 "./src/lsp.am" return; } #line 832 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 833 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 834 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 835 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 836 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 837 "./src/lsp.am" prog->Str2 = path; #line 839 "./src/lsp.am" i64 targetLine = line + 1LL; #line 840 "./src/lsp.am" i64 targetCol = character + 1LL; #line 841 "./src/lsp.am" Amalgame_Compiler_AstNode* call = Amalgame_Compiler_LspServer_FindCallAtPosition(prog, targetLine, targetCol); #line 842 "./src/lsp.am" if (call == NULL) { #line 843 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 844 "./src/lsp.am" return; } #line 846 "./src/lsp.am" code_string calleeName = Amalgame_Compiler_LspServer_CallCalleeName(call); #line 847 "./src/lsp.am" if (String_Length(calleeName) == 0LL) { #line 848 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 849 "./src/lsp.am" return; } #line 851 "./src/lsp.am" Amalgame_Compiler_AstNode* method = Amalgame_Compiler_LspServer_FindMethodDeclByName(prog, calleeName); #line 852 "./src/lsp.am" if (method == NULL) { #line 853 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 854 "./src/lsp.am" return; } #line 860 "./src/lsp.am" code_string label = code_string_concat(method->Name, "("); #line 861 "./src/lsp.am" i64 pn = AmalgameList_count(method->Params); #line 862 "./src/lsp.am" AmalgameList* starts = AmalgameList_new(); #line 863 "./src/lsp.am" AmalgameList* ends = AmalgameList_new(); #line 864 "./src/lsp.am" for (i64 i = 0LL; i < pn; i++) { #line 865 "./src/lsp.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 866 "./src/lsp.am" if (i > 0LL) { label = (code_string_concat(label, ", ")); } #line 867 "./src/lsp.am" i64 startCol = String_Length(label); #line 868 "./src/lsp.am" code_string paramLabel = p->Name; #line 869 "./src/lsp.am" if (String_Length(p->Str) > 0LL) { #line 870 "./src/lsp.am" paramLabel = (code_string_concat((code_string_concat(paramLabel, ": ")), p->Str)); } #line 872 "./src/lsp.am" label = (code_string_concat(label, paramLabel)); #line 873 "./src/lsp.am" AmalgameList_add(starts, (void*)(intptr_t)(startCol)); #line 874 "./src/lsp.am" AmalgameList_add(ends, (void*)(intptr_t)(String_Length(label))); } #line 876 "./src/lsp.am" label = (code_string_concat(label, ")")); #line 877 "./src/lsp.am" if ((String_Length(method->Str) > 0LL) && (!code_string_equals(method->Str, "void"))) { #line 878 "./src/lsp.am" label = (code_string_concat((code_string_concat(label, ": ")), method->Str)); } #line 886 "./src/lsp.am" i64 active = 0LL; #line 887 "./src/lsp.am" i64 an = AmalgameList_count(call->Args); #line 888 "./src/lsp.am" for (i64 ai = 0LL; ai < an; ai++) { #line 889 "./src/lsp.am" Amalgame_Compiler_AstNode* a = (Amalgame_Compiler_AstNode*)AmalgameList_get(call->Args, ai); #line 894 "./src/lsp.am" if ((a->Line < targetLine) || ((a->Line == targetLine) && (a->Column < targetCol))) { #line 895 "./src/lsp.am" active = ai; } } #line 898 "./src/lsp.am" if (active > (pn - 1LL)) { active = (pn - 1LL); } #line 899 "./src/lsp.am" if (active < 0LL) { active = 0LL; } #line 904 "./src/lsp.am" code_string paramsJson = "["; #line 905 "./src/lsp.am" for (i64 i = 0LL; i < pn; i++) { #line 906 "./src/lsp.am" if (i > 0LL) { paramsJson = (code_string_concat(paramsJson, ",")); } #line 907 "./src/lsp.am" paramsJson = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(paramsJson, "{\"label\":[")), String_FromInt((i64)(intptr_t)AmalgameList_get(starts, i)))), ",")), String_FromInt((i64)(intptr_t)AmalgameList_get(ends, i)))), "]}")); } #line 909 "./src/lsp.am" paramsJson = (code_string_concat(paramsJson, "]")); #line 911 "./src/lsp.am" code_string result = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"signatures\":[{\"label\":\"", Amalgame_Compiler_Json_EscapeString(label))), "\",\"parameters\":")), paramsJson)), "}],\"activeSignature\":0,\"activeParameter\":")), String_FromInt(active))), "}"); #line 912 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":")), result)), "}"); #line 913 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_SendNullResult(Amalgame_Compiler_LspServer* self, i64 id) { #line 917 "./src/lsp.am" code_string body = code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":null}"); #line 918 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_HandleDefinition(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character) { #line 934 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 935 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 936 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 937 "./src/lsp.am" return; } #line 939 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 940 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 941 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 942 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 943 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 944 "./src/lsp.am" prog->Str2 = path; #line 945 "./src/lsp.am" Amalgame_Compiler_FullResolver* resolver = Amalgame_Compiler_LspServer_BuildWorkspaceResolver(self, path, prog); #line 947 "./src/lsp.am" i64 targetLine = line + 1LL; #line 948 "./src/lsp.am" i64 targetCol = character + 1LL; #line 949 "./src/lsp.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_LspServer_FindNodeAtPosition(prog, targetLine, targetCol); #line 950 "./src/lsp.am" if (node == NULL) { #line 951 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 952 "./src/lsp.am" return; } #line 955 "./src/lsp.am" Amalgame_Compiler_AstNode* enclosing = Amalgame_Compiler_LspServer_FindEnclosingMethod(prog, targetLine); #line 966 "./src/lsp.am" if ((node->Kind == Amalgame_Compiler_NodeKind_MEMBER) && (enclosing != NULL)) { #line 967 "./src/lsp.am" if ((node->Left != NULL) && (node->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 968 "./src/lsp.am" Amalgame_Compiler_AstNode* recv = Amalgame_Compiler_LspServer_LookupLocalInMethod(enclosing, node->Left->Name); #line 969 "./src/lsp.am" if (recv != NULL) { #line 970 "./src/lsp.am" code_string recvType = Amalgame_Compiler_LspServer_BareTypeName(recv->Str); #line 977 "./src/lsp.am" if ((String_Length(recvType) == 0LL) && (recv->Left != NULL)) { #line 978 "./src/lsp.am" if (recv->Left->Kind == Amalgame_Compiler_NodeKind_NEW_EXPR) { #line 979 "./src/lsp.am" recvType = recv->Left->Name; } } #line 982 "./src/lsp.am" if (String_Length(recvType) > 0LL) { #line 983 "./src/lsp.am" i64 nProgs2 = AmalgameList_count(resolver->Programs); #line 984 "./src/lsp.am" for (i64 i = 0LL; i < nProgs2; i++) { #line 985 "./src/lsp.am" Amalgame_Compiler_AstNode* p2 = (Amalgame_Compiler_AstNode*)AmalgameList_get(resolver->Programs, i); #line 986 "./src/lsp.am" i64 dc2 = AmalgameList_count(p2->Children); #line 987 "./src/lsp.am" for (i64 j = 0LL; j < dc2; j++) { #line 988 "./src/lsp.am" Amalgame_Compiler_AstNode* cls = (Amalgame_Compiler_AstNode*)AmalgameList_get(p2->Children, j); #line 989 "./src/lsp.am" if (cls->Kind != Amalgame_Compiler_NodeKind_CLASS_DECL) { continue; } #line 990 "./src/lsp.am" if (!code_string_equals(cls->Name, recvType)) { continue; } #line 991 "./src/lsp.am" i64 mc = AmalgameList_count(cls->Children); #line 992 "./src/lsp.am" for (i64 k2 = 0LL; k2 < mc; k2++) { #line 993 "./src/lsp.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, k2); #line 994 "./src/lsp.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 995 "./src/lsp.am" if ((mk != Amalgame_Compiler_NodeKind_METHOD_DECL) && (mk != Amalgame_Compiler_NodeKind_VAR_DECL)) { continue; } #line 996 "./src/lsp.am" if (!code_string_equals(m->Name, node->Name)) { continue; } #line 997 "./src/lsp.am" code_string memPath = p2->Str2; #line 998 "./src/lsp.am" if (String_Length(memPath) == 0LL) { memPath = path; } #line 999 "./src/lsp.am" Amalgame_Compiler_LspServer_SendDefinitionLocation(self, id, memPath, m->Line, m->Column, m->Name); #line 1000 "./src/lsp.am" return; } } } } } } } #line 1013 "./src/lsp.am" code_string lookup = node->Name; #line 1014 "./src/lsp.am" if (node->Kind == Amalgame_Compiler_NodeKind_MEMBER) { #line 1015 "./src/lsp.am" if ((node->Left != NULL) && (node->Left->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER)) { #line 1016 "./src/lsp.am" lookup = node->Left->Name; } } #line 1019 "./src/lsp.am" if (String_Length(lookup) == 0LL) { #line 1020 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 1021 "./src/lsp.am" return; } #line 1027 "./src/lsp.am" if (enclosing != NULL) { #line 1028 "./src/lsp.am" Amalgame_Compiler_AstNode* local = Amalgame_Compiler_LspServer_LookupLocalInMethod(enclosing, lookup); #line 1029 "./src/lsp.am" if (local != NULL) { #line 1030 "./src/lsp.am" Amalgame_Compiler_LspServer_SendDefinitionLocation(self, id, path, local->Line, local->Column, lookup); #line 1031 "./src/lsp.am" return; } } #line 1037 "./src/lsp.am" i64 nProgs = AmalgameList_count(resolver->Programs); #line 1038 "./src/lsp.am" for (i64 i = 0LL; i < nProgs; i++) { #line 1039 "./src/lsp.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(resolver->Programs, i); #line 1040 "./src/lsp.am" i64 nDecls = AmalgameList_count(p->Children); #line 1041 "./src/lsp.am" for (i64 j = 0LL; j < nDecls; j++) { #line 1042 "./src/lsp.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(p->Children, j); #line 1043 "./src/lsp.am" if (code_string_equals(decl->Name, lookup)) { #line 1044 "./src/lsp.am" code_string declPath = p->Str2; #line 1045 "./src/lsp.am" if (String_Length(declPath) == 0LL) { declPath = path; } #line 1046 "./src/lsp.am" Amalgame_Compiler_LspServer_SendDefinitionLocation(self, id, declPath, decl->Line, decl->Column, lookup); #line 1047 "./src/lsp.am" return; } } } #line 1052 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); } static code_string Amalgame_Compiler_LspServer_BareTypeName(code_string raw) { #line 1061 "./src/lsp.am" code_string t = raw; #line 1062 "./src/lsp.am" if (String_Length(t) == 0LL) { return ""; } #line 1063 "./src/lsp.am" if (String_EndsWith(t, "?")) { #line 1064 "./src/lsp.am" t = String_Substring(t, 0LL, String_Length(t) - 1LL); } #line 1066 "./src/lsp.am" if (String_EndsWith(t, "*")) { #line 1067 "./src/lsp.am" t = String_Substring(t, 0LL, String_Length(t) - 1LL); } #line 1069 "./src/lsp.am" i64 lt = String_IndexOf(t, "<"); #line 1070 "./src/lsp.am" if (lt >= 0LL) { #line 1071 "./src/lsp.am" t = String_Substring(t, 0LL, lt); } #line 1073 "./src/lsp.am" return t; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindEnclosingMethod(Amalgame_Compiler_AstNode* prog, i64 targetLine) { #line 1086 "./src/lsp.am" Amalgame_Compiler_AstNode* best = NULL; #line 1087 "./src/lsp.am" i64 bestLine = -1LL; #line 1088 "./src/lsp.am" i64 dc = AmalgameList_count(prog->Children); #line 1089 "./src/lsp.am" for (i64 i = 0LL; i < dc; i++) { #line 1090 "./src/lsp.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i); #line 1091 "./src/lsp.am" if (decl->Kind != Amalgame_Compiler_NodeKind_CLASS_DECL) { continue; } #line 1092 "./src/lsp.am" i64 mc = AmalgameList_count(decl->Children); #line 1093 "./src/lsp.am" for (i64 j = 0LL; j < mc; j++) { #line 1094 "./src/lsp.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(decl->Children, j); #line 1095 "./src/lsp.am" if (m->Kind != Amalgame_Compiler_NodeKind_METHOD_DECL) { continue; } #line 1096 "./src/lsp.am" if (m->Line > targetLine) { continue; } #line 1097 "./src/lsp.am" if (m->Line > bestLine) { #line 1098 "./src/lsp.am" bestLine = m->Line; #line 1099 "./src/lsp.am" best = m; } } } #line 1103 "./src/lsp.am" return best; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_LookupLocalInMethod(Amalgame_Compiler_AstNode* method, code_string name) { #line 1112 "./src/lsp.am" i64 pc = AmalgameList_count(method->Params); #line 1113 "./src/lsp.am" for (i64 i = 0LL; i < pc; i++) { #line 1114 "./src/lsp.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 1115 "./src/lsp.am" if (code_string_equals(p->Name, name)) { return p; } } #line 1117 "./src/lsp.am" return Amalgame_Compiler_LspServer_FindLocalVarDecl(method->Body, name); } static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindLocalVarDecl(Amalgame_Compiler_AstNode* node, code_string name) { #line 1125 "./src/lsp.am" if (node == NULL) { return NULL; } #line 1126 "./src/lsp.am" Amalgame_Compiler_NodeKind k = node->Kind; #line 1127 "./src/lsp.am" if ((k == Amalgame_Compiler_NodeKind_METHOD_DECL) || (k == Amalgame_Compiler_NodeKind_CLASS_DECL)) { return NULL; } #line 1128 "./src/lsp.am" if ((k == Amalgame_Compiler_NodeKind_VAR_DECL) && (code_string_equals(node->Name, name))) { return node; } #line 1132 "./src/lsp.am" if (node->Left != NULL) { #line 1133 "./src/lsp.am" Amalgame_Compiler_AstNode* r1 = Amalgame_Compiler_LspServer_FindLocalVarDecl(node->Left, name); #line 1134 "./src/lsp.am" if (r1 != NULL) { return r1; } } #line 1136 "./src/lsp.am" if (node->Right != NULL) { #line 1137 "./src/lsp.am" Amalgame_Compiler_AstNode* r2 = Amalgame_Compiler_LspServer_FindLocalVarDecl(node->Right, name); #line 1138 "./src/lsp.am" if (r2 != NULL) { return r2; } } #line 1140 "./src/lsp.am" if (node->Cond != NULL) { #line 1141 "./src/lsp.am" Amalgame_Compiler_AstNode* r3 = Amalgame_Compiler_LspServer_FindLocalVarDecl(node->Cond, name); #line 1142 "./src/lsp.am" if (r3 != NULL) { return r3; } } #line 1144 "./src/lsp.am" if (node->Body != NULL) { #line 1145 "./src/lsp.am" Amalgame_Compiler_AstNode* r4 = Amalgame_Compiler_LspServer_FindLocalVarDecl(node->Body, name); #line 1146 "./src/lsp.am" if (r4 != NULL) { return r4; } } #line 1148 "./src/lsp.am" if (node->Else != NULL) { #line 1149 "./src/lsp.am" Amalgame_Compiler_AstNode* r5 = Amalgame_Compiler_LspServer_FindLocalVarDecl(node->Else, name); #line 1150 "./src/lsp.am" if (r5 != NULL) { return r5; } } #line 1152 "./src/lsp.am" i64 cn = AmalgameList_count(node->Children); #line 1153 "./src/lsp.am" for (i64 i = 0LL; i < cn; i++) { #line 1154 "./src/lsp.am" Amalgame_Compiler_AstNode* r6 = Amalgame_Compiler_LspServer_FindLocalVarDecl((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Children, i), name); #line 1155 "./src/lsp.am" if (r6 != NULL) { return r6; } } #line 1157 "./src/lsp.am" return NULL; } static void Amalgame_Compiler_LspServer_HandleDocumentSymbol(Amalgame_Compiler_LspServer* self, i64 id, code_string uri) { #line 1181 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 1182 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 1183 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 1184 "./src/lsp.am" return; } #line 1186 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 1187 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 1188 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 1189 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 1190 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 1191 "./src/lsp.am" code_string json = "["; #line 1192 "./src/lsp.am" i64 n = AmalgameList_count(prog->Children); #line 1193 "./src/lsp.am" code_bool first = 1; #line 1194 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 1195 "./src/lsp.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i); #line 1196 "./src/lsp.am" code_string entry = Amalgame_Compiler_LspServer_SymbolForDecl(decl); #line 1197 "./src/lsp.am" if (String_Length(entry) > 0LL) { #line 1198 "./src/lsp.am" if (!first) { json = (code_string_concat(json, ",")); } #line 1199 "./src/lsp.am" json = (code_string_concat(json, entry)); #line 1200 "./src/lsp.am" first = 0; } } #line 1203 "./src/lsp.am" json = (code_string_concat(json, "]")); #line 1204 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":")), json)), "}"); #line 1205 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static code_string Amalgame_Compiler_LspServer_SymbolForDecl(Amalgame_Compiler_AstNode* decl) { #line 1212 "./src/lsp.am" Amalgame_Compiler_NodeKind k = decl->Kind; #line 1213 "./src/lsp.am" i64 kind = 0LL; #line 1214 "./src/lsp.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { kind = 5LL; } else if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) { #line 1215 "./src/lsp.am" kind = 10LL; } else { #line 1216 "./src/lsp.am" return ""; } #line 1217 "./src/lsp.am" code_string name = decl->Name; #line 1218 "./src/lsp.am" if (String_Length(name) == 0LL) { return ""; } #line 1219 "./src/lsp.am" code_string children = "["; #line 1220 "./src/lsp.am" code_bool firstChild = 1; #line 1221 "./src/lsp.am" i64 mc = AmalgameList_count(decl->Children); #line 1222 "./src/lsp.am" for (i64 i = 0LL; i < mc; i++) { #line 1223 "./src/lsp.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(decl->Children, i); #line 1224 "./src/lsp.am" Amalgame_Compiler_NodeKind mk = m->Kind; #line 1225 "./src/lsp.am" i64 ckind = 0LL; #line 1227 "./src/lsp.am" if (mk == Amalgame_Compiler_NodeKind_METHOD_DECL) { ckind = 6LL; } #line 1228 "./src/lsp.am" if (mk == Amalgame_Compiler_NodeKind_VAR_DECL) { ckind = 8LL; } #line 1231 "./src/lsp.am" if ((k == Amalgame_Compiler_NodeKind_ENUM_DECL) && (mk == Amalgame_Compiler_NodeKind_IDENTIFIER)) { ckind = 22LL; } #line 1232 "./src/lsp.am" if (ckind == 0LL) { continue; } #line 1233 "./src/lsp.am" if (String_Length(m->Name) == 0LL) { continue; } #line 1234 "./src/lsp.am" if (!firstChild) { children = (code_string_concat(children, ",")); } #line 1235 "./src/lsp.am" children = (code_string_concat(children, Amalgame_Compiler_LspServer_SymbolEntry(m->Name, ckind, m->Line, m->Column, "[]"))); #line 1236 "./src/lsp.am" firstChild = 0; } #line 1238 "./src/lsp.am" children = (code_string_concat(children, "]")); #line 1239 "./src/lsp.am" return Amalgame_Compiler_LspServer_SymbolEntry(name, kind, decl->Line, decl->Column, children); } static code_string Amalgame_Compiler_LspServer_SymbolEntry(code_string name, i64 kind, i64 line, i64 col, code_string childrenJson) { #line 1247 "./src/lsp.am" i64 lineLsp = line - 1LL; #line 1248 "./src/lsp.am" i64 colLsp = col - 1LL; #line 1249 "./src/lsp.am" i64 nameLen = String_Length(name); #line 1250 "./src/lsp.am" i64 endCol = colLsp + nameLen; #line 1251 "./src/lsp.am" code_string range = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"start\":{\"line\":", String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(colLsp))), "},\"end\":{\"line\":")), String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(endCol))), "}}"); #line 1252 "./src/lsp.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"name\":\"", Amalgame_Compiler_Json_EscapeString(name))), "\",\"kind\":")), String_FromInt(kind))), ",\"range\":")), range)), ",\"selectionRange\":")), range)), ",\"children\":")), childrenJson)), "}"); } static void Amalgame_Compiler_LspServer_HandleReferences(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character) { #line 1268 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 1269 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 1270 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 1271 "./src/lsp.am" return; } #line 1273 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 1274 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 1275 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 1276 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 1277 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 1278 "./src/lsp.am" prog->Str2 = path; #line 1279 "./src/lsp.am" Amalgame_Compiler_FullResolver* resolver = Amalgame_Compiler_LspServer_BuildWorkspaceResolver(self, path, prog); #line 1281 "./src/lsp.am" i64 targetLine = line + 1LL; #line 1282 "./src/lsp.am" i64 targetCol = character + 1LL; #line 1283 "./src/lsp.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_LspServer_FindNodeAtPosition(prog, targetLine, targetCol); #line 1284 "./src/lsp.am" if (node == NULL) { #line 1285 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 1286 "./src/lsp.am" return; } #line 1288 "./src/lsp.am" code_string target = node->Name; #line 1289 "./src/lsp.am" if (String_Length(target) == 0LL) { #line 1290 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 1291 "./src/lsp.am" return; } #line 1294 "./src/lsp.am" code_string json = "["; #line 1295 "./src/lsp.am" code_bool first = 1; #line 1296 "./src/lsp.am" i64 nProgs = AmalgameList_count(resolver->Programs); #line 1297 "./src/lsp.am" for (i64 i = 0LL; i < nProgs; i++) { #line 1298 "./src/lsp.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(resolver->Programs, i); #line 1299 "./src/lsp.am" code_string filePath = p->Str2; #line 1300 "./src/lsp.am" if (String_Length(filePath) == 0LL) { filePath = path; } #line 1301 "./src/lsp.am" AmalgameList* entries = AmalgameList_new(); #line 1302 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectReferences(p, target, filePath, entries); #line 1303 "./src/lsp.am" i64 ec = AmalgameList_count(entries); #line 1304 "./src/lsp.am" for (i64 j = 0LL; j < ec; j++) { #line 1305 "./src/lsp.am" if (!first) { json = (code_string_concat(json, ",")); } #line 1306 "./src/lsp.am" json = (code_string_concat(json, (code_string)AmalgameList_get(entries, j))); #line 1307 "./src/lsp.am" first = 0; } } #line 1310 "./src/lsp.am" json = (code_string_concat(json, "]")); #line 1311 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":")), json)), "}"); #line 1312 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_CollectReferences(Amalgame_Compiler_AstNode* node, code_string target, code_string filePath, AmalgameList* out) { #line 1322 "./src/lsp.am" if (node == NULL) { return; } #line 1323 "./src/lsp.am" Amalgame_Compiler_NodeKind k = node->Kind; #line 1324 "./src/lsp.am" if ((k == Amalgame_Compiler_NodeKind_IDENTIFIER) || (k == Amalgame_Compiler_NodeKind_MEMBER)) { #line 1325 "./src/lsp.am" if (code_string_equals(node->Name, target)) { #line 1326 "./src/lsp.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_LspServer_LocationJson(filePath, node->Line, node->Column, target))); } } #line 1335 "./src/lsp.am" if ((((k == Amalgame_Compiler_NodeKind_CLASS_DECL) || (k == Amalgame_Compiler_NodeKind_ENUM_DECL)) || (k == Amalgame_Compiler_NodeKind_METHOD_DECL)) || (k == Amalgame_Compiler_NodeKind_VAR_DECL)) { #line 1336 "./src/lsp.am" if (code_string_equals(node->Name, target)) { #line 1337 "./src/lsp.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_LspServer_LocationJson(filePath, node->Line, node->Column, target))); } } #line 1340 "./src/lsp.am" if (node->Left != NULL) { Amalgame_Compiler_LspServer_CollectReferences(node->Left, target, filePath, out); } #line 1341 "./src/lsp.am" if (node->Right != NULL) { Amalgame_Compiler_LspServer_CollectReferences(node->Right, target, filePath, out); } #line 1342 "./src/lsp.am" if (node->Cond != NULL) { Amalgame_Compiler_LspServer_CollectReferences(node->Cond, target, filePath, out); } #line 1343 "./src/lsp.am" if (node->Body != NULL) { Amalgame_Compiler_LspServer_CollectReferences(node->Body, target, filePath, out); } #line 1344 "./src/lsp.am" if (node->Else != NULL) { Amalgame_Compiler_LspServer_CollectReferences(node->Else, target, filePath, out); } #line 1345 "./src/lsp.am" i64 cn = AmalgameList_count(node->Children); #line 1346 "./src/lsp.am" for (i64 i = 0LL; i < cn; i++) { #line 1347 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectReferences((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Children, i), target, filePath, out); } #line 1349 "./src/lsp.am" i64 pn = AmalgameList_count(node->Params); #line 1350 "./src/lsp.am" for (i64 j = 0LL; j < pn; j++) { #line 1351 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectReferences((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Params, j), target, filePath, out); } #line 1353 "./src/lsp.am" i64 an = AmalgameList_count(node->Args); #line 1354 "./src/lsp.am" for (i64 k2 = 0LL; k2 < an; k2++) { #line 1355 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectReferences((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Args, k2), target, filePath, out); } } static code_string Amalgame_Compiler_LspServer_LocationJson(code_string filePath, i64 line, i64 col, code_string name) { #line 1363 "./src/lsp.am" i64 lineLsp = line - 1LL; #line 1364 "./src/lsp.am" i64 colLsp = col - 1LL; #line 1365 "./src/lsp.am" i64 nameLen = String_Length(name); #line 1366 "./src/lsp.am" i64 endCol = colLsp + nameLen; #line 1367 "./src/lsp.am" code_string uri = code_string_concat("file://", Amalgame_Compiler_LspServer_PercentEncodePath(filePath)); #line 1368 "./src/lsp.am" code_string range = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"start\":{\"line\":", String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(colLsp))), "},\"end\":{\"line\":")), String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(endCol))), "}}"); #line 1369 "./src/lsp.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"uri\":\"", Amalgame_Compiler_Json_EscapeString(uri))), "\",\"range\":")), range)), "}"); } static void Amalgame_Compiler_LspServer_HandleDocumentHighlight(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character) { #line 1381 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 1382 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 1383 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 1384 "./src/lsp.am" return; } #line 1386 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 1387 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 1388 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 1389 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 1390 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 1391 "./src/lsp.am" prog->Str2 = path; #line 1393 "./src/lsp.am" i64 targetLine = line + 1LL; #line 1394 "./src/lsp.am" i64 targetCol = character + 1LL; #line 1395 "./src/lsp.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_LspServer_FindNodeAtPosition(prog, targetLine, targetCol); #line 1396 "./src/lsp.am" if (node == NULL) { #line 1397 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 1398 "./src/lsp.am" return; } #line 1400 "./src/lsp.am" code_string target = node->Name; #line 1401 "./src/lsp.am" if (String_Length(target) == 0LL) { #line 1402 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 1403 "./src/lsp.am" return; } #line 1406 "./src/lsp.am" AmalgameList* entries = AmalgameList_new(); #line 1407 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectHighlights(prog, target, entries); #line 1408 "./src/lsp.am" code_string json = "["; #line 1409 "./src/lsp.am" code_bool first = 1; #line 1410 "./src/lsp.am" i64 ec = AmalgameList_count(entries); #line 1411 "./src/lsp.am" for (i64 j = 0LL; j < ec; j++) { #line 1412 "./src/lsp.am" if (!first) { json = (code_string_concat(json, ",")); } #line 1413 "./src/lsp.am" json = (code_string_concat(json, (code_string)AmalgameList_get(entries, j))); #line 1414 "./src/lsp.am" first = 0; } #line 1416 "./src/lsp.am" json = (code_string_concat(json, "]")); #line 1417 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":")), json)), "}")); } static void Amalgame_Compiler_LspServer_CollectHighlights(Amalgame_Compiler_AstNode* node, code_string target, AmalgameList* out) { #line 1425 "./src/lsp.am" if (node == NULL) { return; } #line 1426 "./src/lsp.am" Amalgame_Compiler_NodeKind k = node->Kind; #line 1427 "./src/lsp.am" if ((k == Amalgame_Compiler_NodeKind_IDENTIFIER) || (k == Amalgame_Compiler_NodeKind_MEMBER)) { #line 1428 "./src/lsp.am" if (code_string_equals(node->Name, target)) { #line 1429 "./src/lsp.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_LspServer_HighlightJson(node->Line, node->Column, target))); } } #line 1432 "./src/lsp.am" if ((((k == Amalgame_Compiler_NodeKind_CLASS_DECL) || (k == Amalgame_Compiler_NodeKind_ENUM_DECL)) || (k == Amalgame_Compiler_NodeKind_METHOD_DECL)) || (k == Amalgame_Compiler_NodeKind_VAR_DECL)) { #line 1433 "./src/lsp.am" if (code_string_equals(node->Name, target)) { #line 1434 "./src/lsp.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_LspServer_HighlightJson(node->Line, node->Column, target))); } } #line 1437 "./src/lsp.am" if (node->Left != NULL) { Amalgame_Compiler_LspServer_CollectHighlights(node->Left, target, out); } #line 1438 "./src/lsp.am" if (node->Right != NULL) { Amalgame_Compiler_LspServer_CollectHighlights(node->Right, target, out); } #line 1439 "./src/lsp.am" if (node->Cond != NULL) { Amalgame_Compiler_LspServer_CollectHighlights(node->Cond, target, out); } #line 1440 "./src/lsp.am" if (node->Body != NULL) { Amalgame_Compiler_LspServer_CollectHighlights(node->Body, target, out); } #line 1441 "./src/lsp.am" if (node->Else != NULL) { Amalgame_Compiler_LspServer_CollectHighlights(node->Else, target, out); } #line 1442 "./src/lsp.am" i64 cn = AmalgameList_count(node->Children); #line 1443 "./src/lsp.am" for (i64 i = 0LL; i < cn; i++) { #line 1444 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectHighlights((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Children, i), target, out); } #line 1446 "./src/lsp.am" i64 pn = AmalgameList_count(node->Params); #line 1447 "./src/lsp.am" for (i64 j = 0LL; j < pn; j++) { #line 1448 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectHighlights((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Params, j), target, out); } #line 1450 "./src/lsp.am" i64 an = AmalgameList_count(node->Args); #line 1451 "./src/lsp.am" for (i64 k2 = 0LL; k2 < an; k2++) { #line 1452 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectHighlights((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Args, k2), target, out); } } static code_string Amalgame_Compiler_LspServer_HighlightJson(i64 line, i64 col, code_string name) { #line 1459 "./src/lsp.am" i64 lineLsp = line - 1LL; #line 1460 "./src/lsp.am" i64 colLsp = col - 1LL; #line 1461 "./src/lsp.am" i64 endCol = colLsp + String_Length(name); #line 1462 "./src/lsp.am" code_string range = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"start\":{\"line\":", String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(colLsp))), "},\"end\":{\"line\":")), String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(endCol))), "}}"); #line 1463 "./src/lsp.am" return code_string_concat((code_string_concat("{\"range\":", range)), ",\"kind\":1}"); } static void Amalgame_Compiler_LspServer_HandleRename(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character, code_string newName) { #line 1488 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 1489 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 1490 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"changes\":{}}}")); #line 1491 "./src/lsp.am" return; } #line 1493 "./src/lsp.am" if (String_Length(newName) == 0LL) { #line 1494 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"changes\":{}}}")); #line 1495 "./src/lsp.am" return; } #line 1497 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 1498 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 1499 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 1500 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 1501 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 1502 "./src/lsp.am" prog->Str2 = path; #line 1503 "./src/lsp.am" Amalgame_Compiler_FullResolver* resolver = Amalgame_Compiler_LspServer_BuildWorkspaceResolver(self, path, prog); #line 1505 "./src/lsp.am" i64 targetLine = line + 1LL; #line 1506 "./src/lsp.am" i64 targetCol = character + 1LL; #line 1507 "./src/lsp.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_LspServer_FindNodeAtPosition(prog, targetLine, targetCol); #line 1508 "./src/lsp.am" if (node == NULL) { #line 1509 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"changes\":{}}}")); #line 1510 "./src/lsp.am" return; } #line 1512 "./src/lsp.am" code_string target = node->Name; #line 1513 "./src/lsp.am" if (String_Length(target) == 0LL) { #line 1514 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"changes\":{}}}")); #line 1515 "./src/lsp.am" return; } #line 1524 "./src/lsp.am" code_string changes = "{"; #line 1525 "./src/lsp.am" code_bool firstFile = 1; #line 1526 "./src/lsp.am" i64 nProgs = AmalgameList_count(resolver->Programs); #line 1527 "./src/lsp.am" for (i64 i = 0LL; i < nProgs; i++) { #line 1528 "./src/lsp.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(resolver->Programs, i); #line 1529 "./src/lsp.am" code_string filePath = p->Str2; #line 1530 "./src/lsp.am" if (String_Length(filePath) == 0LL) { filePath = path; } #line 1531 "./src/lsp.am" code_string fileUri = code_string_concat("file://", Amalgame_Compiler_LspServer_PercentEncodePath(filePath)); #line 1532 "./src/lsp.am" AmalgameList* edits = AmalgameList_new(); #line 1533 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectRenameEdits(p, target, newName, edits); #line 1534 "./src/lsp.am" i64 ec = AmalgameList_count(edits); #line 1535 "./src/lsp.am" if (ec == 0LL) { continue; } #line 1536 "./src/lsp.am" if (!firstFile) { changes = (code_string_concat(changes, ",")); } #line 1537 "./src/lsp.am" changes = (code_string_concat((code_string_concat((code_string_concat(changes, "\"")), Amalgame_Compiler_Json_EscapeString(fileUri))), "\":[")); #line 1538 "./src/lsp.am" for (i64 j = 0LL; j < ec; j++) { #line 1539 "./src/lsp.am" if (j > 0LL) { changes = (code_string_concat(changes, ",")); } #line 1540 "./src/lsp.am" changes = (code_string_concat(changes, (code_string)AmalgameList_get(edits, j))); } #line 1542 "./src/lsp.am" changes = (code_string_concat(changes, "]")); #line 1543 "./src/lsp.am" firstFile = 0; } #line 1545 "./src/lsp.am" changes = (code_string_concat(changes, "}")); #line 1546 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"changes\":")), changes)), "}}"); #line 1547 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_CollectRenameEdits(Amalgame_Compiler_AstNode* node, code_string target, code_string newName, AmalgameList* out) { #line 1555 "./src/lsp.am" if (node == NULL) { return; } #line 1556 "./src/lsp.am" Amalgame_Compiler_NodeKind k = node->Kind; #line 1563 "./src/lsp.am" code_bool matches = 0; #line 1564 "./src/lsp.am" if ((k == Amalgame_Compiler_NodeKind_IDENTIFIER) || (k == Amalgame_Compiler_NodeKind_MEMBER)) { matches = 1; } #line 1565 "./src/lsp.am" if ((k == Amalgame_Compiler_NodeKind_CLASS_DECL) || (k == Amalgame_Compiler_NodeKind_ENUM_DECL)) { matches = 1; } #line 1566 "./src/lsp.am" if ((k == Amalgame_Compiler_NodeKind_METHOD_DECL) || (k == Amalgame_Compiler_NodeKind_VAR_DECL)) { matches = 1; } #line 1567 "./src/lsp.am" if (k == Amalgame_Compiler_NodeKind_PARAM) { matches = 1; } #line 1568 "./src/lsp.am" if (matches && (code_string_equals(node->Name, target))) { #line 1569 "./src/lsp.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_LspServer_TextEditJson(node->Line, node->Column, target, newName))); } #line 1571 "./src/lsp.am" if (node->Left != NULL) { Amalgame_Compiler_LspServer_CollectRenameEdits(node->Left, target, newName, out); } #line 1572 "./src/lsp.am" if (node->Right != NULL) { Amalgame_Compiler_LspServer_CollectRenameEdits(node->Right, target, newName, out); } #line 1573 "./src/lsp.am" if (node->Cond != NULL) { Amalgame_Compiler_LspServer_CollectRenameEdits(node->Cond, target, newName, out); } #line 1574 "./src/lsp.am" if (node->Body != NULL) { Amalgame_Compiler_LspServer_CollectRenameEdits(node->Body, target, newName, out); } #line 1575 "./src/lsp.am" if (node->Else != NULL) { Amalgame_Compiler_LspServer_CollectRenameEdits(node->Else, target, newName, out); } #line 1576 "./src/lsp.am" i64 cn = AmalgameList_count(node->Children); #line 1577 "./src/lsp.am" for (i64 i = 0LL; i < cn; i++) { #line 1578 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectRenameEdits((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Children, i), target, newName, out); } #line 1580 "./src/lsp.am" i64 pn = AmalgameList_count(node->Params); #line 1581 "./src/lsp.am" for (i64 j = 0LL; j < pn; j++) { #line 1582 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectRenameEdits((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Params, j), target, newName, out); } #line 1584 "./src/lsp.am" i64 an = AmalgameList_count(node->Args); #line 1585 "./src/lsp.am" for (i64 k2 = 0LL; k2 < an; k2++) { #line 1586 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectRenameEdits((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Args, k2), target, newName, out); } } static code_string Amalgame_Compiler_LspServer_TextEditJson(i64 line, i64 col, code_string oldName, code_string newName) { #line 1593 "./src/lsp.am" i64 lineLsp = line - 1LL; #line 1594 "./src/lsp.am" i64 colLsp = col - 1LL; #line 1595 "./src/lsp.am" i64 oldLen = String_Length(oldName); #line 1596 "./src/lsp.am" i64 endCol = colLsp + oldLen; #line 1597 "./src/lsp.am" code_string range = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"start\":{\"line\":", String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(colLsp))), "},\"end\":{\"line\":")), String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(endCol))), "}}"); #line 1598 "./src/lsp.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"range\":", range)), ",\"newText\":\"")), Amalgame_Compiler_Json_EscapeString(newName))), "\"}"); } static void Amalgame_Compiler_LspServer_HandlePrepareRename(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character) { #line 1611 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 1612 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 1613 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 1614 "./src/lsp.am" return; } #line 1616 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 1617 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 1618 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 1619 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 1620 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 1622 "./src/lsp.am" i64 targetLine = line + 1LL; #line 1623 "./src/lsp.am" i64 targetCol = character + 1LL; #line 1624 "./src/lsp.am" Amalgame_Compiler_AstNode* node = Amalgame_Compiler_LspServer_FindNodeAtPosition(prog, targetLine, targetCol); #line 1625 "./src/lsp.am" if (node == NULL) { #line 1626 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 1627 "./src/lsp.am" return; } #line 1629 "./src/lsp.am" Amalgame_Compiler_NodeKind k = node->Kind; #line 1632 "./src/lsp.am" code_bool renameable = 0; #line 1633 "./src/lsp.am" if ((k == Amalgame_Compiler_NodeKind_IDENTIFIER) || (k == Amalgame_Compiler_NodeKind_MEMBER)) { renameable = 1; } #line 1634 "./src/lsp.am" if ((k == Amalgame_Compiler_NodeKind_CLASS_DECL) || (k == Amalgame_Compiler_NodeKind_ENUM_DECL)) { renameable = 1; } #line 1635 "./src/lsp.am" if ((k == Amalgame_Compiler_NodeKind_METHOD_DECL) || (k == Amalgame_Compiler_NodeKind_VAR_DECL)) { renameable = 1; } #line 1636 "./src/lsp.am" if (k == Amalgame_Compiler_NodeKind_PARAM) { renameable = 1; } #line 1637 "./src/lsp.am" if (!renameable) { #line 1638 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 1639 "./src/lsp.am" return; } #line 1641 "./src/lsp.am" code_string name = node->Name; #line 1642 "./src/lsp.am" if (String_Length(name) == 0LL) { #line 1643 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 1644 "./src/lsp.am" return; } #line 1646 "./src/lsp.am" i64 lineLsp = node->Line - 1LL; #line 1647 "./src/lsp.am" i64 colLsp = node->Column - 1LL; #line 1648 "./src/lsp.am" i64 nameLen = String_Length(name); #line 1649 "./src/lsp.am" i64 endCol = colLsp + nameLen; #line 1650 "./src/lsp.am" code_string range = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"start\":{\"line\":", String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(colLsp))), "},\"end\":{\"line\":")), String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(endCol))), "}}"); #line 1651 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"range\":")), range)), ",\"placeholder\":\"")), Amalgame_Compiler_Json_EscapeString(name))), "\"}}"); #line 1652 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_HandlePrepareCallHierarchy(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 character) { #line 1678 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 1679 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 1680 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 1681 "./src/lsp.am" return; } #line 1683 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 1684 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 1685 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 1686 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 1687 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 1688 "./src/lsp.am" i64 targetLine = line + 1LL; #line 1689 "./src/lsp.am" Amalgame_Compiler_AstNode* enclosing = Amalgame_Compiler_LspServer_FindEnclosingMethod(prog, targetLine); #line 1690 "./src/lsp.am" if (enclosing == NULL) { #line 1691 "./src/lsp.am" Amalgame_Compiler_LspServer_SendNullResult(self, id); #line 1692 "./src/lsp.am" return; } #line 1694 "./src/lsp.am" code_string item = Amalgame_Compiler_LspServer_CallHierarchyItemJson(enclosing, path); #line 1695 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[")), item)), "]}"); #line 1696 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_HandleIncomingCalls(Amalgame_Compiler_LspServer* self, i64 id, Amalgame_Compiler_JsonValue* item) { #line 1700 "./src/lsp.am" code_string target = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(item, "name")); #line 1701 "./src/lsp.am" if (String_Length(target) == 0LL) { #line 1702 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 1703 "./src/lsp.am" return; } #line 1707 "./src/lsp.am" code_string itemUri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(item, "uri")); #line 1708 "./src/lsp.am" code_string anchor = Amalgame_Compiler_LspServer_UriToPath(itemUri); #line 1713 "./src/lsp.am" code_string openSrc = Amalgame_Compiler_LspServer_LookupDoc(self, itemUri); #line 1714 "./src/lsp.am" Amalgame_Compiler_Lexer* lex2 = Amalgame_Compiler_Lexer_new(openSrc, anchor); #line 1715 "./src/lsp.am" AmalgameList* toks2 = Amalgame_Compiler_Lexer_Tokenize(lex2); #line 1716 "./src/lsp.am" Amalgame_Compiler_Parser* par2 = Amalgame_Compiler_Parser_new(toks2); #line 1717 "./src/lsp.am" Amalgame_Compiler_AstNode* openProg = Amalgame_Compiler_Parser_Parse(par2); #line 1718 "./src/lsp.am" openProg->Str2 = anchor; #line 1719 "./src/lsp.am" Amalgame_Compiler_FullResolver* resolver = Amalgame_Compiler_LspServer_BuildWorkspaceResolver(self, anchor, openProg); #line 1721 "./src/lsp.am" code_string json = "["; #line 1722 "./src/lsp.am" code_bool first = 1; #line 1723 "./src/lsp.am" i64 nProgs = AmalgameList_count(resolver->Programs); #line 1724 "./src/lsp.am" for (i64 i = 0LL; i < nProgs; i++) { #line 1725 "./src/lsp.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(resolver->Programs, i); #line 1726 "./src/lsp.am" code_string filePath = p->Str2; #line 1727 "./src/lsp.am" if (String_Length(filePath) == 0LL) { filePath = anchor; } #line 1728 "./src/lsp.am" i64 dc = AmalgameList_count(p->Children); #line 1729 "./src/lsp.am" for (i64 j = 0LL; j < dc; j++) { #line 1730 "./src/lsp.am" Amalgame_Compiler_AstNode* cls = (Amalgame_Compiler_AstNode*)AmalgameList_get(p->Children, j); #line 1731 "./src/lsp.am" if (cls->Kind != Amalgame_Compiler_NodeKind_CLASS_DECL) { continue; } #line 1732 "./src/lsp.am" i64 mc = AmalgameList_count(cls->Children); #line 1733 "./src/lsp.am" for (i64 k2 = 0LL; k2 < mc; k2++) { #line 1734 "./src/lsp.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, k2); #line 1735 "./src/lsp.am" if (m->Kind != Amalgame_Compiler_NodeKind_METHOD_DECL) { continue; } #line 1736 "./src/lsp.am" AmalgameList* ranges = AmalgameList_new(); #line 1737 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectCallSitesForName(m->Body, target, ranges); #line 1738 "./src/lsp.am" i64 rc = AmalgameList_count(ranges); #line 1739 "./src/lsp.am" if (rc == 0LL) { continue; } #line 1740 "./src/lsp.am" code_string rangesJson = "["; #line 1741 "./src/lsp.am" for (i64 ri = 0LL; ri < rc; ri++) { #line 1742 "./src/lsp.am" if (ri > 0LL) { rangesJson = (code_string_concat(rangesJson, ",")); } #line 1743 "./src/lsp.am" rangesJson = (code_string_concat(rangesJson, (code_string)AmalgameList_get(ranges, ri))); } #line 1745 "./src/lsp.am" rangesJson = (code_string_concat(rangesJson, "]")); #line 1746 "./src/lsp.am" code_string fromItem = Amalgame_Compiler_LspServer_CallHierarchyItemJson(m, filePath); #line 1747 "./src/lsp.am" if (!first) { json = (code_string_concat(json, ",")); } #line 1748 "./src/lsp.am" json = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(json, "{\"from\":")), fromItem)), ",\"fromRanges\":")), rangesJson)), "}")); #line 1749 "./src/lsp.am" first = 0; } } } #line 1753 "./src/lsp.am" json = (code_string_concat(json, "]")); #line 1754 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":")), json)), "}"); #line 1755 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_HandleOutgoingCalls(Amalgame_Compiler_LspServer* self, i64 id, Amalgame_Compiler_JsonValue* item) { #line 1759 "./src/lsp.am" code_string itemName = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(item, "name")); #line 1760 "./src/lsp.am" code_string itemUri = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(item, "uri")); #line 1761 "./src/lsp.am" if ((String_Length(itemName) == 0LL) || (String_Length(itemUri) == 0LL)) { #line 1762 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 1763 "./src/lsp.am" return; } #line 1768 "./src/lsp.am" Amalgame_Compiler_JsonValue* selRange = Amalgame_Compiler_JsonValue_Get(item, "selectionRange"); #line 1769 "./src/lsp.am" Amalgame_Compiler_JsonValue* selStart = Amalgame_Compiler_JsonValue_Get(selRange, "start"); #line 1770 "./src/lsp.am" i64 methodLine = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(selStart, "line")) + 1LL; #line 1772 "./src/lsp.am" code_string anchor = Amalgame_Compiler_LspServer_UriToPath(itemUri); #line 1773 "./src/lsp.am" code_string openSrc = Amalgame_Compiler_LspServer_LookupDoc(self, itemUri); #line 1774 "./src/lsp.am" Amalgame_Compiler_Lexer* lex2 = Amalgame_Compiler_Lexer_new(openSrc, anchor); #line 1775 "./src/lsp.am" AmalgameList* toks2 = Amalgame_Compiler_Lexer_Tokenize(lex2); #line 1776 "./src/lsp.am" Amalgame_Compiler_Parser* par2 = Amalgame_Compiler_Parser_new(toks2); #line 1777 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par2); #line 1778 "./src/lsp.am" prog->Str2 = anchor; #line 1779 "./src/lsp.am" Amalgame_Compiler_FullResolver* resolver = Amalgame_Compiler_LspServer_BuildWorkspaceResolver(self, anchor, prog); #line 1782 "./src/lsp.am" Amalgame_Compiler_AstNode* method = NULL; #line 1783 "./src/lsp.am" i64 nProgs = AmalgameList_count(resolver->Programs); #line 1784 "./src/lsp.am" for (i64 i = 0LL; i < nProgs; i++) { #line 1785 "./src/lsp.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(resolver->Programs, i); #line 1786 "./src/lsp.am" code_string pPath = p->Str2; #line 1787 "./src/lsp.am" if (!code_string_equals(pPath, anchor)) { continue; } #line 1788 "./src/lsp.am" i64 dc = AmalgameList_count(p->Children); #line 1789 "./src/lsp.am" for (i64 j = 0LL; j < dc; j++) { #line 1790 "./src/lsp.am" Amalgame_Compiler_AstNode* cls = (Amalgame_Compiler_AstNode*)AmalgameList_get(p->Children, j); #line 1791 "./src/lsp.am" if (cls->Kind != Amalgame_Compiler_NodeKind_CLASS_DECL) { continue; } #line 1792 "./src/lsp.am" i64 mc = AmalgameList_count(cls->Children); #line 1793 "./src/lsp.am" for (i64 k2 = 0LL; k2 < mc; k2++) { #line 1794 "./src/lsp.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, k2); #line 1795 "./src/lsp.am" if (m->Kind != Amalgame_Compiler_NodeKind_METHOD_DECL) { continue; } #line 1796 "./src/lsp.am" if (!code_string_equals(m->Name, itemName)) { continue; } #line 1797 "./src/lsp.am" if (m->Line != methodLine) { continue; } #line 1798 "./src/lsp.am" method = m; } } } #line 1802 "./src/lsp.am" if (method == NULL) { #line 1803 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 1804 "./src/lsp.am" return; } #line 1810 "./src/lsp.am" AmalgameList* calleeNames = AmalgameList_new(); #line 1811 "./src/lsp.am" AmalgameList* calleeSites = AmalgameList_new(); #line 1812 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectOutgoingCalls(method->Body, calleeNames, calleeSites); #line 1814 "./src/lsp.am" code_string json = "["; #line 1815 "./src/lsp.am" code_bool first = 1; #line 1816 "./src/lsp.am" i64 cn = AmalgameList_count(calleeNames); #line 1817 "./src/lsp.am" for (i64 i = 0LL; i < cn; i++) { #line 1818 "./src/lsp.am" code_string name = (code_string)AmalgameList_get(calleeNames, i); #line 1819 "./src/lsp.am" code_string ranges = (code_string)AmalgameList_get(calleeSites, i); #line 1824 "./src/lsp.am" code_string toItem = ""; #line 1825 "./src/lsp.am" for (i64 pi = 0LL; pi < nProgs; pi++) { #line 1826 "./src/lsp.am" if (String_Length(toItem) > 0LL) { break; } #line 1827 "./src/lsp.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(resolver->Programs, pi); #line 1828 "./src/lsp.am" code_string pPath = p->Str2; #line 1829 "./src/lsp.am" if (String_Length(pPath) == 0LL) { pPath = anchor; } #line 1830 "./src/lsp.am" i64 dc = AmalgameList_count(p->Children); #line 1831 "./src/lsp.am" for (i64 dj = 0LL; dj < dc; dj++) { #line 1832 "./src/lsp.am" if (String_Length(toItem) > 0LL) { break; } #line 1833 "./src/lsp.am" Amalgame_Compiler_AstNode* cls = (Amalgame_Compiler_AstNode*)AmalgameList_get(p->Children, dj); #line 1834 "./src/lsp.am" if (cls->Kind != Amalgame_Compiler_NodeKind_CLASS_DECL) { continue; } #line 1835 "./src/lsp.am" i64 mc = AmalgameList_count(cls->Children); #line 1836 "./src/lsp.am" for (i64 mk = 0LL; mk < mc; mk++) { #line 1837 "./src/lsp.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(cls->Children, mk); #line 1838 "./src/lsp.am" if (m->Kind != Amalgame_Compiler_NodeKind_METHOD_DECL) { continue; } #line 1839 "./src/lsp.am" if (!code_string_equals(m->Name, name)) { continue; } #line 1840 "./src/lsp.am" toItem = Amalgame_Compiler_LspServer_CallHierarchyItemJson(m, pPath); } } } #line 1844 "./src/lsp.am" if (String_Length(toItem) == 0LL) { continue; } #line 1845 "./src/lsp.am" if (!first) { json = (code_string_concat(json, ",")); } #line 1846 "./src/lsp.am" json = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(json, "{\"to\":")), toItem)), ",\"fromRanges\":")), ranges)), "}")); #line 1847 "./src/lsp.am" first = 0; } #line 1849 "./src/lsp.am" json = (code_string_concat(json, "]")); #line 1850 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":")), json)), "}"); #line 1851 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_CollectCallSitesForName(Amalgame_Compiler_AstNode* node, code_string target, AmalgameList* out) { #line 1859 "./src/lsp.am" if (node == NULL) { return; } #line 1860 "./src/lsp.am" Amalgame_Compiler_AstNode* n = node; #line 1861 "./src/lsp.am" if ((n->Kind == Amalgame_Compiler_NodeKind_CALL) && (n->Left != NULL)) { #line 1862 "./src/lsp.am" Amalgame_Compiler_AstNode* callee = n->Left; #line 1863 "./src/lsp.am" code_string calleeName = ""; #line 1864 "./src/lsp.am" if (callee->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { calleeName = callee->Name; } #line 1865 "./src/lsp.am" if (callee->Kind == Amalgame_Compiler_NodeKind_MEMBER) { calleeName = callee->Name; } #line 1866 "./src/lsp.am" if (code_string_equals(calleeName, target)) { #line 1867 "./src/lsp.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_LspServer_RangeJsonForName(callee->Line, callee->Column, calleeName))); } } #line 1872 "./src/lsp.am" if (n->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) { return; } #line 1873 "./src/lsp.am" if (n->Left != NULL) { Amalgame_Compiler_LspServer_CollectCallSitesForName(n->Left, target, out); } #line 1874 "./src/lsp.am" if (n->Right != NULL) { Amalgame_Compiler_LspServer_CollectCallSitesForName(n->Right, target, out); } #line 1875 "./src/lsp.am" if (n->Cond != NULL) { Amalgame_Compiler_LspServer_CollectCallSitesForName(n->Cond, target, out); } #line 1876 "./src/lsp.am" if (n->Body != NULL) { Amalgame_Compiler_LspServer_CollectCallSitesForName(n->Body, target, out); } #line 1877 "./src/lsp.am" if (n->Else != NULL) { Amalgame_Compiler_LspServer_CollectCallSitesForName(n->Else, target, out); } #line 1878 "./src/lsp.am" i64 cn = AmalgameList_count(n->Children); #line 1879 "./src/lsp.am" for (i64 i = 0LL; i < cn; i++) { #line 1880 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectCallSitesForName((Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, i), target, out); } #line 1882 "./src/lsp.am" i64 pn = AmalgameList_count(n->Params); #line 1883 "./src/lsp.am" for (i64 j = 0LL; j < pn; j++) { #line 1884 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectCallSitesForName((Amalgame_Compiler_AstNode*)AmalgameList_get(n->Params, j), target, out); } #line 1886 "./src/lsp.am" i64 an = AmalgameList_count(n->Args); #line 1887 "./src/lsp.am" for (i64 k = 0LL; k < an; k++) { #line 1888 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectCallSitesForName((Amalgame_Compiler_AstNode*)AmalgameList_get(n->Args, k), target, out); } } static void Amalgame_Compiler_LspServer_CollectOutgoingCalls(Amalgame_Compiler_AstNode* node, AmalgameList* names, AmalgameList* rangesOut) { #line 1897 "./src/lsp.am" if (node == NULL) { return; } #line 1898 "./src/lsp.am" Amalgame_Compiler_AstNode* n = node; #line 1899 "./src/lsp.am" if ((n->Kind == Amalgame_Compiler_NodeKind_CALL) && (n->Left != NULL)) { #line 1900 "./src/lsp.am" Amalgame_Compiler_AstNode* callee = n->Left; #line 1901 "./src/lsp.am" code_string calleeName = ""; #line 1902 "./src/lsp.am" if (callee->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { calleeName = callee->Name; } #line 1903 "./src/lsp.am" if (callee->Kind == Amalgame_Compiler_NodeKind_MEMBER) { calleeName = callee->Name; } #line 1904 "./src/lsp.am" if (String_Length(calleeName) > 0LL) { #line 1905 "./src/lsp.am" code_string r = Amalgame_Compiler_LspServer_RangeJsonForName(callee->Line, callee->Column, calleeName); #line 1906 "./src/lsp.am" i64 nc = AmalgameList_count(names); #line 1907 "./src/lsp.am" code_bool found = 0; #line 1908 "./src/lsp.am" for (i64 i = 0LL; i < nc; i++) { #line 1909 "./src/lsp.am" if (code_string_equals((code_string)AmalgameList_get(names, i), calleeName)) { #line 1910 "./src/lsp.am" code_string prev = (code_string)AmalgameList_get(rangesOut, i); #line 1913 "./src/lsp.am" i64 prevLen = String_Length(prev); #line 1914 "./src/lsp.am" code_string head = String_Substring(prev, 0LL, prevLen - 1LL); #line 1915 "./src/lsp.am" code_string sep = ","; #line 1916 "./src/lsp.am" if (code_string_equals(prev, "[]")) { sep = ""; } #line 1917 "./src/lsp.am" code_string updated = code_string_concat((code_string_concat((code_string_concat(head, sep)), r)), "]"); #line 1918 "./src/lsp.am" AmalgameList_removeAt(rangesOut, i); #line 1919 "./src/lsp.am" AmalgameList_add(rangesOut, (void*)(intptr_t)(updated)); #line 1922 "./src/lsp.am" AmalgameList_removeAt(names, i); #line 1923 "./src/lsp.am" AmalgameList_add(names, (void*)(intptr_t)(calleeName)); #line 1924 "./src/lsp.am" found = 1; } } #line 1927 "./src/lsp.am" if (!found) { #line 1928 "./src/lsp.am" AmalgameList_add(names, (void*)(intptr_t)(calleeName)); #line 1929 "./src/lsp.am" AmalgameList_add(rangesOut, (void*)(intptr_t)(code_string_concat((code_string_concat("[", r)), "]"))); } } } #line 1933 "./src/lsp.am" if (n->Kind == Amalgame_Compiler_NodeKind_METHOD_DECL) { return; } #line 1934 "./src/lsp.am" if (n->Left != NULL) { Amalgame_Compiler_LspServer_CollectOutgoingCalls(n->Left, names, rangesOut); } #line 1935 "./src/lsp.am" if (n->Right != NULL) { Amalgame_Compiler_LspServer_CollectOutgoingCalls(n->Right, names, rangesOut); } #line 1936 "./src/lsp.am" if (n->Cond != NULL) { Amalgame_Compiler_LspServer_CollectOutgoingCalls(n->Cond, names, rangesOut); } #line 1937 "./src/lsp.am" if (n->Body != NULL) { Amalgame_Compiler_LspServer_CollectOutgoingCalls(n->Body, names, rangesOut); } #line 1938 "./src/lsp.am" if (n->Else != NULL) { Amalgame_Compiler_LspServer_CollectOutgoingCalls(n->Else, names, rangesOut); } #line 1939 "./src/lsp.am" i64 cn = AmalgameList_count(n->Children); #line 1940 "./src/lsp.am" for (i64 i = 0LL; i < cn; i++) { #line 1941 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectOutgoingCalls((Amalgame_Compiler_AstNode*)AmalgameList_get(n->Children, i), names, rangesOut); } #line 1943 "./src/lsp.am" i64 pn = AmalgameList_count(n->Params); #line 1944 "./src/lsp.am" for (i64 j = 0LL; j < pn; j++) { #line 1945 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectOutgoingCalls((Amalgame_Compiler_AstNode*)AmalgameList_get(n->Params, j), names, rangesOut); } #line 1947 "./src/lsp.am" i64 an = AmalgameList_count(n->Args); #line 1948 "./src/lsp.am" for (i64 k = 0LL; k < an; k++) { #line 1949 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectOutgoingCalls((Amalgame_Compiler_AstNode*)AmalgameList_get(n->Args, k), names, rangesOut); } } static code_string Amalgame_Compiler_LspServer_CallHierarchyItemJson(Amalgame_Compiler_AstNode* method, code_string filePath) { #line 1962 "./src/lsp.am" code_string name = method->Name; #line 1963 "./src/lsp.am" i64 lineLsp = method->Line - 1LL; #line 1964 "./src/lsp.am" i64 colLsp = method->Column - 1LL; #line 1965 "./src/lsp.am" i64 nameLen = String_Length(name); #line 1966 "./src/lsp.am" i64 endCol = colLsp + nameLen; #line 1967 "./src/lsp.am" code_string uri = code_string_concat("file://", Amalgame_Compiler_LspServer_PercentEncodePath(filePath)); #line 1968 "./src/lsp.am" code_string range = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"start\":{\"line\":", String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(colLsp))), "},\"end\":{\"line\":")), String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(endCol))), "}}"); #line 1969 "./src/lsp.am" code_string data = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"name\":\"", Amalgame_Compiler_Json_EscapeString(name))), "\",\"uri\":\"")), Amalgame_Compiler_Json_EscapeString(uri))), "\",\"line\":")), String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(colLsp))), "}"); #line 1970 "./src/lsp.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"name\":\"", Amalgame_Compiler_Json_EscapeString(name))), "\",\"kind\":6,\"uri\":\"")), Amalgame_Compiler_Json_EscapeString(uri))), "\",\"range\":")), range)), ",\"selectionRange\":")), range)), ",\"data\":")), data)), "}"); } static code_string Amalgame_Compiler_LspServer_RangeJsonForName(i64 line, i64 col, code_string name) { #line 1978 "./src/lsp.am" i64 lineLsp = line - 1LL; #line 1979 "./src/lsp.am" i64 colLsp = col - 1LL; #line 1980 "./src/lsp.am" i64 nameLen = String_Length(name); #line 1981 "./src/lsp.am" i64 endCol = colLsp + nameLen; #line 1982 "./src/lsp.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"start\":{\"line\":", String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(colLsp))), "},\"end\":{\"line\":")), String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(endCol))), "}}"); } static void Amalgame_Compiler_LspServer_HandleInlayHint(Amalgame_Compiler_LspServer* self, i64 id, code_string uri) { #line 2007 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 2008 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 2009 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 2010 "./src/lsp.am" return; } #line 2012 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 2013 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 2014 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 2015 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 2016 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 2017 "./src/lsp.am" prog->Str2 = path; #line 2018 "./src/lsp.am" Amalgame_Compiler_FullResolver* resolver = Amalgame_Compiler_LspServer_BuildWorkspaceResolver(self, path, prog); #line 2019 "./src/lsp.am" Amalgame_Compiler_TypeChecker* tc = Amalgame_Compiler_TypeChecker_new(resolver, path); #line 2020 "./src/lsp.am" Amalgame_Compiler_TypeChecker_Check(tc, prog); #line 2022 "./src/lsp.am" AmalgameList* hints = AmalgameList_new(); #line 2023 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectInlayHints(prog, tc, hints); #line 2025 "./src/lsp.am" code_string json = "["; #line 2026 "./src/lsp.am" i64 n = AmalgameList_count(hints); #line 2027 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 2028 "./src/lsp.am" if (i > 0LL) { json = (code_string_concat(json, ",")); } #line 2029 "./src/lsp.am" json = (code_string_concat(json, (code_string)AmalgameList_get(hints, i))); } #line 2031 "./src/lsp.am" json = (code_string_concat(json, "]")); #line 2032 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":")), json)), "}"); #line 2033 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_CollectInlayHints(Amalgame_Compiler_AstNode* node, Amalgame_Compiler_TypeChecker* tc, AmalgameList* out) { #line 2041 "./src/lsp.am" if (node == NULL) { return; } #line 2042 "./src/lsp.am" if (node->Kind == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 2046 "./src/lsp.am" if ((String_Length(node->Str) == 0LL) || (code_string_equals(node->Str, "__tuple_destructure__"))) { #line 2047 "./src/lsp.am" if ((!code_string_equals(node->Str, "__tuple_destructure__")) && (node->Left != NULL)) { #line 2048 "./src/lsp.am" code_string inferred = Amalgame_Compiler_TypeChecker_LookupNodeType(tc, node->Left); #line 2049 "./src/lsp.am" if ((String_Length(inferred) > 0LL) && (!code_string_equals(inferred, "?"))) { #line 2050 "./src/lsp.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_LspServer_InlayHintJson(node->Line, node->Column, node->Name, inferred))); } } } } #line 2055 "./src/lsp.am" if (node->Left != NULL) { Amalgame_Compiler_LspServer_CollectInlayHints(node->Left, tc, out); } #line 2056 "./src/lsp.am" if (node->Right != NULL) { Amalgame_Compiler_LspServer_CollectInlayHints(node->Right, tc, out); } #line 2057 "./src/lsp.am" if (node->Cond != NULL) { Amalgame_Compiler_LspServer_CollectInlayHints(node->Cond, tc, out); } #line 2058 "./src/lsp.am" if (node->Body != NULL) { Amalgame_Compiler_LspServer_CollectInlayHints(node->Body, tc, out); } #line 2059 "./src/lsp.am" if (node->Else != NULL) { Amalgame_Compiler_LspServer_CollectInlayHints(node->Else, tc, out); } #line 2060 "./src/lsp.am" i64 cn = AmalgameList_count(node->Children); #line 2061 "./src/lsp.am" for (i64 i = 0LL; i < cn; i++) { #line 2062 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectInlayHints((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Children, i), tc, out); } #line 2064 "./src/lsp.am" i64 pn = AmalgameList_count(node->Params); #line 2065 "./src/lsp.am" for (i64 j = 0LL; j < pn; j++) { #line 2066 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectInlayHints((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Params, j), tc, out); } #line 2068 "./src/lsp.am" i64 an = AmalgameList_count(node->Args); #line 2069 "./src/lsp.am" for (i64 k = 0LL; k < an; k++) { #line 2070 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectInlayHints((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Args, k), tc, out); } } static code_string Amalgame_Compiler_LspServer_InlayHintJson(i64 line, i64 col, code_string name, code_string typeStr) { #line 2080 "./src/lsp.am" i64 lineLsp = line - 1LL; #line 2081 "./src/lsp.am" i64 colLsp = col - 1LL; #line 2082 "./src/lsp.am" i64 nameLen = String_Length(name); #line 2083 "./src/lsp.am" i64 endCol = colLsp + nameLen; #line 2084 "./src/lsp.am" code_string pos = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"line\":", String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(endCol))), "}"); #line 2085 "./src/lsp.am" code_string label = code_string_concat(": ", typeStr); #line 2086 "./src/lsp.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"position\":", pos)), ",\"label\":\"")), Amalgame_Compiler_Json_EscapeString(label))), "\",\"kind\":1,\"paddingLeft\":true}"); } static void Amalgame_Compiler_LspServer_HandleCodeAction(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 startLine, i64 startChr, i64 endLine, i64 endChr) { #line 2104 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 2105 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 2106 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 2107 "./src/lsp.am" return; } #line 2109 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 2110 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 2111 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 2112 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 2113 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 2114 "./src/lsp.am" prog->Str2 = path; #line 2115 "./src/lsp.am" Amalgame_Compiler_FullResolver* resolver = Amalgame_Compiler_LspServer_BuildWorkspaceResolver(self, path, prog); #line 2116 "./src/lsp.am" Amalgame_Compiler_TypeChecker* tc = Amalgame_Compiler_TypeChecker_new(resolver, path); #line 2117 "./src/lsp.am" Amalgame_Compiler_TypeChecker_Check(tc, prog); #line 2120 "./src/lsp.am" i64 sLine = startLine + 1LL; #line 2121 "./src/lsp.am" i64 eLine = endLine + 1LL; #line 2122 "./src/lsp.am" AmalgameList* actions = AmalgameList_new(); #line 2123 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectAnnotationFixes(prog, tc, uri, sLine, eLine, actions); #line 2124 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectPackageInstallSuggestions(self, resolver, uri, path, sLine, eLine, actions); #line 2126 "./src/lsp.am" code_string json = "["; #line 2127 "./src/lsp.am" i64 n = AmalgameList_count(actions); #line 2128 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 2129 "./src/lsp.am" if (i > 0LL) { json = (code_string_concat(json, ",")); } #line 2130 "./src/lsp.am" json = (code_string_concat(json, (code_string)AmalgameList_get(actions, i))); } #line 2132 "./src/lsp.am" json = (code_string_concat(json, "]")); #line 2133 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":")), json)), "}"); #line 2134 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_CollectPackageInstallSuggestions(Amalgame_Compiler_LspServer* self, Amalgame_Compiler_FullResolver* resolver, code_string uri, code_string path, i64 sLine, i64 eLine, AmalgameList* out) { #line 2151 "./src/lsp.am" i64 errN = AmalgameList_count(resolver->RawErrors); #line 2152 "./src/lsp.am" if (errN == 0LL) { return; } #line 2153 "./src/lsp.am" code_string prefix = "Unknown symbol '"; #line 2154 "./src/lsp.am" i64 prefLen = String_Length(prefix); #line 2155 "./src/lsp.am" AmalgameList* seen = AmalgameList_new(); #line 2156 "./src/lsp.am" for (i64 ei = 0LL; ei < errN; ei++) { #line 2157 "./src/lsp.am" Amalgame_Compiler_ResolverError* err = (Amalgame_Compiler_ResolverError*)AmalgameList_get(resolver->RawErrors, ei); #line 2158 "./src/lsp.am" if ((err->Line < sLine) || (err->Line > eLine)) { continue; } #line 2159 "./src/lsp.am" if (!String_StartsWith(err->Message, prefix)) { continue; } #line 2160 "./src/lsp.am" code_string rest = String_Substring(err->Message, prefLen, String_Length(err->Message) - prefLen); #line 2161 "./src/lsp.am" i64 endQuote = String_IndexOf(rest, "'"); #line 2162 "./src/lsp.am" if (endQuote <= 0LL) { continue; } #line 2163 "./src/lsp.am" code_string symName = String_Substring(rest, 0LL, endQuote); #line 2165 "./src/lsp.am" if ((code_string_equals(symName, "_")) || (code_string_equals(symName, "_unknown_"))) { continue; } #line 2168 "./src/lsp.am" code_bool dup = 0; #line 2169 "./src/lsp.am" i64 sn = AmalgameList_count(seen); #line 2170 "./src/lsp.am" for (i64 si = 0LL; si < sn; si++) { #line 2171 "./src/lsp.am" if (code_string_equals((code_string)AmalgameList_get(seen, si), symName)) { dup = 1; } } #line 2173 "./src/lsp.am" if (dup) { continue; } #line 2174 "./src/lsp.am" AmalgameList_add(seen, (void*)(intptr_t)(symName)); #line 2182 "./src/lsp.am" code_string cmd = "amc"; #line 2183 "./src/lsp.am" code_string amcBin = Amalgame_Compiler_LspServer_AmcBinaryPath(); #line 2184 "./src/lsp.am" if (String_Length(amcBin) > 0LL) { cmd = amcBin; } #line 2185 "./src/lsp.am" AmalgameProcessResult* result = Process_RunCapture(code_string_concat((code_string_concat(cmd, " package suggest --json ")), symName)); #line 2186 "./src/lsp.am" if (result->Exit != 0LL) { continue; } #line 2187 "./src/lsp.am" code_string trimmed = String_Trim(result->Stdout); #line 2188 "./src/lsp.am" if ((String_Length(trimmed) == 0LL) || (code_string_equals(trimmed, "[]"))) { continue; } #line 2189 "./src/lsp.am" Amalgame_Compiler_JsonResult* parsed = Amalgame_Compiler_Json_Parse(trimmed); #line 2190 "./src/lsp.am" if (!parsed->Ok) { continue; } #line 2191 "./src/lsp.am" Amalgame_Compiler_JsonValue* doc = parsed->Value; #line 2192 "./src/lsp.am" if (Amalgame_Compiler_JsonValue_IsNull(doc) || !Amalgame_Compiler_JsonValue_IsArray(doc)) { continue; } #line 2193 "./src/lsp.am" AmalgameList* arr = Amalgame_Compiler_JsonValue_AsArray(doc); #line 2194 "./src/lsp.am" i64 nResults = AmalgameList_count(arr); #line 2200 "./src/lsp.am" code_string docSource = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 2201 "./src/lsp.am" i64 insertLine = -1LL; #line 2202 "./src/lsp.am" if (String_Length(docSource) > 0LL) { #line 2203 "./src/lsp.am" insertLine = Amalgame_Compiler_LspServer_FindImportInsertionLine(docSource); } #line 2205 "./src/lsp.am" for (i64 ri = 0LL; ri < nResults; ri++) { #line 2206 "./src/lsp.am" Amalgame_Compiler_JsonValue* entry = (Amalgame_Compiler_JsonValue*)AmalgameList_get(arr, ri); #line 2207 "./src/lsp.am" code_string pkgName = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(entry, "name")); #line 2208 "./src/lsp.am" if (String_Length(pkgName) == 0LL) { continue; } #line 2209 "./src/lsp.am" code_string pkgTag = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(entry, "latest_compatible_tag")); #line 2210 "./src/lsp.am" code_string pkgDesc = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(entry, "description")); #line 2211 "./src/lsp.am" code_string pkgUrl = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(entry, "url")); #line 2212 "./src/lsp.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_LspServer_PackageInstallActionJson(pkgName, pkgTag, pkgDesc, symName))); #line 2217 "./src/lsp.am" if (insertLine >= 0LL) { #line 2218 "./src/lsp.am" code_string ns = Amalgame_Compiler_LspServer_InferNamespaceFromUrl(pkgUrl); #line 2219 "./src/lsp.am" if ((String_Length(ns) > 0LL) && !Amalgame_Compiler_LspServer_HasImport(docSource, ns)) { #line 2220 "./src/lsp.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_LspServer_PackageImportActionJson(uri, insertLine, ns, symName))); } } } } } static code_string Amalgame_Compiler_LspServer_AmcBinaryPath() { #line 2233 "./src/lsp.am" { /* inline-C */ #ifdef _WIN32 char buf[4096]; DWORD n = GetModuleFileNameA(NULL, buf, sizeof(buf)); if (n == 0 || n >= sizeof(buf)) { return (code_string) ""; } for (DWORD i = 0; i < n; i++) { if (buf[i] == '\\') buf[i] = '/'; } char* out = (char*) GC_MALLOC((size_t)(n + 1)); memcpy(out, buf, (size_t)(n + 1)); return (code_string) out; #elif defined(__APPLE__) char raw[4096]; uint32_t size = sizeof(raw); if (_NSGetExecutablePath(raw, &size) != 0) { return (code_string) ""; } char resolved[4096]; char* p = realpath(raw, resolved); const char* src = p ? (const char*)resolved : (const char*)raw; size_t n = strlen(src); char* out = (char*) GC_MALLOC(n + 1); memcpy(out, src, n + 1); return (code_string) out; #else char buf[4096]; ssize_t n = readlink("/proc/self/exe", buf, sizeof(buf) - 1); if (n <= 0) { return (code_string) ""; } buf[n] = '\0'; char* out = (char*) GC_MALLOC((size_t)(n + 1)); memcpy(out, buf, (size_t)(n + 1)); return (code_string) out; #endif } } static code_string Amalgame_Compiler_LspServer_PackageInstallActionJson(code_string pkgName, code_string pkgTag, code_string pkgDesc, code_string symName) { #line 2271 "./src/lsp.am" code_string label = code_string_concat("Install package ", pkgName); #line 2272 "./src/lsp.am" if (String_Length(pkgTag) > 0LL) { label = (code_string_concat((code_string_concat(label, "@")), pkgTag)); } #line 2273 "./src/lsp.am" label = (code_string_concat((code_string_concat((code_string_concat(label, " (for '")), symName)), "')")); #line 2274 "./src/lsp.am" code_string cmdArgs = code_string_concat("amc package add ", pkgName); #line 2275 "./src/lsp.am" if (String_Length(pkgTag) > 0LL) { cmdArgs = (code_string_concat((code_string_concat(cmdArgs, "@")), pkgTag)); } #line 2276 "./src/lsp.am" code_string cmd = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"title\":\"", Amalgame_Compiler_Json_EscapeString(label))), "\",\"command\":\"")), Amalgame_Compiler_Json_EscapeString(cmdArgs))), "\"}"); #line 2277 "./src/lsp.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"title\":\"", Amalgame_Compiler_Json_EscapeString(label))), "\",\"kind\":\"quickfix\",\"command\":")), cmd)), "}"); } static code_string Amalgame_Compiler_LspServer_SegmentToNamespacePart(code_string seg) { #line 2285 "./src/lsp.am" code_string s = String_ToLower(seg); #line 2286 "./src/lsp.am" if (code_string_equals(s, "sdl")) { return "SDL"; } #line 2287 "./src/lsp.am" if (code_string_equals(s, "tls")) { return "TLS"; } #line 2288 "./src/lsp.am" if (code_string_equals(s, "ui")) { return "UI"; } #line 2289 "./src/lsp.am" if (code_string_equals(s, "io")) { return "IO"; } #line 2290 "./src/lsp.am" if (code_string_equals(s, "mqtt")) { return "MQTT"; } #line 2291 "./src/lsp.am" if (code_string_equals(s, "nats")) { return "NATS"; } #line 2292 "./src/lsp.am" if (code_string_equals(s, "amqp")) { return "AMQP"; } #line 2293 "./src/lsp.am" if (code_string_equals(s, "nosql")) { return "NoSQL"; } #line 2294 "./src/lsp.am" if (code_string_equals(s, "sqlite")) { return "SQLite"; } #line 2295 "./src/lsp.am" if (code_string_equals(s, "duckdb")) { return "DuckDB"; } #line 2296 "./src/lsp.am" if (code_string_equals(s, "rabbitmq")) { return "RabbitMQ"; } #line 2297 "./src/lsp.am" if (code_string_equals(s, "mongodb")) { return "MongoDB"; } #line 2298 "./src/lsp.am" if (code_string_equals(s, "websocket")) { return "WebSocket"; } #line 2299 "./src/lsp.am" if (code_string_equals(s, "ml")) { return "ML"; } #line 2300 "./src/lsp.am" if (code_string_equals(s, "ai")) { return "AI"; } #line 2301 "./src/lsp.am" if (code_string_equals(s, "orm")) { return "ORM"; } #line 2302 "./src/lsp.am" if (code_string_equals(s, "postgresql")) { return "PostgreSQL"; } #line 2303 "./src/lsp.am" if (code_string_equals(s, "mysql")) { return "MySQL"; } #line 2304 "./src/lsp.am" if (code_string_equals(s, "mariadb")) { return "MariaDB"; } #line 2305 "./src/lsp.am" if (code_string_equals(s, "mssql")) { return "MSSQL"; } #line 2306 "./src/lsp.am" if (code_string_equals(s, "dynamodb")) { return "DynamoDB"; } #line 2307 "./src/lsp.am" i64 n = String_Length(s); #line 2308 "./src/lsp.am" if (n == 0LL) { return ""; } #line 2309 "./src/lsp.am" code_string firstUpper = String_ToUpper(String_Substring(s, 0LL, 1LL)); #line 2310 "./src/lsp.am" if (n == 1LL) { return firstUpper; } #line 2311 "./src/lsp.am" return code_string_concat(firstUpper, String_Substring(s, 1LL, n - 1LL)); } static code_string Amalgame_Compiler_LspServer_InferNamespaceFromUrl(code_string url) { #line 2326 "./src/lsp.am" if (String_Length(url) == 0LL) { return ""; } #line 2327 "./src/lsp.am" code_string slug = url; #line 2328 "./src/lsp.am" i64 slashIdx = String_LastIndexOf(url, "/"); #line 2329 "./src/lsp.am" if ((slashIdx >= 0LL) && ((slashIdx + 1LL) < String_Length(url))) { #line 2330 "./src/lsp.am" slug = String_Substring(url, slashIdx + 1LL, (String_Length(url) - slashIdx) - 1LL); } #line 2332 "./src/lsp.am" if (String_StartsWith(slug, "amalgame-")) { #line 2333 "./src/lsp.am" slug = String_Substring(slug, 9LL, String_Length(slug) - 9LL); } #line 2335 "./src/lsp.am" if (String_Length(slug) == 0LL) { return ""; } #line 2336 "./src/lsp.am" AmalgameList* parts = String_Split(slug, "-"); #line 2337 "./src/lsp.am" code_string ns = "Amalgame"; #line 2338 "./src/lsp.am" i64 n = AmalgameList_count(parts); #line 2339 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 2340 "./src/lsp.am" code_string part = (code_string)AmalgameList_get(parts, i); #line 2341 "./src/lsp.am" if (String_Length(part) == 0LL) { continue; } #line 2342 "./src/lsp.am" ns = (code_string_concat((code_string_concat(ns, ".")), Amalgame_Compiler_LspServer_SegmentToNamespacePart(part))); } #line 2344 "./src/lsp.am" return ns; } static i64 Amalgame_Compiler_LspServer_FindImportInsertionLine(code_string source) { #line 2357 "./src/lsp.am" AmalgameList* lines = String_Split(source, "\n"); #line 2358 "./src/lsp.am" i64 n = AmalgameList_count(lines); #line 2359 "./src/lsp.am" i64 lastAnchor = -1LL; #line 2360 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 2361 "./src/lsp.am" code_string trimmed = String_Trim((code_string)AmalgameList_get(lines, i)); #line 2362 "./src/lsp.am" if (String_Length(trimmed) == 0LL) { continue; } #line 2363 "./src/lsp.am" if (String_StartsWith(trimmed, "//")) { continue; } #line 2364 "./src/lsp.am" if (String_StartsWith(trimmed, "namespace ")) { #line 2365 "./src/lsp.am" lastAnchor = i; #line 2366 "./src/lsp.am" continue; } #line 2368 "./src/lsp.am" if (String_StartsWith(trimmed, "import ")) { #line 2369 "./src/lsp.am" lastAnchor = i; #line 2370 "./src/lsp.am" continue; } #line 2372 "./src/lsp.am" break; } #line 2374 "./src/lsp.am" return lastAnchor + 1LL; } static code_bool Amalgame_Compiler_LspServer_HasImport(code_string source, code_string ns) { #line 2381 "./src/lsp.am" AmalgameList* lines = String_Split(source, "\n"); #line 2382 "./src/lsp.am" i64 n = AmalgameList_count(lines); #line 2383 "./src/lsp.am" code_string needle = code_string_concat("import ", ns); #line 2384 "./src/lsp.am" code_bool found = 0; #line 2385 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 2386 "./src/lsp.am" if (code_string_equals(String_Trim((code_string)AmalgameList_get(lines, i)), needle)) { found = 1; } } #line 2388 "./src/lsp.am" return found; } static code_string Amalgame_Compiler_LspServer_PackageImportActionJson(code_string uri, i64 insertLine, code_string ns, code_string symName) { #line 2396 "./src/lsp.am" code_string posStr = code_string_concat((code_string_concat("{\"line\":", String_FromInt(insertLine))), ",\"character\":0}"); #line 2397 "./src/lsp.am" code_string range = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"start\":", posStr)), ",\"end\":")), posStr)), "}"); #line 2398 "./src/lsp.am" code_string newText = code_string_concat((code_string_concat("import ", ns)), "\n"); #line 2399 "./src/lsp.am" code_string edit = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"range\":", range)), ",\"newText\":\"")), Amalgame_Compiler_Json_EscapeString(newText))), "\"}"); #line 2400 "./src/lsp.am" code_string changes = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"", Amalgame_Compiler_Json_EscapeString(uri))), "\":[")), edit)), "]}"); #line 2401 "./src/lsp.am" code_string title = code_string_concat((code_string_concat((code_string_concat((code_string_concat("Add import ", ns)), " (for '")), symName)), "')"); #line 2402 "./src/lsp.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"title\":\"", Amalgame_Compiler_Json_EscapeString(title))), "\",\"kind\":\"quickfix\",\"isPreferred\":true,\"edit\":{\"changes\":")), changes)), "}}"); } static void Amalgame_Compiler_LspServer_CollectAnnotationFixes(Amalgame_Compiler_AstNode* node, Amalgame_Compiler_TypeChecker* tc, code_string uri, i64 sLine, i64 eLine, AmalgameList* out) { #line 2410 "./src/lsp.am" if (node == NULL) { return; } #line 2411 "./src/lsp.am" if (node->Kind == Amalgame_Compiler_NodeKind_VAR_DECL) { #line 2413 "./src/lsp.am" code_bool inRange = (node->Line >= sLine) && (node->Line <= eLine); #line 2414 "./src/lsp.am" if (((inRange && (String_Length(node->Str) == 0LL)) && (!code_string_equals(node->Str, "__tuple_destructure__"))) && (node->Left != NULL)) { #line 2415 "./src/lsp.am" code_string inferred = Amalgame_Compiler_TypeChecker_LookupNodeType(tc, node->Left); #line 2416 "./src/lsp.am" if ((String_Length(inferred) > 0LL) && (!code_string_equals(inferred, "?"))) { #line 2417 "./src/lsp.am" AmalgameList_add(out, (void*)(intptr_t)(Amalgame_Compiler_LspServer_AnnotationFixJson(uri, node->Line, node->Column, node->Name, inferred))); } } } #line 2421 "./src/lsp.am" if (node->Left != NULL) { Amalgame_Compiler_LspServer_CollectAnnotationFixes(node->Left, tc, uri, sLine, eLine, out); } #line 2422 "./src/lsp.am" if (node->Right != NULL) { Amalgame_Compiler_LspServer_CollectAnnotationFixes(node->Right, tc, uri, sLine, eLine, out); } #line 2423 "./src/lsp.am" if (node->Cond != NULL) { Amalgame_Compiler_LspServer_CollectAnnotationFixes(node->Cond, tc, uri, sLine, eLine, out); } #line 2424 "./src/lsp.am" if (node->Body != NULL) { Amalgame_Compiler_LspServer_CollectAnnotationFixes(node->Body, tc, uri, sLine, eLine, out); } #line 2425 "./src/lsp.am" if (node->Else != NULL) { Amalgame_Compiler_LspServer_CollectAnnotationFixes(node->Else, tc, uri, sLine, eLine, out); } #line 2426 "./src/lsp.am" i64 cn = AmalgameList_count(node->Children); #line 2427 "./src/lsp.am" for (i64 i = 0LL; i < cn; i++) { #line 2428 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectAnnotationFixes((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Children, i), tc, uri, sLine, eLine, out); } #line 2430 "./src/lsp.am" i64 pn = AmalgameList_count(node->Params); #line 2431 "./src/lsp.am" for (i64 j = 0LL; j < pn; j++) { #line 2432 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectAnnotationFixes((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Params, j), tc, uri, sLine, eLine, out); } #line 2434 "./src/lsp.am" i64 an = AmalgameList_count(node->Args); #line 2435 "./src/lsp.am" for (i64 k = 0LL; k < an; k++) { #line 2436 "./src/lsp.am" Amalgame_Compiler_LspServer_CollectAnnotationFixes((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Args, k), tc, uri, sLine, eLine, out); } } static code_string Amalgame_Compiler_LspServer_AnnotationFixJson(code_string uri, i64 line, i64 col, code_string name, code_string typeStr) { #line 2449 "./src/lsp.am" i64 lineLsp = line - 1LL; #line 2450 "./src/lsp.am" i64 colLsp = col - 1LL; #line 2451 "./src/lsp.am" i64 nameLen = String_Length(name); #line 2452 "./src/lsp.am" i64 endCol = colLsp + nameLen; #line 2453 "./src/lsp.am" code_string insertPoint = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"line\":", String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(endCol))), "}"); #line 2454 "./src/lsp.am" code_string range = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"start\":", insertPoint)), ",\"end\":")), insertPoint)), "}"); #line 2455 "./src/lsp.am" code_string newText = code_string_concat(": ", typeStr); #line 2456 "./src/lsp.am" code_string edit = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"range\":", range)), ",\"newText\":\"")), Amalgame_Compiler_Json_EscapeString(newText))), "\"}"); #line 2457 "./src/lsp.am" code_string changes = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"", Amalgame_Compiler_Json_EscapeString(uri))), "\":[")), edit)), "]}"); #line 2458 "./src/lsp.am" code_string title = code_string_concat("Add type annotation: ", typeStr); #line 2459 "./src/lsp.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"title\":\"", Amalgame_Compiler_Json_EscapeString(title))), "\",\"kind\":\"quickfix\",\"isPreferred\":true,\"edit\":{\"changes\":")), changes)), "}}"); } static void Amalgame_Compiler_LspServer_HandleFoldingRange(Amalgame_Compiler_LspServer* self, i64 id, code_string uri) { #line 2483 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 2484 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 2485 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":[]}")); #line 2486 "./src/lsp.am" return; } #line 2488 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 2489 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 2490 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 2492 "./src/lsp.am" AmalgameList* folds = AmalgameList_new(); #line 2493 "./src/lsp.am" AmalgameList* braceStack = AmalgameList_new(); #line 2494 "./src/lsp.am" i64 commStart = 0LL; #line 2495 "./src/lsp.am" i64 commEnd = 0LL; #line 2496 "./src/lsp.am" i64 lastComm = -2LL; #line 2497 "./src/lsp.am" i64 impStart = 0LL; #line 2498 "./src/lsp.am" i64 impEnd = 0LL; #line 2499 "./src/lsp.am" i64 lastImp = -2LL; #line 2501 "./src/lsp.am" i64 nT = AmalgameList_count(toks); #line 2502 "./src/lsp.am" for (i64 i = 0LL; i < nT; i++) { #line 2503 "./src/lsp.am" Amalgame_Compiler_Token* t = (Amalgame_Compiler_Token*)AmalgameList_get(toks, i); #line 2504 "./src/lsp.am" Amalgame_Compiler_TokenType ty = t->Type; #line 2506 "./src/lsp.am" if (ty == Amalgame_Compiler_TokenType_LBRACE) { #line 2507 "./src/lsp.am" AmalgameList_add(braceStack, (void*)(intptr_t)(t->Line)); } #line 2509 "./src/lsp.am" if (ty == Amalgame_Compiler_TokenType_RBRACE) { #line 2510 "./src/lsp.am" i64 depth = AmalgameList_count(braceStack); #line 2511 "./src/lsp.am" if (depth > 0LL) { #line 2512 "./src/lsp.am" i64 openLine = (i64)(intptr_t)AmalgameList_get(braceStack, depth - 1LL); #line 2513 "./src/lsp.am" AmalgameList_removeAt(braceStack, depth - 1LL); #line 2514 "./src/lsp.am" i64 closeLine = t->Line; #line 2516 "./src/lsp.am" if (closeLine > (openLine + 1LL)) { #line 2517 "./src/lsp.am" AmalgameList_add(folds, (void*)(intptr_t)(Amalgame_Compiler_LspServer_FoldEntry(openLine - 1LL, closeLine - 2LL, ""))); } } } #line 2522 "./src/lsp.am" if (ty == Amalgame_Compiler_TokenType_COMMENT) { #line 2523 "./src/lsp.am" if (t->Line == (lastComm + 1LL)) { #line 2524 "./src/lsp.am" commEnd = t->Line; } else { #line 2526 "./src/lsp.am" if (commEnd > commStart) { #line 2527 "./src/lsp.am" AmalgameList_add(folds, (void*)(intptr_t)(Amalgame_Compiler_LspServer_FoldEntry(commStart - 1LL, commEnd - 1LL, "comment"))); } #line 2529 "./src/lsp.am" commStart = t->Line; #line 2530 "./src/lsp.am" commEnd = t->Line; } #line 2532 "./src/lsp.am" lastComm = t->Line; } #line 2535 "./src/lsp.am" if (ty == Amalgame_Compiler_TokenType_KW_IMPORT) { #line 2536 "./src/lsp.am" if (t->Line == (lastImp + 1LL)) { #line 2537 "./src/lsp.am" impEnd = t->Line; } else { #line 2539 "./src/lsp.am" if (impEnd > impStart) { #line 2540 "./src/lsp.am" AmalgameList_add(folds, (void*)(intptr_t)(Amalgame_Compiler_LspServer_FoldEntry(impStart - 1LL, impEnd - 1LL, "imports"))); } #line 2542 "./src/lsp.am" impStart = t->Line; #line 2543 "./src/lsp.am" impEnd = t->Line; } #line 2545 "./src/lsp.am" lastImp = t->Line; } } #line 2549 "./src/lsp.am" if (commEnd > commStart) { #line 2550 "./src/lsp.am" AmalgameList_add(folds, (void*)(intptr_t)(Amalgame_Compiler_LspServer_FoldEntry(commStart - 1LL, commEnd - 1LL, "comment"))); } #line 2552 "./src/lsp.am" if (impEnd > impStart) { #line 2553 "./src/lsp.am" AmalgameList_add(folds, (void*)(intptr_t)(Amalgame_Compiler_LspServer_FoldEntry(impStart - 1LL, impEnd - 1LL, "imports"))); } #line 2556 "./src/lsp.am" code_string json = "["; #line 2557 "./src/lsp.am" i64 fn = AmalgameList_count(folds); #line 2558 "./src/lsp.am" for (i64 i = 0LL; i < fn; i++) { #line 2559 "./src/lsp.am" if (i > 0LL) { json = (code_string_concat(json, ",")); } #line 2560 "./src/lsp.am" json = (code_string_concat(json, (code_string)AmalgameList_get(folds, i))); } #line 2562 "./src/lsp.am" json = (code_string_concat(json, "]")); #line 2563 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":")), json)), "}"); #line 2564 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static code_string Amalgame_Compiler_LspServer_FoldEntry(i64 startLine, i64 endLine, code_string kind) { #line 2572 "./src/lsp.am" code_string s = code_string_concat((code_string_concat((code_string_concat("{\"startLine\":", String_FromInt(startLine))), ",\"endLine\":")), String_FromInt(endLine)); #line 2573 "./src/lsp.am" if (String_Length(kind) > 0LL) { #line 2574 "./src/lsp.am" s = (code_string_concat((code_string_concat((code_string_concat(s, ",\"kind\":\"")), kind)), "\"")); } #line 2576 "./src/lsp.am" s = (code_string_concat(s, "}")); #line 2577 "./src/lsp.am" return s; } static void Amalgame_Compiler_LspServer_HandleWorkspaceSymbol(Amalgame_Compiler_LspServer* self, i64 id, code_string query) { #line 2600 "./src/lsp.am" code_string anchor = ""; #line 2601 "./src/lsp.am" if (AmalgameList_count(self->DocUris) > 0LL) { #line 2602 "./src/lsp.am" anchor = Amalgame_Compiler_LspServer_UriToPath((code_string)AmalgameList_get(self->DocUris, 0LL)); } else { #line 2604 "./src/lsp.am" anchor = "./_.am"; } #line 2606 "./src/lsp.am" Amalgame_Compiler_LspServer_EnsureWorkspaceCache(self, anchor); #line 2608 "./src/lsp.am" code_string q = String_ToLower(query); #line 2609 "./src/lsp.am" code_string json = "["; #line 2610 "./src/lsp.am" code_bool first = 1; #line 2616 "./src/lsp.am" i64 openN = AmalgameList_count(self->DocUris); #line 2617 "./src/lsp.am" for (i64 di = 0LL; di < openN; di++) { #line 2618 "./src/lsp.am" code_string docUri = (code_string)AmalgameList_get(self->DocUris, di); #line 2619 "./src/lsp.am" code_string docSrc = (code_string)AmalgameList_get(self->Docs, di); #line 2620 "./src/lsp.am" code_string docPath = Amalgame_Compiler_LspServer_UriToPath(docUri); #line 2621 "./src/lsp.am" code_bool dup = 0; #line 2622 "./src/lsp.am" i64 sn = AmalgameList_count(self->CachedSiblingPaths); #line 2623 "./src/lsp.am" for (i64 sj = 0LL; sj < sn; sj++) { #line 2624 "./src/lsp.am" if (code_string_equals((code_string)AmalgameList_get(self->CachedSiblingPaths, sj), docPath)) { dup = 1; } } #line 2626 "./src/lsp.am" if (dup) { continue; } #line 2627 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(docSrc, docPath); #line 2628 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 2629 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 2630 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 2631 "./src/lsp.am" i64 dc = AmalgameList_count(prog->Children); #line 2632 "./src/lsp.am" for (i64 j = 0LL; j < dc; j++) { #line 2633 "./src/lsp.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, j); #line 2634 "./src/lsp.am" code_string entry = Amalgame_Compiler_LspServer_WorkspaceSymbolEntry(decl, docPath, q); #line 2635 "./src/lsp.am" if (String_Length(entry) > 0LL) { #line 2636 "./src/lsp.am" if (!first) { json = (code_string_concat(json, ",")); } #line 2637 "./src/lsp.am" json = (code_string_concat(json, entry)); #line 2638 "./src/lsp.am" first = 0; } } } #line 2642 "./src/lsp.am" i64 n = AmalgameList_count(self->CachedSiblingProgs); #line 2643 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 2644 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = (Amalgame_Compiler_AstNode*)AmalgameList_get(self->CachedSiblingProgs, i); #line 2645 "./src/lsp.am" code_string path = (code_string)AmalgameList_get(self->CachedSiblingPaths, i); #line 2646 "./src/lsp.am" i64 dc = AmalgameList_count(prog->Children); #line 2647 "./src/lsp.am" for (i64 j = 0LL; j < dc; j++) { #line 2648 "./src/lsp.am" Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, j); #line 2649 "./src/lsp.am" code_string entry = Amalgame_Compiler_LspServer_WorkspaceSymbolEntry(decl, path, q); #line 2650 "./src/lsp.am" if (String_Length(entry) > 0LL) { #line 2651 "./src/lsp.am" if (!first) { json = (code_string_concat(json, ",")); } #line 2652 "./src/lsp.am" json = (code_string_concat(json, entry)); #line 2653 "./src/lsp.am" first = 0; } } } #line 2657 "./src/lsp.am" json = (code_string_concat(json, "]")); #line 2658 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":")), json)), "}"); #line 2659 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static code_string Amalgame_Compiler_LspServer_WorkspaceSymbolEntry(Amalgame_Compiler_AstNode* decl, code_string path, code_string lowerQuery) { #line 2669 "./src/lsp.am" Amalgame_Compiler_NodeKind k = decl->Kind; #line 2670 "./src/lsp.am" i64 kind = 0LL; #line 2671 "./src/lsp.am" if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) { kind = 5LL; } else if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) { #line 2672 "./src/lsp.am" kind = 10LL; } else { #line 2673 "./src/lsp.am" return ""; } #line 2674 "./src/lsp.am" code_string name = decl->Name; #line 2675 "./src/lsp.am" if (String_Length(name) == 0LL) { return ""; } #line 2676 "./src/lsp.am" if (String_Length(lowerQuery) > 0LL) { #line 2677 "./src/lsp.am" code_string lname = String_ToLower(name); #line 2678 "./src/lsp.am" if (String_IndexOf(lname, lowerQuery) < 0LL) { return ""; } } #line 2680 "./src/lsp.am" i64 lineLsp = decl->Line - 1LL; #line 2681 "./src/lsp.am" i64 colLsp = decl->Column - 1LL; #line 2682 "./src/lsp.am" i64 nameLen = String_Length(name); #line 2683 "./src/lsp.am" i64 endCol = colLsp + nameLen; #line 2684 "./src/lsp.am" code_string uri = code_string_concat("file://", Amalgame_Compiler_LspServer_PercentEncodePath(path)); #line 2685 "./src/lsp.am" code_string range = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"start\":{\"line\":", String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(colLsp))), "},\"end\":{\"line\":")), String_FromInt(lineLsp))), ",\"character\":")), String_FromInt(endCol))), "}}"); #line 2686 "./src/lsp.am" code_string location = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"uri\":\"", Amalgame_Compiler_Json_EscapeString(uri))), "\",\"range\":")), range)), "}"); #line 2687 "./src/lsp.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"name\":\"", Amalgame_Compiler_Json_EscapeString(name))), "\",\"kind\":")), String_FromInt(kind))), ",\"location\":")), location)), "}"); } static void Amalgame_Compiler_LspServer_SendDefinitionLocation(Amalgame_Compiler_LspServer* self, i64 id, code_string path, i64 line, i64 col, code_string name) { #line 2700 "./src/lsp.am" code_string encPath = Amalgame_Compiler_LspServer_PercentEncodePath(path); #line 2701 "./src/lsp.am" code_string declUri = code_string_concat("file://", encPath); #line 2702 "./src/lsp.am" i64 declLine = line - 1LL; #line 2703 "./src/lsp.am" i64 declCol = col - 1LL; #line 2708 "./src/lsp.am" i64 nameLen = String_Length(name); #line 2709 "./src/lsp.am" i64 endCol = declCol + nameLen; #line 2710 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"uri\":\"")), Amalgame_Compiler_Json_EscapeString(declUri))), "\",\"range\":{\"start\":{\"line\":")), String_FromInt(declLine))), ",\"character\":")), String_FromInt(declCol))), "},\"end\":{\"line\":")), String_FromInt(declLine))), ",\"character\":")), String_FromInt(endCol))), "}}}}"); #line 2711 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static code_string Amalgame_Compiler_LspServer_PercentEncodePath(code_string path) { #line 2719 "./src/lsp.am" code_string out = ""; #line 2720 "./src/lsp.am" i64 n = String_Length(path); #line 2721 "./src/lsp.am" code_string upper = "0123456789ABCDEF"; #line 2722 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 2723 "./src/lsp.am" code_string c = String_CharAt1(path, i); #line 2724 "./src/lsp.am" i64 code = String_ToInt(String_FromInt(0LL)); #line 2731 "./src/lsp.am" code_bool isSafeAlnum = Amalgame_Compiler_LspServer_IsUriSafeChar(c); #line 2732 "./src/lsp.am" if (isSafeAlnum) { #line 2733 "./src/lsp.am" out = (code_string_concat(out, c)); } else { #line 2739 "./src/lsp.am" i64 cn = String_Length(c); #line 2740 "./src/lsp.am" for (i64 bi = 0LL; bi < cn; bi++) { #line 2741 "./src/lsp.am" code_string b = String_CharAt1(c, bi); #line 2742 "./src/lsp.am" i64 bcode = Amalgame_Compiler_LspServer_AsciiCodeOf(b); #line 2743 "./src/lsp.am" i64 hi = bcode / 16LL; #line 2744 "./src/lsp.am" i64 lo = bcode - (hi * 16LL); #line 2745 "./src/lsp.am" code_string hiCh = String_CharAt1(upper, hi); #line 2746 "./src/lsp.am" code_string loCh = String_CharAt1(upper, lo); #line 2747 "./src/lsp.am" out = (code_string_concat((code_string_concat((code_string_concat(out, "%")), hiCh)), loCh)); } } } #line 2751 "./src/lsp.am" return out; } static code_bool Amalgame_Compiler_LspServer_IsUriSafeChar(code_string c) { #line 2758 "./src/lsp.am" if (String_Length(c) != 1LL) { return 0; } #line 2759 "./src/lsp.am" i64 code = Amalgame_Compiler_LspServer_AsciiCodeOf(c); #line 2760 "./src/lsp.am" if ((code >= 65LL) && (code <= 90LL)) { return 1; } #line 2761 "./src/lsp.am" if ((code >= 97LL) && (code <= 122LL)) { return 1; } #line 2762 "./src/lsp.am" if ((code >= 48LL) && (code <= 57LL)) { return 1; } #line 2763 "./src/lsp.am" if ((((code == 45LL) || (code == 46LL)) || (code == 95LL)) || (code == 126LL)) { return 1; } #line 2764 "./src/lsp.am" if (code == 47LL) { return 1; } #line 2765 "./src/lsp.am" return 0; } static i64 Amalgame_Compiler_LspServer_AsciiCodeOf(code_string c) { #line 2772 "./src/lsp.am" i64 n = String_Length(c); #line 2773 "./src/lsp.am" if (n == 0LL) { return 0LL; } #line 2774 "./src/lsp.am" for (i64 code = 0LL; code < 256LL; code++) { #line 2775 "./src/lsp.am" if (code_string_equals(String_FromByte(code), c)) { return code; } } #line 2777 "./src/lsp.am" return 0LL; } static void Amalgame_Compiler_LspServer_HandleCompletion(Amalgame_Compiler_LspServer* self, i64 id, code_string uri, i64 line, i64 chr) { #line 2795 "./src/lsp.am" code_string source = Amalgame_Compiler_LspServer_LookupDoc(self, uri); #line 2796 "./src/lsp.am" if (String_Length(source) == 0LL) { #line 2797 "./src/lsp.am" Amalgame_Compiler_LspServer_SendEmptyCompletion(self, id); #line 2798 "./src/lsp.am" return; } #line 2800 "./src/lsp.am" code_string path = Amalgame_Compiler_LspServer_UriToPath(uri); #line 2801 "./src/lsp.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(source, path); #line 2802 "./src/lsp.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 2803 "./src/lsp.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 2804 "./src/lsp.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 2805 "./src/lsp.am" prog->Str2 = path; #line 2806 "./src/lsp.am" Amalgame_Compiler_FullResolver* resolver = Amalgame_Compiler_LspServer_BuildWorkspaceResolver(self, path, prog); #line 2813 "./src/lsp.am" if (Amalgame_Compiler_LspServer_IsImportLine(source, line)) { #line 2814 "./src/lsp.am" Amalgame_Compiler_LspServer_SendImportCompletion(self, id); #line 2815 "./src/lsp.am" return; } #line 2821 "./src/lsp.am" code_string receiverType = Amalgame_Compiler_LspServer_ReceiverTypeAt(source, line, chr, resolver); #line 2822 "./src/lsp.am" if ((String_Length(receiverType) > 0LL) && (!code_string_equals(receiverType, "?"))) { #line 2823 "./src/lsp.am" Amalgame_Compiler_LspServer_SendMemberCompletion(self, id, resolver, receiverType); #line 2824 "./src/lsp.am" return; } #line 2829 "./src/lsp.am" Amalgame_Compiler_LspServer_SendGlobalCompletion(self, id, resolver); } static code_bool Amalgame_Compiler_LspServer_IsImportLine(code_string source, i64 line) { #line 2837 "./src/lsp.am" i64 n = String_Length(source); #line 2838 "./src/lsp.am" i64 pos = 0LL; #line 2839 "./src/lsp.am" i64 curLine = 0LL; #line 2840 "./src/lsp.am" i64 lineStart = 0LL; #line 2841 "./src/lsp.am" while (pos < n) { #line 2842 "./src/lsp.am" if (curLine == line) { break; } #line 2843 "./src/lsp.am" code_string c = String_Substring(source, pos, 1LL); #line 2844 "./src/lsp.am" if (code_string_equals(c, "\n")) { #line 2845 "./src/lsp.am" curLine = (curLine + 1LL); #line 2846 "./src/lsp.am" lineStart = (pos + 1LL); } #line 2848 "./src/lsp.am" pos = (pos + 1LL); } #line 2850 "./src/lsp.am" if (curLine != line) { return 0; } #line 2852 "./src/lsp.am" i64 lineEnd = lineStart; #line 2853 "./src/lsp.am" while (lineEnd < n) { #line 2854 "./src/lsp.am" code_string c = String_Substring(source, lineEnd, 1LL); #line 2855 "./src/lsp.am" if (code_string_equals(c, "\n")) { break; } #line 2856 "./src/lsp.am" lineEnd = (lineEnd + 1LL); } #line 2858 "./src/lsp.am" code_string lineText = String_Trim(String_Substring(source, lineStart, lineEnd - lineStart)); #line 2859 "./src/lsp.am" return String_StartsWith(lineText, "import ") || (code_string_equals(lineText, "import")); } static void Amalgame_Compiler_LspServer_SendImportCompletion(Amalgame_Compiler_LspServer* self, i64 id) { #line 2876 "./src/lsp.am" code_string lockPath = code_string_concat(self->CachedRoot, "/amalgame.lock"); #line 2877 "./src/lsp.am" code_string cacheRoot = code_string_concat(Amalgame_Compiler_PackageRegistry_AmalgameHome(), "/packages"); #line 2878 "./src/lsp.am" code_string items = ""; #line 2879 "./src/lsp.am" code_bool first = 1; #line 2880 "./src/lsp.am" AmalgameList* seen = AmalgameList_new(); #line 2881 "./src/lsp.am" if (File_Exists(lockPath)) { #line 2882 "./src/lsp.am" Amalgame_Compiler_PackageRegistry* reg = Amalgame_Compiler_PackageRegistry_LoadFrom(lockPath, cacheRoot); #line 2883 "./src/lsp.am" i64 n = AmalgameList_count(reg->Packages); #line 2884 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 2885 "./src/lsp.am" Amalgame_Compiler_LoadedPackage* p = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(reg->Packages, i); #line 2886 "./src/lsp.am" code_string ns = p->Ns; #line 2887 "./src/lsp.am" if (String_Length(ns) == 0LL) { continue; } #line 2888 "./src/lsp.am" code_string detail = code_string_concat((code_string_concat(p->Name, " @ ")), p->Tag); #line 2890 "./src/lsp.am" if (!first) { items = (code_string_concat(items, ",")); } #line 2891 "./src/lsp.am" items = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(items, "{\"label\":\"")), Amalgame_Compiler_Json_EscapeString(ns))), "\",\"kind\":9,\"detail\":\"")), Amalgame_Compiler_Json_EscapeString(detail))), "\"}")); #line 2892 "./src/lsp.am" AmalgameList_add(seen, (void*)(intptr_t)(ns)); #line 2893 "./src/lsp.am" first = 0; } } #line 2899 "./src/lsp.am" AmalgameList* bundled = Amalgame_Compiler_LspServer_BundledNamespaces(); #line 2900 "./src/lsp.am" i64 bn = AmalgameList_count(bundled); #line 2901 "./src/lsp.am" for (i64 bi = 0LL; bi < bn; bi++) { #line 2902 "./src/lsp.am" code_string ns = (code_string)AmalgameList_get(bundled, bi); #line 2903 "./src/lsp.am" if (Amalgame_Compiler_LspServer_ContainsString(seen, ns)) { continue; } #line 2904 "./src/lsp.am" if (!first) { items = (code_string_concat(items, ",")); } #line 2905 "./src/lsp.am" items = (code_string_concat((code_string_concat((code_string_concat(items, "{\"label\":\"")), Amalgame_Compiler_Json_EscapeString(ns))), "\",\"kind\":9,\"detail\":\"bundled stdlib\"}")); #line 2906 "./src/lsp.am" AmalgameList_add(seen, (void*)(intptr_t)(ns)); #line 2907 "./src/lsp.am" first = 0; } #line 2916 "./src/lsp.am" code_string indexPath = code_string_concat(Amalgame_Compiler_PackageRegistry_AmalgameHome(), "/.amalgame/cache/packages-index.toml"); #line 2917 "./src/lsp.am" if (File_Exists(indexPath)) { #line 2918 "./src/lsp.am" code_string indexSrc = File_ReadAll(indexPath); #line 2919 "./src/lsp.am" if (String_Length(indexSrc) > 0LL) { #line 2920 "./src/lsp.am" Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(indexSrc); #line 2921 "./src/lsp.am" if (!Amalgame_Compiler_TomlValue_IsNull(doc)) { #line 2922 "./src/lsp.am" Amalgame_Compiler_TomlValue* pkgArr = Amalgame_Compiler_TomlValue_Get(doc, "package"); #line 2923 "./src/lsp.am" if (Amalgame_Compiler_TomlValue_IsArray(pkgArr)) { #line 2924 "./src/lsp.am" i64 ni = Amalgame_Compiler_TomlValue_Count(pkgArr); #line 2925 "./src/lsp.am" for (i64 ii = 0LL; ii < ni; ii++) { #line 2926 "./src/lsp.am" Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(pkgArr, ii); #line 2927 "./src/lsp.am" code_string nameS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "name")); #line 2928 "./src/lsp.am" code_string urlS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "url")); #line 2929 "./src/lsp.am" if (String_Length(nameS) == 0LL) { continue; } #line 2930 "./src/lsp.am" code_string ns = Amalgame_Compiler_LspServer_InferNamespaceFromUrl(urlS); #line 2931 "./src/lsp.am" if (String_Length(ns) == 0LL) { continue; } #line 2932 "./src/lsp.am" if (Amalgame_Compiler_LspServer_ContainsString(seen, ns)) { continue; } #line 2933 "./src/lsp.am" if (!first) { items = (code_string_concat(items, ",")); } #line 2934 "./src/lsp.am" code_string detail = code_string_concat("\\u2193 install ", nameS); #line 2935 "./src/lsp.am" items = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(items, "{\"label\":\"")), Amalgame_Compiler_Json_EscapeString(ns))), "\",\"kind\":9,\"detail\":\"")), detail)), "\"}")); #line 2936 "./src/lsp.am" AmalgameList_add(seen, (void*)(intptr_t)(ns)); #line 2937 "./src/lsp.am" first = 0; } } } } } #line 2943 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"isIncomplete\":false,\"items\":[")), items)), "]}}"); #line 2944 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static code_bool Amalgame_Compiler_LspServer_ContainsString(AmalgameList* xs, code_string needle) { #line 2951 "./src/lsp.am" i64 n = AmalgameList_count(xs); #line 2952 "./src/lsp.am" code_bool found = 0; #line 2953 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 2954 "./src/lsp.am" if (code_string_equals((code_string)AmalgameList_get(xs, i), needle)) { found = 1; } } #line 2956 "./src/lsp.am" return found; } static AmalgameList* Amalgame_Compiler_LspServer_BundledNamespaces() { #line 2963 "./src/lsp.am" AmalgameList* xs = AmalgameList_new(); #line 2964 "./src/lsp.am" AmalgameList_add(xs, (void*)(intptr_t)("Amalgame.IO")); #line 2965 "./src/lsp.am" AmalgameList_add(xs, (void*)(intptr_t)("Amalgame.Process")); #line 2966 "./src/lsp.am" AmalgameList_add(xs, (void*)(intptr_t)("Amalgame.String")); #line 2967 "./src/lsp.am" AmalgameList_add(xs, (void*)(intptr_t)("Amalgame.Collections")); #line 2968 "./src/lsp.am" AmalgameList_add(xs, (void*)(intptr_t)("Amalgame.Console")); #line 2969 "./src/lsp.am" AmalgameList_add(xs, (void*)(intptr_t)("Amalgame.Net")); #line 2970 "./src/lsp.am" AmalgameList_add(xs, (void*)(intptr_t)("Amalgame.Path")); #line 2971 "./src/lsp.am" AmalgameList_add(xs, (void*)(intptr_t)("Amalgame.Formats.Json")); #line 2972 "./src/lsp.am" AmalgameList_add(xs, (void*)(intptr_t)("Amalgame.Formats.Toml")); #line 2973 "./src/lsp.am" AmalgameList_add(xs, (void*)(intptr_t)("Amalgame.Formats.Msgpack")); #line 2974 "./src/lsp.am" return xs; } static void Amalgame_Compiler_LspServer_SendGlobalCompletion(Amalgame_Compiler_LspServer* self, i64 id, Amalgame_Compiler_FullResolver* resolver) { #line 2978 "./src/lsp.am" code_string items = ""; #line 2979 "./src/lsp.am" code_bool first = 1; #line 2984 "./src/lsp.am" items = (code_string_concat(items, "{\"label\":\"loop\",\"kind\":15,\"detail\":\"MCU: per-tick loop (arena reset each tick)\",\"insertText\":\"loop {\\n\\t$0\\n}\",\"insertTextFormat\":2}")); #line 2985 "./src/lsp.am" items = (code_string_concat(items, ",{\"label\":\"setup\",\"kind\":15,\"detail\":\"MCU: run-once / persistent setup block\",\"insertText\":\"setup {\\n\\t$0\\n}\",\"insertTextFormat\":2}")); #line 2986 "./src/lsp.am" items = (code_string_concat(items, ",{\"label\":\"region\",\"kind\":15,\"detail\":\"MCU: lexical sub-arena\",\"insertText\":\"region {\\n\\t$0\\n}\",\"insertTextFormat\":2}")); #line 2987 "./src/lsp.am" items = (code_string_concat(items, ",{\"label\":\"persist\",\"kind\":15,\"detail\":\"MCU: keep a value past the tick reset\",\"insertText\":\"persist($0)\",\"insertTextFormat\":2}")); #line 2988 "./src/lsp.am" first = 0; #line 2989 "./src/lsp.am" i64 gn = Amalgame_Compiler_FullResolver_GlobalCount(resolver); #line 2990 "./src/lsp.am" for (i64 gi = 0LL; gi < gn; gi++) { #line 2991 "./src/lsp.am" code_string name = Amalgame_Compiler_FullResolver_GlobalNameAt(resolver, gi); #line 2992 "./src/lsp.am" if (String_Length(name) == 0LL) { continue; } #line 2993 "./src/lsp.am" code_string typeS = Amalgame_Compiler_FullResolver_GlobalTypeAt(resolver, gi); #line 2998 "./src/lsp.am" i64 kind = 6LL; #line 2999 "./src/lsp.am" if (code_string_equals(typeS, "type")) { kind = 7LL; } else if (code_string_equals(typeS, "void")) { #line 3000 "./src/lsp.am" kind = 3LL; } #line 3001 "./src/lsp.am" if (!first) { items = (code_string_concat(items, ",")); } #line 3002 "./src/lsp.am" items = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(items, "{\"label\":\"")), Amalgame_Compiler_Json_EscapeString(name))), "\",\"kind\":")), String_FromInt(kind))), ",\"detail\":\"")), Amalgame_Compiler_Json_EscapeString(typeS))), "\"}")); #line 3003 "./src/lsp.am" first = 0; } #line 3005 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"isIncomplete\":false,\"items\":[")), items)), "]}}"); #line 3006 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } static void Amalgame_Compiler_LspServer_SendMemberCompletion(Amalgame_Compiler_LspServer* self, i64 id, Amalgame_Compiler_FullResolver* resolver, code_string typeName) { #line 3013 "./src/lsp.am" code_string bare = typeName; #line 3014 "./src/lsp.am" if (String_EndsWith(bare, "?")) { #line 3015 "./src/lsp.am" bare = String_Substring(bare, 0LL, String_Length(bare) - 1LL); } #line 3017 "./src/lsp.am" if (String_EndsWith(bare, "*")) { #line 3018 "./src/lsp.am" bare = String_Substring(bare, 0LL, String_Length(bare) - 1LL); } #line 3025 "./src/lsp.am" Amalgame_Compiler_MemberTable* members = resolver->Members; #line 3026 "./src/lsp.am" i64 mc = Amalgame_Compiler_MemberTable_MemberCountFor(members, bare); #line 3027 "./src/lsp.am" if (mc == 0LL) { #line 3031 "./src/lsp.am" Amalgame_Compiler_LspServer_SendEmptyCompletion(self, id); #line 3032 "./src/lsp.am" return; } #line 3034 "./src/lsp.am" code_string items = ""; #line 3035 "./src/lsp.am" code_bool first = 1; #line 3036 "./src/lsp.am" for (i64 i = 0LL; i < mc; i++) { #line 3037 "./src/lsp.am" code_string name = Amalgame_Compiler_MemberTable_MemberNameForAt(members, bare, i); #line 3038 "./src/lsp.am" if (String_Length(name) == 0LL) { continue; } #line 3039 "./src/lsp.am" code_string mtype = Amalgame_Compiler_MemberTable_Get(members, bare, name); #line 3045 "./src/lsp.am" i64 kind = 5LL; #line 3046 "./src/lsp.am" if (((((code_string_equals(mtype, "void")) || (code_string_equals(mtype, "int"))) || (code_string_equals(mtype, "string"))) || (code_string_equals(mtype, "bool"))) || (code_string_equals(mtype, "float"))) { #line 3047 "./src/lsp.am" kind = 2LL; } else if ((String_Length(mtype) > 0LL) && (!code_string_equals(mtype, "?"))) { #line 3049 "./src/lsp.am" kind = 2LL; } #line 3051 "./src/lsp.am" if (!first) { items = (code_string_concat(items, ",")); } #line 3052 "./src/lsp.am" items = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(items, "{\"label\":\"")), Amalgame_Compiler_Json_EscapeString(name))), "\",\"kind\":")), String_FromInt(kind))), ",\"detail\":\"")), Amalgame_Compiler_Json_EscapeString(mtype))), "\"}")); #line 3053 "./src/lsp.am" first = 0; } #line 3055 "./src/lsp.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"isIncomplete\":false,\"items\":[")), items)), "]}}"); #line 3056 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } code_string Amalgame_Compiler_LspServer_ReceiverTypeAt(code_string source, i64 line, i64 chr, Amalgame_Compiler_FullResolver* resolver) { #line 3065 "./src/lsp.am" i64 n = String_Length(source); #line 3066 "./src/lsp.am" i64 lineStart = 0LL; #line 3067 "./src/lsp.am" i64 curLine = 0LL; #line 3068 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 3069 "./src/lsp.am" if (curLine == line) { #line 3070 "./src/lsp.am" lineStart = i; #line 3071 "./src/lsp.am" break; } #line 3073 "./src/lsp.am" code_string c = String_CharAt1(source, i); #line 3074 "./src/lsp.am" if (code_string_equals(c, "\n")) { curLine = (curLine + 1LL); } } #line 3076 "./src/lsp.am" if (curLine != line) { return ""; } #line 3079 "./src/lsp.am" i64 cursorAbs = lineStart + chr; #line 3080 "./src/lsp.am" if ((cursorAbs <= 0LL) || (cursorAbs > n)) { return ""; } #line 3082 "./src/lsp.am" i64 dotPos = cursorAbs - 1LL; #line 3083 "./src/lsp.am" if (dotPos < 0LL) { return ""; } #line 3084 "./src/lsp.am" code_string dotCh = String_CharAt1(source, dotPos); #line 3085 "./src/lsp.am" if (!code_string_equals(dotCh, ".")) { return ""; } #line 3087 "./src/lsp.am" code_string ident = ""; #line 3088 "./src/lsp.am" i64 p = dotPos - 1LL; #line 3089 "./src/lsp.am" while (p >= lineStart) { #line 3090 "./src/lsp.am" code_string c = String_CharAt1(source, p); #line 3091 "./src/lsp.am" if (Amalgame_Compiler_LspServer_IsIdentChar(c)) { #line 3092 "./src/lsp.am" ident = (code_string_concat(c, ident)); #line 3093 "./src/lsp.am" p = (p - 1LL); } else { #line 3094 "./src/lsp.am" break; } } #line 3096 "./src/lsp.am" if (String_Length(ident) == 0LL) { return ""; } #line 3107 "./src/lsp.am" if (code_string_equals(ident, "this")) { #line 3108 "./src/lsp.am" return Amalgame_Compiler_LspServer_EnclosingClassAt(source, cursorAbs); } #line 3110 "./src/lsp.am" if (Amalgame_Compiler_FullResolver_HasSymbol(resolver, ident)) { #line 3111 "./src/lsp.am" code_string t = Amalgame_Compiler_FullResolver_GetTypeName(resolver, ident); #line 3116 "./src/lsp.am" if ((String_Length(t) > 0LL) && (!code_string_equals(t, "?"))) { return t; } } #line 3124 "./src/lsp.am" code_string lt = Amalgame_Compiler_LspServer_ScanLocalDeclType(source, cursorAbs, ident); #line 3125 "./src/lsp.am" if (String_Length(lt) > 0LL) { return lt; } #line 3126 "./src/lsp.am" return ""; } static code_string Amalgame_Compiler_LspServer_EnclosingClassAt(code_string source, i64 before) { #line 3142 "./src/lsp.am" i64 n = String_Length(source); #line 3143 "./src/lsp.am" if (before > n) { before = n; } #line 3147 "./src/lsp.am" AmalgameList* names = AmalgameList_new(); #line 3148 "./src/lsp.am" AmalgameList* depths = AmalgameList_new(); #line 3149 "./src/lsp.am" i64 depth = 0LL; #line 3150 "./src/lsp.am" i64 i = 0LL; #line 3151 "./src/lsp.am" while (i < before) { #line 3152 "./src/lsp.am" code_string c = String_CharAt1(source, i); #line 3153 "./src/lsp.am" if (code_string_equals(c, "{")) { depth = (depth + 1LL); i = (i + 1LL); continue; } #line 3154 "./src/lsp.am" if (code_string_equals(c, "}")) { #line 3155 "./src/lsp.am" depth = (depth - 1LL); #line 3157 "./src/lsp.am" i64 nn = AmalgameList_count(names); #line 3158 "./src/lsp.am" if (nn > 0LL) { #line 3159 "./src/lsp.am" i64 top = (i64)(intptr_t)AmalgameList_get(depths, nn - 1LL); #line 3160 "./src/lsp.am" if (top > depth) { #line 3161 "./src/lsp.am" AmalgameList_removeAt(names, nn - 1LL); #line 3162 "./src/lsp.am" AmalgameList_removeAt(depths, nn - 1LL); } } #line 3165 "./src/lsp.am" i = (i + 1LL); continue; } #line 3172 "./src/lsp.am" if ((code_string_equals(c, "c")) && Amalgame_Compiler_LspServer_MatchKeywordAt(source, i, "class")) { #line 3174 "./src/lsp.am" i64 j = i + 5LL; #line 3175 "./src/lsp.am" while (j < before) { #line 3176 "./src/lsp.am" code_string cj = String_CharAt1(source, j); #line 3177 "./src/lsp.am" if ((code_string_equals(cj, " ")) || (code_string_equals(cj, "\t"))) { j = (j + 1LL); continue; } #line 3178 "./src/lsp.am" break; } #line 3180 "./src/lsp.am" i64 nameStart = j; #line 3181 "./src/lsp.am" while (j < before) { #line 3182 "./src/lsp.am" code_string cj2 = String_CharAt1(source, j); #line 3183 "./src/lsp.am" if (Amalgame_Compiler_LspServer_IsIdentChar(cj2)) { j = (j + 1LL); continue; } #line 3184 "./src/lsp.am" break; } #line 3186 "./src/lsp.am" if (j > nameStart) { #line 3187 "./src/lsp.am" code_string className = String_Substring(source, nameStart, j - nameStart); #line 3189 "./src/lsp.am" while (j < before) { #line 3190 "./src/lsp.am" code_string cj3 = String_CharAt1(source, j); #line 3191 "./src/lsp.am" if (code_string_equals(cj3, "{")) { #line 3192 "./src/lsp.am" depth = (depth + 1LL); #line 3193 "./src/lsp.am" AmalgameList_add(names, (void*)(intptr_t)(className)); #line 3194 "./src/lsp.am" AmalgameList_add(depths, (void*)(intptr_t)(depth)); #line 3195 "./src/lsp.am" j = (j + 1LL); #line 3196 "./src/lsp.am" break; } #line 3198 "./src/lsp.am" j = (j + 1LL); } #line 3200 "./src/lsp.am" i = j; #line 3201 "./src/lsp.am" continue; } } #line 3204 "./src/lsp.am" i = (i + 1LL); } #line 3206 "./src/lsp.am" i64 nf = AmalgameList_count(names); #line 3207 "./src/lsp.am" if (nf == 0LL) { return ""; } #line 3208 "./src/lsp.am" return (code_string)AmalgameList_get(names, nf - 1LL); } static code_bool Amalgame_Compiler_LspServer_MatchKeywordAt(code_string source, i64 pos, code_string kw) { #line 3216 "./src/lsp.am" i64 n = String_Length(source); #line 3217 "./src/lsp.am" i64 kl = String_Length(kw); #line 3218 "./src/lsp.am" if ((pos + kl) > n) { return 0; } #line 3219 "./src/lsp.am" for (i64 ki = 0LL; ki < kl; ki++) { #line 3220 "./src/lsp.am" if (!code_string_equals(String_CharAt1(source, pos + ki), String_CharAt1(kw, ki))) { #line 3221 "./src/lsp.am" return 0; } } #line 3224 "./src/lsp.am" if (pos > 0LL) { #line 3225 "./src/lsp.am" code_string prev = String_CharAt1(source, pos - 1LL); #line 3226 "./src/lsp.am" if (Amalgame_Compiler_LspServer_IsIdentChar(prev)) { return 0; } } #line 3228 "./src/lsp.am" if ((pos + kl) < n) { #line 3229 "./src/lsp.am" code_string next = String_CharAt1(source, pos + kl); #line 3230 "./src/lsp.am" if (Amalgame_Compiler_LspServer_IsIdentChar(next)) { return 0; } } #line 3232 "./src/lsp.am" return 1; } static code_string Amalgame_Compiler_LspServer_ScanLocalDeclType(code_string source, i64 before, code_string ident) { #line 3239 "./src/lsp.am" i64 n = String_Length(source); #line 3240 "./src/lsp.am" if (before > n) { before = n; } #line 3245 "./src/lsp.am" code_string bestType = ""; #line 3246 "./src/lsp.am" AmalgameList* needles = AmalgameList_new(); #line 3247 "./src/lsp.am" AmalgameList_add(needles, (void*)(intptr_t)(code_string_concat("let ", ident))); #line 3248 "./src/lsp.am" AmalgameList_add(needles, (void*)(intptr_t)(code_string_concat("var ", ident))); #line 3249 "./src/lsp.am" i64 nn = AmalgameList_count(needles); #line 3250 "./src/lsp.am" for (i64 ni = 0LL; ni < nn; ni++) { #line 3251 "./src/lsp.am" code_string needle = (code_string)AmalgameList_get(needles, ni); #line 3252 "./src/lsp.am" i64 nlen = String_Length(needle); #line 3253 "./src/lsp.am" i64 pos = 0LL; #line 3254 "./src/lsp.am" while (pos < before) { #line 3255 "./src/lsp.am" i64 idx = String_IndexOf(String_Substring(source, pos, before - pos), needle); #line 3256 "./src/lsp.am" if (idx < 0LL) { break; } #line 3257 "./src/lsp.am" i64 absIdx = pos + idx; #line 3261 "./src/lsp.am" code_bool okStart = (absIdx == 0LL) || !Amalgame_Compiler_LspServer_IsIdentChar(String_CharAt1(source, absIdx - 1LL)); #line 3262 "./src/lsp.am" i64 after = absIdx + nlen; #line 3263 "./src/lsp.am" code_bool okEnd = (after >= n) || !Amalgame_Compiler_LspServer_IsIdentChar(String_CharAt1(source, after)); #line 3264 "./src/lsp.am" if (okStart && okEnd) { #line 3265 "./src/lsp.am" code_string t = Amalgame_Compiler_LspServer_ExtractTypeAfterDecl(source, after, n); #line 3266 "./src/lsp.am" if (String_Length(t) > 0LL) { bestType = t; } } #line 3268 "./src/lsp.am" pos = (absIdx + nlen); } } #line 3271 "./src/lsp.am" return bestType; } static code_string Amalgame_Compiler_LspServer_ExtractTypeAfterDecl(code_string source, i64 start, i64 n) { #line 3278 "./src/lsp.am" i64 i = start; #line 3280 "./src/lsp.am" while (i < n) { #line 3281 "./src/lsp.am" code_string c = String_CharAt1(source, i); #line 3282 "./src/lsp.am" if ((code_string_equals(c, " ")) || (code_string_equals(c, "\t"))) { i = (i + 1LL); } else { break; } } #line 3284 "./src/lsp.am" if (i >= n) { return ""; } #line 3285 "./src/lsp.am" code_string head = String_CharAt1(source, i); #line 3286 "./src/lsp.am" if (code_string_equals(head, ":")) { #line 3287 "./src/lsp.am" i = (i + 1LL); #line 3289 "./src/lsp.am" while (i < n) { #line 3290 "./src/lsp.am" code_string c = String_CharAt1(source, i); #line 3291 "./src/lsp.am" if ((code_string_equals(c, " ")) || (code_string_equals(c, "\t"))) { i = (i + 1LL); } else { break; } } #line 3294 "./src/lsp.am" code_string t = ""; #line 3295 "./src/lsp.am" while (i < n) { #line 3296 "./src/lsp.am" code_string c = String_CharAt1(source, i); #line 3297 "./src/lsp.am" if (Amalgame_Compiler_LspServer_IsIdentChar(c)) { #line 3298 "./src/lsp.am" t = (code_string_concat(t, c)); #line 3299 "./src/lsp.am" i = (i + 1LL); } else { #line 3300 "./src/lsp.am" break; } } #line 3302 "./src/lsp.am" return t; } #line 3304 "./src/lsp.am" if (code_string_equals(head, "=")) { #line 3305 "./src/lsp.am" i = (i + 1LL); #line 3307 "./src/lsp.am" while (i < n) { #line 3308 "./src/lsp.am" code_string c = String_CharAt1(source, i); #line 3309 "./src/lsp.am" if ((code_string_equals(c, " ")) || (code_string_equals(c, "\t"))) { i = (i + 1LL); } else { break; } } #line 3312 "./src/lsp.am" code_string newKw = "new "; #line 3313 "./src/lsp.am" if ((i + 4LL) <= n) { #line 3314 "./src/lsp.am" code_string head4 = String_Substring(source, i, 4LL); #line 3315 "./src/lsp.am" if (code_string_equals(head4, newKw)) { #line 3316 "./src/lsp.am" i = (i + 4LL); #line 3317 "./src/lsp.am" code_string t = ""; #line 3318 "./src/lsp.am" while (i < n) { #line 3319 "./src/lsp.am" code_string c = String_CharAt1(source, i); #line 3320 "./src/lsp.am" if (Amalgame_Compiler_LspServer_IsIdentChar(c)) { #line 3321 "./src/lsp.am" t = (code_string_concat(t, c)); #line 3322 "./src/lsp.am" i = (i + 1LL); } else { #line 3323 "./src/lsp.am" break; } } #line 3325 "./src/lsp.am" return t; } } } #line 3329 "./src/lsp.am" return ""; } static code_bool Amalgame_Compiler_LspServer_IsIdentChar(code_string c) { #line 3333 "./src/lsp.am" if (String_Length(c) == 0LL) { return 0; } #line 3334 "./src/lsp.am" code_string alnum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; #line 3335 "./src/lsp.am" return String_IndexOf(alnum, c) >= 0LL; } static void Amalgame_Compiler_LspServer_SendEmptyCompletion(Amalgame_Compiler_LspServer* self, i64 id) { #line 3339 "./src/lsp.am" code_string body = code_string_concat((code_string_concat("{\"jsonrpc\":\"2.0\",\"id\":", String_FromInt(id))), ",\"result\":{\"isIncomplete\":false,\"items\":[]}}"); #line 3340 "./src/lsp.am" Amalgame_Compiler_LspServer_Send(self, body); } code_string Amalgame_Compiler_LspServer_DiagnosticFromResolver(code_string source, Amalgame_Compiler_ResolverError* e) { #line 3352 "./src/lsp.am" return Amalgame_Compiler_LspServer_DiagnosticBody(source, e->Line, e->Column, e->Message); } code_string Amalgame_Compiler_LspServer_DiagnosticFromTc(code_string source, Amalgame_Compiler_TypeError* e) { #line 3356 "./src/lsp.am" return Amalgame_Compiler_LspServer_DiagnosticBody(source, e->Line, e->Column, e->Message); } static code_string Amalgame_Compiler_LspServer_DiagnosticBody(code_string source, i64 line, i64 col, code_string msg) { #line 3364 "./src/lsp.am" i64 l = line - 1LL; #line 3365 "./src/lsp.am" i64 cStart = col - 1LL; #line 3366 "./src/lsp.am" if (l < 0LL) { l = 0LL; } #line 3367 "./src/lsp.am" if (cStart < 0LL) { cStart = 0LL; } #line 3368 "./src/lsp.am" i64 endCol = Amalgame_Compiler_LspServer_TokenEndCol(source, line, col); #line 3369 "./src/lsp.am" i64 cEnd = endCol - 1LL; #line 3370 "./src/lsp.am" if (cEnd <= cStart) { cEnd = (cStart + 1LL); } #line 3371 "./src/lsp.am" code_string lStr = String_FromInt(l); #line 3372 "./src/lsp.am" code_string cStartStr = String_FromInt(cStart); #line 3373 "./src/lsp.am" code_string cEndStr = String_FromInt(cEnd); #line 3374 "./src/lsp.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"severity\":1,\"range\":{\"start\":{\"line\":", lStr)), ",\"character\":")), cStartStr)), "},\"end\":{\"line\":")), lStr)), ",\"character\":")), cEndStr)), "}},\"message\":\"")), Amalgame_Compiler_Json_EscapeString(msg))), "\"}"); } static i64 Amalgame_Compiler_LspServer_TokenEndCol(code_string source, i64 line, i64 col) { #line 3382 "./src/lsp.am" i64 n = String_Length(source); #line 3383 "./src/lsp.am" i64 off = 0LL; #line 3384 "./src/lsp.am" i64 ln = 1LL; #line 3385 "./src/lsp.am" while ((ln < line) && (off < n)) { #line 3386 "./src/lsp.am" code_string ch = String_CharAt1(source, off); #line 3387 "./src/lsp.am" if (code_string_equals(ch, "\n")) { ln = (ln + 1LL); } #line 3388 "./src/lsp.am" off = (off + 1LL); } #line 3390 "./src/lsp.am" i64 colIdx = 0LL; #line 3391 "./src/lsp.am" while ((colIdx < (col - 1LL)) && (off < n)) { #line 3392 "./src/lsp.am" code_string ch = String_CharAt1(source, off); #line 3393 "./src/lsp.am" if (code_string_equals(ch, "\n")) { break; } #line 3394 "./src/lsp.am" off = (off + 1LL); #line 3395 "./src/lsp.am" colIdx = (colIdx + 1LL); } #line 3397 "./src/lsp.am" i64 endCol = col; #line 3398 "./src/lsp.am" while (off < n) { #line 3399 "./src/lsp.am" code_string ch = String_CharAt1(source, off); #line 3400 "./src/lsp.am" if (Amalgame_Compiler_LspServer_IsWordChar(ch)) { #line 3401 "./src/lsp.am" off = (off + 1LL); #line 3402 "./src/lsp.am" endCol = (endCol + 1LL); } else { #line 3403 "./src/lsp.am" break; } } #line 3405 "./src/lsp.am" return endCol; } static code_bool Amalgame_Compiler_LspServer_IsWordChar(code_string ch) { #line 3409 "./src/lsp.am" if (String_Length(ch) == 0LL) { return 0; } #line 3410 "./src/lsp.am" if (code_string_equals(ch, "_")) { return 1; } #line 3411 "./src/lsp.am" if (String_IndexOf("0123456789", ch) >= 0LL) { return 1; } #line 3412 "./src/lsp.am" if (String_IndexOf("abcdefghijklmnopqrstuvwxyz", ch) >= 0LL) { return 1; } #line 3413 "./src/lsp.am" if (String_IndexOf("ABCDEFGHIJKLMNOPQRSTUVWXYZ", ch) >= 0LL) { return 1; } #line 3414 "./src/lsp.am" return 0; } code_string Amalgame_Compiler_LspServer_UriToPath(code_string uri) { #line 3424 "./src/lsp.am" code_string raw = uri; #line 3425 "./src/lsp.am" if (String_StartsWith(uri, "file://")) { #line 3426 "./src/lsp.am" i64 n = String_Length(uri); #line 3427 "./src/lsp.am" raw = String_Substring(uri, 7LL, n - 7LL); } #line 3429 "./src/lsp.am" return Amalgame_Compiler_LspServer_PercentDecode(raw); } static code_string Amalgame_Compiler_LspServer_PercentDecode(code_string s) { #line 3436 "./src/lsp.am" code_string out = ""; #line 3437 "./src/lsp.am" i64 n = String_Length(s); #line 3438 "./src/lsp.am" i64 i = 0LL; #line 3439 "./src/lsp.am" while (i < n) { #line 3440 "./src/lsp.am" code_string c = String_CharAt1(s, i); #line 3441 "./src/lsp.am" if ((code_string_equals(c, "%")) && ((i + 2LL) < n)) { #line 3442 "./src/lsp.am" code_string h0 = String_CharAt1(s, i + 1LL); #line 3443 "./src/lsp.am" code_string h1 = String_CharAt1(s, i + 2LL); #line 3444 "./src/lsp.am" i64 v0 = Amalgame_Compiler_LspServer_HexDigit(h0); #line 3445 "./src/lsp.am" i64 v1 = Amalgame_Compiler_LspServer_HexDigit(h1); #line 3446 "./src/lsp.am" if ((v0 >= 0LL) && (v1 >= 0LL)) { #line 3447 "./src/lsp.am" i64 b = (v0 * 16LL) + v1; #line 3448 "./src/lsp.am" out = (code_string_concat(out, String_FromByte(b))); #line 3449 "./src/lsp.am" i = (i + 3LL); } else { #line 3451 "./src/lsp.am" out = (code_string_concat(out, c)); #line 3452 "./src/lsp.am" i = (i + 1LL); } } else { #line 3455 "./src/lsp.am" out = (code_string_concat(out, c)); #line 3456 "./src/lsp.am" i = (i + 1LL); } } #line 3459 "./src/lsp.am" return out; } static i64 Amalgame_Compiler_LspServer_HexDigit(code_string c) { #line 3463 "./src/lsp.am" if (code_string_equals(c, "0")) { return 0LL; } #line 3464 "./src/lsp.am" if (code_string_equals(c, "1")) { return 1LL; } #line 3465 "./src/lsp.am" if (code_string_equals(c, "2")) { return 2LL; } #line 3466 "./src/lsp.am" if (code_string_equals(c, "3")) { return 3LL; } #line 3467 "./src/lsp.am" if (code_string_equals(c, "4")) { return 4LL; } #line 3468 "./src/lsp.am" if (code_string_equals(c, "5")) { return 5LL; } #line 3469 "./src/lsp.am" if (code_string_equals(c, "6")) { return 6LL; } #line 3470 "./src/lsp.am" if (code_string_equals(c, "7")) { return 7LL; } #line 3471 "./src/lsp.am" if (code_string_equals(c, "8")) { return 8LL; } #line 3472 "./src/lsp.am" if (code_string_equals(c, "9")) { return 9LL; } #line 3473 "./src/lsp.am" if ((code_string_equals(c, "a")) || (code_string_equals(c, "A"))) { return 10LL; } #line 3474 "./src/lsp.am" if ((code_string_equals(c, "b")) || (code_string_equals(c, "B"))) { return 11LL; } #line 3475 "./src/lsp.am" if ((code_string_equals(c, "c")) || (code_string_equals(c, "C"))) { return 12LL; } #line 3476 "./src/lsp.am" if ((code_string_equals(c, "d")) || (code_string_equals(c, "D"))) { return 13LL; } #line 3477 "./src/lsp.am" if ((code_string_equals(c, "e")) || (code_string_equals(c, "E"))) { return 14LL; } #line 3478 "./src/lsp.am" if ((code_string_equals(c, "f")) || (code_string_equals(c, "F"))) { return 15LL; } #line 3479 "./src/lsp.am" return -1LL; } Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindNodeAtPosition(Amalgame_Compiler_AstNode* root, i64 line, i64 col) { #line 3495 "./src/lsp.am" if (root == NULL) { return NULL; } #line 3496 "./src/lsp.am" Amalgame_Compiler_AstNode* best = NULL; #line 3497 "./src/lsp.am" best = Amalgame_Compiler_LspServer_FindNodeWalk(root, line, col, best); #line 3498 "./src/lsp.am" return best; } code_string Amalgame_Compiler_LspServer_FormatMethodSignatureMarkdown(Amalgame_Compiler_AstNode* method) { #line 3509 "./src/lsp.am" code_string sig = code_string_concat(method->Name, "("); #line 3510 "./src/lsp.am" i64 n = AmalgameList_count(method->Params); #line 3511 "./src/lsp.am" for (i64 i = 0LL; i < n; i++) { #line 3512 "./src/lsp.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, i); #line 3513 "./src/lsp.am" if (i > 0LL) { sig = (code_string_concat(sig, ", ")); } #line 3514 "./src/lsp.am" sig = (code_string_concat(sig, p->Name)); #line 3515 "./src/lsp.am" if (String_Length(p->Str) > 0LL) { #line 3516 "./src/lsp.am" sig = (code_string_concat((code_string_concat(sig, ": ")), p->Str)); } } #line 3519 "./src/lsp.am" sig = (code_string_concat(sig, ")")); #line 3520 "./src/lsp.am" if ((String_Length(method->Str) > 0LL) && (!code_string_equals(method->Str, "void"))) { #line 3521 "./src/lsp.am" sig = (code_string_concat((code_string_concat(sig, ": ")), method->Str)); } #line 3523 "./src/lsp.am" return code_string_concat((code_string_concat("```amalgame\n", sig)), "\n```"); } Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindMethodDeclByName(Amalgame_Compiler_AstNode* prog, code_string methodName) { #line 3533 "./src/lsp.am" if (prog == NULL) { return NULL; } #line 3534 "./src/lsp.am" i64 topN = AmalgameList_count(prog->Children); #line 3535 "./src/lsp.am" for (i64 ti = 0LL; ti < topN; ti++) { #line 3536 "./src/lsp.am" Amalgame_Compiler_AstNode* top = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, ti); #line 3537 "./src/lsp.am" if (top->Kind != Amalgame_Compiler_NodeKind_CLASS_DECL) { continue; } #line 3538 "./src/lsp.am" i64 mn = AmalgameList_count(top->Children); #line 3539 "./src/lsp.am" for (i64 mi = 0LL; mi < mn; mi++) { #line 3540 "./src/lsp.am" Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(top->Children, mi); #line 3541 "./src/lsp.am" if (m->Kind != Amalgame_Compiler_NodeKind_METHOD_DECL) { continue; } #line 3542 "./src/lsp.am" if (code_string_equals(m->Name, methodName)) { return m; } } } #line 3545 "./src/lsp.am" return NULL; } Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindCallAtPosition(Amalgame_Compiler_AstNode* root, i64 line, i64 col) { #line 3555 "./src/lsp.am" if (root == NULL) { return NULL; } #line 3556 "./src/lsp.am" Amalgame_Compiler_AstNode* best = NULL; #line 3557 "./src/lsp.am" best = Amalgame_Compiler_LspServer_FindCallWalk(root, line, col, best); #line 3558 "./src/lsp.am" return best; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindCallWalk(Amalgame_Compiler_AstNode* node, i64 line, i64 col, Amalgame_Compiler_AstNode* best) { #line 3562 "./src/lsp.am" Amalgame_Compiler_AstNode* current = best; #line 3563 "./src/lsp.am" if (node->Kind == Amalgame_Compiler_NodeKind_CALL) { #line 3564 "./src/lsp.am" if ((line > node->Line) || ((line == node->Line) && (col >= node->Column))) { #line 3565 "./src/lsp.am" current = node; } } #line 3568 "./src/lsp.am" if (node->Left != NULL) { current = Amalgame_Compiler_LspServer_FindCallWalk(node->Left, line, col, current); } #line 3569 "./src/lsp.am" if (node->Right != NULL) { current = Amalgame_Compiler_LspServer_FindCallWalk(node->Right, line, col, current); } #line 3570 "./src/lsp.am" if (node->Cond != NULL) { current = Amalgame_Compiler_LspServer_FindCallWalk(node->Cond, line, col, current); } #line 3571 "./src/lsp.am" if (node->Body != NULL) { current = Amalgame_Compiler_LspServer_FindCallWalk(node->Body, line, col, current); } #line 3572 "./src/lsp.am" if (node->Else != NULL) { current = Amalgame_Compiler_LspServer_FindCallWalk(node->Else, line, col, current); } #line 3573 "./src/lsp.am" i64 cn = AmalgameList_count(node->Children); #line 3574 "./src/lsp.am" for (i64 ci = 0LL; ci < cn; ci++) { current = Amalgame_Compiler_LspServer_FindCallWalk((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Children, ci), line, col, current); } #line 3575 "./src/lsp.am" i64 pn = AmalgameList_count(node->Params); #line 3576 "./src/lsp.am" for (i64 pi = 0LL; pi < pn; pi++) { current = Amalgame_Compiler_LspServer_FindCallWalk((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Params, pi), line, col, current); } #line 3577 "./src/lsp.am" i64 an = AmalgameList_count(node->Args); #line 3578 "./src/lsp.am" for (i64 ai = 0LL; ai < an; ai++) { current = Amalgame_Compiler_LspServer_FindCallWalk((Amalgame_Compiler_AstNode*)AmalgameList_get(node->Args, ai), line, col, current); } #line 3579 "./src/lsp.am" return current; } code_string Amalgame_Compiler_LspServer_CallCalleeName(Amalgame_Compiler_AstNode* call) { #line 3588 "./src/lsp.am" if (call == NULL) { return ""; } #line 3589 "./src/lsp.am" if (call->Left == NULL) { return ""; } #line 3590 "./src/lsp.am" Amalgame_Compiler_AstNode* l = call->Left; #line 3591 "./src/lsp.am" if (l->Kind == Amalgame_Compiler_NodeKind_IDENTIFIER) { return l->Name; } #line 3592 "./src/lsp.am" if (l->Kind == Amalgame_Compiler_NodeKind_MEMBER) { return l->Name; } #line 3593 "./src/lsp.am" return ""; } static Amalgame_Compiler_AstNode* Amalgame_Compiler_LspServer_FindNodeWalk(Amalgame_Compiler_AstNode* node, i64 line, i64 col, Amalgame_Compiler_AstNode* best) { #line 3597 "./src/lsp.am" Amalgame_Compiler_AstNode* current = best; #line 3598 "./src/lsp.am" if (Amalgame_Compiler_LspServer_NodeCovers(node, line, col)) { #line 3602 "./src/lsp.am" if (String_Length(node->Name) > 0LL) { #line 3603 "./src/lsp.am" current = node; } else if (current == NULL) { #line 3605 "./src/lsp.am" current = node; } } #line 3609 "./src/lsp.am" if (node->Left != NULL) { current = Amalgame_Compiler_LspServer_FindNodeWalk(node->Left, line, col, current); } #line 3610 "./src/lsp.am" if (node->Right != NULL) { current = Amalgame_Compiler_LspServer_FindNodeWalk(node->Right, line, col, current); } #line 3611 "./src/lsp.am" if (node->Cond != NULL) { current = Amalgame_Compiler_LspServer_FindNodeWalk(node->Cond, line, col, current); } #line 3612 "./src/lsp.am" if (node->Body != NULL) { current = Amalgame_Compiler_LspServer_FindNodeWalk(node->Body, line, col, current); } #line 3613 "./src/lsp.am" if (node->Else != NULL) { current = Amalgame_Compiler_LspServer_FindNodeWalk(node->Else, line, col, current); } #line 3615 "./src/lsp.am" i64 cn = AmalgameList_count(node->Children); #line 3616 "./src/lsp.am" for (i64 ci = 0LL; ci < cn; ci++) { #line 3617 "./src/lsp.am" Amalgame_Compiler_AstNode* c = (Amalgame_Compiler_AstNode*)AmalgameList_get(node->Children, ci); #line 3618 "./src/lsp.am" current = Amalgame_Compiler_LspServer_FindNodeWalk(c, line, col, current); } #line 3620 "./src/lsp.am" i64 pn = AmalgameList_count(node->Params); #line 3621 "./src/lsp.am" for (i64 pi = 0LL; pi < pn; pi++) { #line 3622 "./src/lsp.am" Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(node->Params, pi); #line 3623 "./src/lsp.am" current = Amalgame_Compiler_LspServer_FindNodeWalk(p, line, col, current); } #line 3625 "./src/lsp.am" i64 an = AmalgameList_count(node->Args); #line 3626 "./src/lsp.am" for (i64 ai = 0LL; ai < an; ai++) { #line 3627 "./src/lsp.am" Amalgame_Compiler_AstNode* a = (Amalgame_Compiler_AstNode*)AmalgameList_get(node->Args, ai); #line 3628 "./src/lsp.am" current = Amalgame_Compiler_LspServer_FindNodeWalk(a, line, col, current); } #line 3630 "./src/lsp.am" return current; } static code_bool Amalgame_Compiler_LspServer_NodeCovers(Amalgame_Compiler_AstNode* node, i64 line, i64 col) { #line 3634 "./src/lsp.am" if (node->Line != line) { return 0; } #line 3635 "./src/lsp.am" i64 nameLen = String_Length(node->Name); #line 3636 "./src/lsp.am" if (nameLen == 0LL) { return 0; } #line 3637 "./src/lsp.am" i64 endCol = node->Column + nameLen; #line 3638 "./src/lsp.am" if (col < node->Column) { return 0; } #line 3639 "./src/lsp.am" if (col > endCol) { return 0; } #line 3640 "./src/lsp.am" return 1; } struct _Amalgame_Compiler_MiValue { i64 Kind; code_string Str; AmalgameList* TupleKeys; AmalgameList* TupleVals; AmalgameList* ListKeys; AmalgameList* ListItems; }; Amalgame_Compiler_MiValue* Amalgame_Compiler_MiValue_FieldOrNull(Amalgame_Compiler_MiValue* self, code_string key); code_string Amalgame_Compiler_MiValue_FieldString(Amalgame_Compiler_MiValue* self, code_string key); Amalgame_Compiler_MiValue* Amalgame_Compiler_MiValue_new() { Amalgame_Compiler_MiValue* self = (Amalgame_Compiler_MiValue*) GC_MALLOC(sizeof(Amalgame_Compiler_MiValue)); #line 56 "./src/dap/mi_parser.am" self->Kind = 0LL; #line 57 "./src/dap/mi_parser.am" self->Str = ""; #line 58 "./src/dap/mi_parser.am" self->TupleKeys = AmalgameList_new(); #line 59 "./src/dap/mi_parser.am" self->TupleVals = AmalgameList_new(); #line 60 "./src/dap/mi_parser.am" self->ListKeys = AmalgameList_new(); #line 61 "./src/dap/mi_parser.am" self->ListItems = AmalgameList_new(); return self; } Amalgame_Compiler_MiValue* Amalgame_Compiler_MiValue_FieldOrNull(Amalgame_Compiler_MiValue* self, code_string key) { #line 68 "./src/dap/mi_parser.am" i64 n = AmalgameList_count(self->TupleKeys); #line 69 "./src/dap/mi_parser.am" Amalgame_Compiler_MiValue* found = NULL; #line 70 "./src/dap/mi_parser.am" for (i64 i = 0LL; i < n; i++) { #line 71 "./src/dap/mi_parser.am" if (code_string_equals((code_string)AmalgameList_get(self->TupleKeys, i), key)) { found = (Amalgame_Compiler_MiValue*)AmalgameList_get(self->TupleVals, i); } } #line 73 "./src/dap/mi_parser.am" return found; } code_string Amalgame_Compiler_MiValue_FieldString(Amalgame_Compiler_MiValue* self, code_string key) { #line 79 "./src/dap/mi_parser.am" Amalgame_Compiler_MiValue* v = Amalgame_Compiler_MiValue_FieldOrNull(self, key); #line 80 "./src/dap/mi_parser.am" if (v == NULL) { return ""; } #line 81 "./src/dap/mi_parser.am" if (v->Kind != 0LL) { return ""; } #line 82 "./src/dap/mi_parser.am" return v->Str; } struct _Amalgame_Compiler_MiRecord { i64 RecordKind; i64 Token; code_string Class; AmalgameList* Results; AmalgameList* Values; code_string StreamText; }; Amalgame_Compiler_MiValue* Amalgame_Compiler_MiRecord_ResultOrNull(Amalgame_Compiler_MiRecord* self, code_string key); Amalgame_Compiler_MiRecord* Amalgame_Compiler_MiRecord_new() { Amalgame_Compiler_MiRecord* self = (Amalgame_Compiler_MiRecord*) GC_MALLOC(sizeof(Amalgame_Compiler_MiRecord)); #line 113 "./src/dap/mi_parser.am" self->RecordKind = 0LL; #line 114 "./src/dap/mi_parser.am" self->Token = -1LL; #line 115 "./src/dap/mi_parser.am" self->Class = ""; #line 116 "./src/dap/mi_parser.am" self->Results = AmalgameList_new(); #line 117 "./src/dap/mi_parser.am" self->Values = AmalgameList_new(); #line 118 "./src/dap/mi_parser.am" self->StreamText = ""; return self; } Amalgame_Compiler_MiValue* Amalgame_Compiler_MiRecord_ResultOrNull(Amalgame_Compiler_MiRecord* self, code_string key) { #line 124 "./src/dap/mi_parser.am" i64 n = AmalgameList_count(self->Results); #line 125 "./src/dap/mi_parser.am" Amalgame_Compiler_MiValue* found = NULL; #line 126 "./src/dap/mi_parser.am" for (i64 i = 0LL; i < n; i++) { #line 127 "./src/dap/mi_parser.am" if (code_string_equals((code_string)AmalgameList_get(self->Results, i), key)) { found = (Amalgame_Compiler_MiValue*)AmalgameList_get(self->Values, i); } } #line 129 "./src/dap/mi_parser.am" return found; } struct _Amalgame_Compiler_MiParser { code_string Input; i64 Pos; }; static code_string Amalgame_Compiler_MiParser_Peek(Amalgame_Compiler_MiParser* self); static code_bool Amalgame_Compiler_MiParser_IsAlpha(code_string c); static code_bool Amalgame_Compiler_MiParser_IsDigit(code_string c); static code_bool Amalgame_Compiler_MiParser_IsOctalDigit(code_string c); static code_string Amalgame_Compiler_MiParser_ParseIdent(Amalgame_Compiler_MiParser* self); static code_string Amalgame_Compiler_MiParser_ParseCString(Amalgame_Compiler_MiParser* self); Amalgame_Compiler_MiValue* Amalgame_Compiler_MiParser_ParseValue(Amalgame_Compiler_MiParser* self); static Amalgame_Compiler_MiValue* Amalgame_Compiler_MiParser_ParseTuple(Amalgame_Compiler_MiParser* self); static Amalgame_Compiler_MiValue* Amalgame_Compiler_MiParser_ParseList(Amalgame_Compiler_MiParser* self); Amalgame_Compiler_MiRecord* Amalgame_Compiler_MiParser_ParseRecord(Amalgame_Compiler_MiParser* self); static void Amalgame_Compiler_MiParser_ParseResultList(Amalgame_Compiler_MiParser* self, Amalgame_Compiler_MiRecord* rec); Amalgame_Compiler_MiParser* Amalgame_Compiler_MiParser_new(code_string input) { Amalgame_Compiler_MiParser* self = (Amalgame_Compiler_MiParser*) GC_MALLOC(sizeof(Amalgame_Compiler_MiParser)); #line 140 "./src/dap/mi_parser.am" self->Input = input; #line 141 "./src/dap/mi_parser.am" self->Pos = 0LL; return self; } static code_string Amalgame_Compiler_MiParser_Peek(Amalgame_Compiler_MiParser* self) { #line 148 "./src/dap/mi_parser.am" if (self->Pos >= String_Length(self->Input)) { return ""; } #line 149 "./src/dap/mi_parser.am" return String_Substring(self->Input, self->Pos, 1LL); } static code_bool Amalgame_Compiler_MiParser_IsAlpha(code_string c) { #line 158 "./src/dap/mi_parser.am" if (String_Length(c) == 0LL) { return 0; } #line 159 "./src/dap/mi_parser.am" return String_IndexOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", c) >= 0LL; } static code_bool Amalgame_Compiler_MiParser_IsDigit(code_string c) { #line 162 "./src/dap/mi_parser.am" if (String_Length(c) == 0LL) { return 0; } #line 163 "./src/dap/mi_parser.am" return String_IndexOf("0123456789", c) >= 0LL; } static code_bool Amalgame_Compiler_MiParser_IsOctalDigit(code_string c) { #line 166 "./src/dap/mi_parser.am" if (String_Length(c) == 0LL) { return 0; } #line 167 "./src/dap/mi_parser.am" return String_IndexOf("01234567", c) >= 0LL; } static code_string Amalgame_Compiler_MiParser_ParseIdent(Amalgame_Compiler_MiParser* self) { #line 174 "./src/dap/mi_parser.am" code_string out = ""; #line 175 "./src/dap/mi_parser.am" while (self->Pos < String_Length(self->Input)) { #line 176 "./src/dap/mi_parser.am" code_string c = String_Substring(self->Input, self->Pos, 1LL); #line 177 "./src/dap/mi_parser.am" code_bool isAlpha = Amalgame_Compiler_MiParser_IsAlpha(c); #line 178 "./src/dap/mi_parser.am" code_bool isDigit = Amalgame_Compiler_MiParser_IsDigit(c); #line 179 "./src/dap/mi_parser.am" code_bool isMore = (code_string_equals(c, "_")) || (code_string_equals(c, "-")); #line 180 "./src/dap/mi_parser.am" if ((isAlpha || isDigit) || isMore) { #line 181 "./src/dap/mi_parser.am" out = (code_string_concat(out, c)); #line 182 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); } else { #line 183 "./src/dap/mi_parser.am" break; } } #line 185 "./src/dap/mi_parser.am" return out; } static code_string Amalgame_Compiler_MiParser_ParseCString(Amalgame_Compiler_MiParser* self) { #line 195 "./src/dap/mi_parser.am" if (!code_string_equals(Amalgame_Compiler_MiParser_Peek(self), "\"")) { return ""; } #line 196 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 197 "./src/dap/mi_parser.am" code_string out = ""; #line 198 "./src/dap/mi_parser.am" i64 n = String_Length(self->Input); #line 199 "./src/dap/mi_parser.am" while (self->Pos < n) { #line 200 "./src/dap/mi_parser.am" code_string c = String_Substring(self->Input, self->Pos, 1LL); #line 201 "./src/dap/mi_parser.am" if (code_string_equals(c, "\"")) { #line 202 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 203 "./src/dap/mi_parser.am" return out; } #line 205 "./src/dap/mi_parser.am" if (code_string_equals(c, "\\")) { #line 206 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 207 "./src/dap/mi_parser.am" if (self->Pos >= n) { #line 209 "./src/dap/mi_parser.am" out = (code_string_concat(out, "\\")); #line 210 "./src/dap/mi_parser.am" return out; } #line 212 "./src/dap/mi_parser.am" code_string esc = String_Substring(self->Input, self->Pos, 1LL); #line 220 "./src/dap/mi_parser.am" if (Amalgame_Compiler_MiParser_IsOctalDigit(esc)) { #line 221 "./src/dap/mi_parser.am" i64 b = String_ToInt(esc); #line 222 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 223 "./src/dap/mi_parser.am" if (self->Pos < n) { #line 224 "./src/dap/mi_parser.am" code_string c2 = String_Substring(self->Input, self->Pos, 1LL); #line 225 "./src/dap/mi_parser.am" if (Amalgame_Compiler_MiParser_IsOctalDigit(c2)) { #line 226 "./src/dap/mi_parser.am" b = ((b * 8LL) + String_ToInt(c2)); #line 227 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 228 "./src/dap/mi_parser.am" if (self->Pos < n) { #line 229 "./src/dap/mi_parser.am" code_string c3 = String_Substring(self->Input, self->Pos, 1LL); #line 230 "./src/dap/mi_parser.am" if (Amalgame_Compiler_MiParser_IsOctalDigit(c3)) { #line 231 "./src/dap/mi_parser.am" b = ((b * 8LL) + String_ToInt(c3)); #line 232 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); } } } } #line 237 "./src/dap/mi_parser.am" out = (code_string_concat(out, String_FromByte(b))); #line 238 "./src/dap/mi_parser.am" continue; } #line 240 "./src/dap/mi_parser.am" if (code_string_equals(esc, "n")) { out = (code_string_concat(out, "\n")); } else if (code_string_equals(esc, "t")) { #line 241 "./src/dap/mi_parser.am" out = (code_string_concat(out, "\t")); } else if (code_string_equals(esc, "r")) { #line 242 "./src/dap/mi_parser.am" out = (code_string_concat(out, "\r")); } else if (code_string_equals(esc, "\"")) { #line 243 "./src/dap/mi_parser.am" out = (code_string_concat(out, "\"")); } else if (code_string_equals(esc, "\\")) { #line 244 "./src/dap/mi_parser.am" out = (code_string_concat(out, "\\")); } else { #line 245 "./src/dap/mi_parser.am" out = (code_string_concat(out, esc)); } #line 246 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 247 "./src/dap/mi_parser.am" continue; } #line 249 "./src/dap/mi_parser.am" out = (code_string_concat(out, c)); #line 250 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); } #line 252 "./src/dap/mi_parser.am" return out; } Amalgame_Compiler_MiValue* Amalgame_Compiler_MiParser_ParseValue(Amalgame_Compiler_MiParser* self) { #line 257 "./src/dap/mi_parser.am" code_string c = Amalgame_Compiler_MiParser_Peek(self); #line 258 "./src/dap/mi_parser.am" if (code_string_equals(c, "\"")) { #line 259 "./src/dap/mi_parser.am" Amalgame_Compiler_MiValue* v = Amalgame_Compiler_MiValue_new(); #line 260 "./src/dap/mi_parser.am" v->Kind = 0LL; #line 261 "./src/dap/mi_parser.am" v->Str = Amalgame_Compiler_MiParser_ParseCString(self); #line 262 "./src/dap/mi_parser.am" return v; } #line 264 "./src/dap/mi_parser.am" if (code_string_equals(c, "{")) { return Amalgame_Compiler_MiParser_ParseTuple(self); } #line 265 "./src/dap/mi_parser.am" if (code_string_equals(c, "[")) { return Amalgame_Compiler_MiParser_ParseList(self); } #line 269 "./src/dap/mi_parser.am" return Amalgame_Compiler_MiValue_new(); } static Amalgame_Compiler_MiValue* Amalgame_Compiler_MiParser_ParseTuple(Amalgame_Compiler_MiParser* self) { #line 273 "./src/dap/mi_parser.am" Amalgame_Compiler_MiValue* v = Amalgame_Compiler_MiValue_new(); #line 274 "./src/dap/mi_parser.am" v->Kind = 1LL; #line 275 "./src/dap/mi_parser.am" if (!code_string_equals(Amalgame_Compiler_MiParser_Peek(self), "{")) { return v; } #line 276 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 277 "./src/dap/mi_parser.am" if (code_string_equals(Amalgame_Compiler_MiParser_Peek(self), "}")) { #line 278 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 279 "./src/dap/mi_parser.am" return v; } #line 281 "./src/dap/mi_parser.am" i64 n = String_Length(self->Input); #line 282 "./src/dap/mi_parser.am" while (self->Pos < n) { #line 283 "./src/dap/mi_parser.am" code_string key = Amalgame_Compiler_MiParser_ParseIdent(self); #line 284 "./src/dap/mi_parser.am" if (code_string_equals(Amalgame_Compiler_MiParser_Peek(self), "=")) { self->Pos = (self->Pos + 1LL); } #line 285 "./src/dap/mi_parser.am" Amalgame_Compiler_MiValue* val = Amalgame_Compiler_MiParser_ParseValue(self); #line 286 "./src/dap/mi_parser.am" AmalgameList_add(v->TupleKeys, (void*)(intptr_t)(key)); #line 287 "./src/dap/mi_parser.am" AmalgameList_add(v->TupleVals, (void*)(intptr_t)(val)); #line 288 "./src/dap/mi_parser.am" if (code_string_equals(Amalgame_Compiler_MiParser_Peek(self), ",")) { #line 289 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 290 "./src/dap/mi_parser.am" continue; } #line 292 "./src/dap/mi_parser.am" if (code_string_equals(Amalgame_Compiler_MiParser_Peek(self), "}")) { #line 293 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 294 "./src/dap/mi_parser.am" return v; } #line 296 "./src/dap/mi_parser.am" break; } #line 298 "./src/dap/mi_parser.am" return v; } static Amalgame_Compiler_MiValue* Amalgame_Compiler_MiParser_ParseList(Amalgame_Compiler_MiParser* self) { #line 302 "./src/dap/mi_parser.am" Amalgame_Compiler_MiValue* v = Amalgame_Compiler_MiValue_new(); #line 303 "./src/dap/mi_parser.am" v->Kind = 2LL; #line 304 "./src/dap/mi_parser.am" if (!code_string_equals(Amalgame_Compiler_MiParser_Peek(self), "[")) { return v; } #line 305 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 306 "./src/dap/mi_parser.am" if (code_string_equals(Amalgame_Compiler_MiParser_Peek(self), "]")) { #line 307 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 308 "./src/dap/mi_parser.am" return v; } #line 310 "./src/dap/mi_parser.am" i64 n = String_Length(self->Input); #line 311 "./src/dap/mi_parser.am" while (self->Pos < n) { #line 316 "./src/dap/mi_parser.am" i64 savedPos = self->Pos; #line 317 "./src/dap/mi_parser.am" code_string maybeKey = Amalgame_Compiler_MiParser_ParseIdent(self); #line 318 "./src/dap/mi_parser.am" if ((String_Length(maybeKey) > 0LL) && (code_string_equals(Amalgame_Compiler_MiParser_Peek(self), "="))) { #line 319 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 320 "./src/dap/mi_parser.am" Amalgame_Compiler_MiValue* val = Amalgame_Compiler_MiParser_ParseValue(self); #line 321 "./src/dap/mi_parser.am" AmalgameList_add(v->ListKeys, (void*)(intptr_t)(maybeKey)); #line 322 "./src/dap/mi_parser.am" AmalgameList_add(v->ListItems, (void*)(intptr_t)(val)); } else { #line 324 "./src/dap/mi_parser.am" self->Pos = savedPos; #line 325 "./src/dap/mi_parser.am" Amalgame_Compiler_MiValue* val = Amalgame_Compiler_MiParser_ParseValue(self); #line 326 "./src/dap/mi_parser.am" AmalgameList_add(v->ListKeys, (void*)(intptr_t)("")); #line 327 "./src/dap/mi_parser.am" AmalgameList_add(v->ListItems, (void*)(intptr_t)(val)); } #line 329 "./src/dap/mi_parser.am" if (code_string_equals(Amalgame_Compiler_MiParser_Peek(self), ",")) { #line 330 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 331 "./src/dap/mi_parser.am" continue; } #line 333 "./src/dap/mi_parser.am" if (code_string_equals(Amalgame_Compiler_MiParser_Peek(self), "]")) { #line 334 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 335 "./src/dap/mi_parser.am" return v; } #line 337 "./src/dap/mi_parser.am" break; } #line 339 "./src/dap/mi_parser.am" return v; } Amalgame_Compiler_MiRecord* Amalgame_Compiler_MiParser_ParseRecord(Amalgame_Compiler_MiParser* self) { #line 345 "./src/dap/mi_parser.am" Amalgame_Compiler_MiRecord* rec = Amalgame_Compiler_MiRecord_new(); #line 347 "./src/dap/mi_parser.am" code_string tokenStr = ""; #line 348 "./src/dap/mi_parser.am" while (self->Pos < String_Length(self->Input)) { #line 349 "./src/dap/mi_parser.am" code_string c = String_Substring(self->Input, self->Pos, 1LL); #line 350 "./src/dap/mi_parser.am" if (Amalgame_Compiler_MiParser_IsDigit(c)) { #line 351 "./src/dap/mi_parser.am" tokenStr = (code_string_concat(tokenStr, c)); #line 352 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); } else { #line 353 "./src/dap/mi_parser.am" break; } } #line 355 "./src/dap/mi_parser.am" if (String_Length(tokenStr) > 0LL) { #line 356 "./src/dap/mi_parser.am" rec->Token = String_ToInt(tokenStr); } #line 358 "./src/dap/mi_parser.am" code_string prefix = Amalgame_Compiler_MiParser_Peek(self); #line 359 "./src/dap/mi_parser.am" if (code_string_equals(prefix, "^")) { rec->RecordKind = 0LL; } else if (code_string_equals(prefix, "*")) { #line 360 "./src/dap/mi_parser.am" rec->RecordKind = 1LL; } else if (code_string_equals(prefix, "+")) { #line 361 "./src/dap/mi_parser.am" rec->RecordKind = 2LL; } else if (code_string_equals(prefix, "=")) { #line 362 "./src/dap/mi_parser.am" rec->RecordKind = 3LL; } else if (code_string_equals(prefix, "~")) { #line 363 "./src/dap/mi_parser.am" rec->RecordKind = 4LL; } else if (code_string_equals(prefix, "@")) { #line 364 "./src/dap/mi_parser.am" rec->RecordKind = 5LL; } else if (code_string_equals(prefix, "&")) { #line 365 "./src/dap/mi_parser.am" rec->RecordKind = 6LL; } else if (code_string_equals(prefix, "(")) { #line 368 "./src/dap/mi_parser.am" rec->RecordKind = 7LL; #line 369 "./src/dap/mi_parser.am" return rec; } else { #line 373 "./src/dap/mi_parser.am" return rec; } #line 375 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 377 "./src/dap/mi_parser.am" if (((rec->RecordKind == 4LL) || (rec->RecordKind == 5LL)) || (rec->RecordKind == 6LL)) { #line 378 "./src/dap/mi_parser.am" rec->StreamText = Amalgame_Compiler_MiParser_ParseCString(self); #line 379 "./src/dap/mi_parser.am" return rec; } #line 382 "./src/dap/mi_parser.am" rec->Class = Amalgame_Compiler_MiParser_ParseIdent(self); #line 383 "./src/dap/mi_parser.am" if (code_string_equals(Amalgame_Compiler_MiParser_Peek(self), ",")) { #line 384 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); #line 385 "./src/dap/mi_parser.am" Amalgame_Compiler_MiParser_ParseResultList(self, rec); } #line 387 "./src/dap/mi_parser.am" return rec; } static void Amalgame_Compiler_MiParser_ParseResultList(Amalgame_Compiler_MiParser* self, Amalgame_Compiler_MiRecord* rec) { #line 391 "./src/dap/mi_parser.am" i64 n = String_Length(self->Input); #line 392 "./src/dap/mi_parser.am" while (self->Pos < n) { #line 393 "./src/dap/mi_parser.am" code_string key = Amalgame_Compiler_MiParser_ParseIdent(self); #line 394 "./src/dap/mi_parser.am" if (String_Length(key) == 0LL) { break; } #line 395 "./src/dap/mi_parser.am" if (code_string_equals(Amalgame_Compiler_MiParser_Peek(self), "=")) { self->Pos = (self->Pos + 1LL); } #line 396 "./src/dap/mi_parser.am" Amalgame_Compiler_MiValue* val = Amalgame_Compiler_MiParser_ParseValue(self); #line 397 "./src/dap/mi_parser.am" AmalgameList_add(rec->Results, (void*)(intptr_t)(key)); #line 398 "./src/dap/mi_parser.am" AmalgameList_add(rec->Values, (void*)(intptr_t)(val)); #line 399 "./src/dap/mi_parser.am" if (!code_string_equals(Amalgame_Compiler_MiParser_Peek(self), ",")) { break; } #line 400 "./src/dap/mi_parser.am" self->Pos = (self->Pos + 1LL); } } struct _Amalgame_Compiler_DapServer { code_bool Raw; code_bool ShowRuntime; code_string McuTarget; code_string OpenocdCfg; code_string ConnectCmd; code_bool McuSettling; i64 GdbInFd; i64 GdbOutFd; i64 GdbPid; code_bool StopRequested; code_bool StdinOpen; code_string DapInputBuf; code_string GdbInputBuf; i64 NextMiToken; AmalgameList* MiTokens; AmalgameList* MiTokensReq; AmalgameList* MiTokensKind; i64 _outSeqCounter; code_bool BkptInFlight; i64 BkptInFlightSeq; code_string BkptInFlightSource; i64 BkptInFlightPending; AmalgameList* BkptInFlightDapShape; AmalgameList* BkptKnownNumbers; i64 StepBudget; i64 PendingVars_Seq; AmalgameList* PendingVars_Names; AmalgameList* PendingVars_Types; AmalgameList* PendingVars_Values; AmalgameList* PendingVars_Queries; AmalgameList* PendingVars_Refs; i64 PendingVars_Idx; AmalgameList* ChildRef_Refs; AmalgameList* ChildRef_Types; AmalgameList* ChildRef_Addrs; AmalgameList* ChildRef_Sizes; i64 NextChildRef; i64 MapDisc_Seq; code_string MapDisc_Kind; code_string MapDisc_BaseExpr; i64 MapDisc_Capacity; i64 MapDisc_SlotIdx; AmalgameList* MapDisc_Occupied; }; i64 Amalgame_Compiler_DapServer_Run(Amalgame_Compiler_DapServer* self); static code_bool Amalgame_Compiler_DapServer_HasFlag(Amalgame_Compiler_DapServer* self, code_string needle); static i64 Amalgame_Compiler_DapServer_RunSelfTestMi(); static void Amalgame_Compiler_DapServer_ParseFlags(Amalgame_Compiler_DapServer* self); i64 Amalgame_Compiler_DapServer_RunBridge(Amalgame_Compiler_DapServer* self); static i64 Amalgame_Compiler_DapServer_SpawnGdb(Amalgame_Compiler_DapServer* self, code_string gdbPath); static i64 Amalgame_Compiler_DapServer_PollLoop(Amalgame_Compiler_DapServer* self); static i64 Amalgame_Compiler_DapServer_PollOnce(Amalgame_Compiler_DapServer* self); static code_string Amalgame_Compiler_DapServer_ReadFromFd(Amalgame_Compiler_DapServer* self, i64 which); void Amalgame_Compiler_DapServer_WriteToFd(Amalgame_Compiler_DapServer* self, i64 which, code_string s); void Amalgame_Compiler_DapServer_CloseGdbStdin(Amalgame_Compiler_DapServer* self); static void Amalgame_Compiler_DapServer_OnDapInput(Amalgame_Compiler_DapServer* self, code_string chunk); static code_string Amalgame_Compiler_DapServer_Crlf(); static code_string Amalgame_Compiler_DapServer_CrlfCrlf(); static code_string Amalgame_Compiler_DapServer_TryExtractDapFrame(Amalgame_Compiler_DapServer* self); void Amalgame_Compiler_DapServer_SendDapFrame(Amalgame_Compiler_DapServer* self, code_string body); static void Amalgame_Compiler_DapServer_OnGdbOutput(Amalgame_Compiler_DapServer* self, code_string chunk); static void Amalgame_Compiler_DapServer_HandleMiLine(Amalgame_Compiler_DapServer* self, code_string line); static void Amalgame_Compiler_DapServer_HandleMiResult(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_HandleMiExecAsync(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_HandleMiNotifyAsync(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static code_bool Amalgame_Compiler_DapServer_IsHiddenFrameFunc(Amalgame_Compiler_DapServer* self, code_string funcS); static void Amalgame_Compiler_DapServer_EmitStoppedEvent(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static i64 Amalgame_Compiler_DapServer_IssueMiCommand(Amalgame_Compiler_DapServer* self, i64 dapSeq, code_string command, code_string mi); static i64 Amalgame_Compiler_DapServer_FindMiTokenIndex(Amalgame_Compiler_DapServer* self, i64 tok); static void Amalgame_Compiler_DapServer_ReleaseMiTokenAt(Amalgame_Compiler_DapServer* self, i64 idx); static void Amalgame_Compiler_DapServer_HandleDapMessage(Amalgame_Compiler_DapServer* self, code_string body); static void Amalgame_Compiler_DapServer_SendDapAck(Amalgame_Compiler_DapServer* self, i64 seq, code_string command); static void Amalgame_Compiler_DapServer_HandleTerminate(Amalgame_Compiler_DapServer* self, i64 seq); static void Amalgame_Compiler_DapServer_HandleThreads(Amalgame_Compiler_DapServer* self, i64 seq); static void Amalgame_Compiler_DapServer_HandleContinue(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleStep(Amalgame_Compiler_DapServer* self, i64 seq, code_string dapCmd, code_string miCmd); static void Amalgame_Compiler_DapServer_HandlePause(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleLaunch(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleSetBreakpoints(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_RespondSetBreakpoints(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_SendBkptResponse(Amalgame_Compiler_DapServer* self, i64 seq, AmalgameList* entries); static void Amalgame_Compiler_DapServer_HandleSetFunctionBreakpoints(Amalgame_Compiler_DapServer* self, i64 seq); static void Amalgame_Compiler_DapServer_HandleSetExceptionBreakpoints(Amalgame_Compiler_DapServer* self, i64 seq); static void Amalgame_Compiler_DapServer_HandleConfigurationDone(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleStackTrace(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleScopes(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleVariables(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleChildVariables(Amalgame_Compiler_DapServer* self, i64 seq, i64 vref); static void Amalgame_Compiler_DapServer_StartMapDiscovery(Amalgame_Compiler_DapServer* self, i64 seq, code_string kind, code_string baseExpr); static void Amalgame_Compiler_DapServer_HandleMapDiscCapResponse(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_FireNextSlotProbe(Amalgame_Compiler_DapServer* self); static void Amalgame_Compiler_DapServer_HandleMapDiscSlotResponse(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_EmitMapChildren(Amalgame_Compiler_DapServer* self); static void Amalgame_Compiler_DapServer_FinishMapDiscoveryEmpty(Amalgame_Compiler_DapServer* self); static void Amalgame_Compiler_DapServer_FailMapDiscovery(Amalgame_Compiler_DapServer* self, code_string msg); static void Amalgame_Compiler_DapServer_ResetMapDiscovery(Amalgame_Compiler_DapServer* self); static i64 Amalgame_Compiler_DapServer_FindChildRefIndex(Amalgame_Compiler_DapServer* self, i64 vref); static i64 Amalgame_Compiler_DapServer_AllocChildRef(Amalgame_Compiler_DapServer* self, code_string typeS, code_string addr, i64 size); static void Amalgame_Compiler_DapServer_HandleEvaluate(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_RespondLaunch(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_RespondConfigurationDone(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_RespondStackTrace(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_RespondVariables(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_ProcessNextVarFollowup(Amalgame_Compiler_DapServer* self); static code_string Amalgame_Compiler_DapServer_PrettyPrintQuery(code_string name, code_string typeS); static code_string Amalgame_Compiler_DapServer_PrettyPrintFormat(code_string typeS, code_string evalResult); static void Amalgame_Compiler_DapServer_HandleVarFollowupResponse(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec); static code_string Amalgame_Compiler_DapServer_ContainerKind(code_string typeS); static void Amalgame_Compiler_DapServer_RewriteRefAt(Amalgame_Compiler_DapServer* self, i64 idx, i64 newRef); static void Amalgame_Compiler_DapServer_RewriteValueAt(Amalgame_Compiler_DapServer* self, i64 idx, code_string newValue); static void Amalgame_Compiler_DapServer_SendVariablesResponse(Amalgame_Compiler_DapServer* self); static void Amalgame_Compiler_DapServer_RespondEvaluate(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec); static void Amalgame_Compiler_DapServer_HandleInitialize(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_HandleDisconnect(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args); static void Amalgame_Compiler_DapServer_SendDapErrorResponse(Amalgame_Compiler_DapServer* self, i64 seq, code_string command, code_string reason); static i64 Amalgame_Compiler_DapServer_NextOutSeq(Amalgame_Compiler_DapServer* self); static void Amalgame_Compiler_DapServer_Cleanup(Amalgame_Compiler_DapServer* self); i64 Amalgame_Compiler_DapServer_RunRaw(Amalgame_Compiler_DapServer* self); static code_string Amalgame_Compiler_DapServer_DetectBackend(Amalgame_Compiler_DapServer* self); static code_string Amalgame_Compiler_DapServer_Probe(code_string candidate); static i64 Amalgame_Compiler_DapServer_ExecBackend(Amalgame_Compiler_DapServer* self, code_string exe); Amalgame_Compiler_DapServer* Amalgame_Compiler_DapServer_new() { Amalgame_Compiler_DapServer* self = (Amalgame_Compiler_DapServer*) GC_MALLOC(sizeof(Amalgame_Compiler_DapServer)); #line 181 "./src/dap.am" self->Raw = 0; #line 182 "./src/dap.am" self->ShowRuntime = 0; #line 183 "./src/dap.am" self->McuTarget = ""; #line 184 "./src/dap.am" self->OpenocdCfg = ""; #line 185 "./src/dap.am" self->ConnectCmd = ""; #line 186 "./src/dap.am" self->McuSettling = 0; #line 187 "./src/dap.am" self->GdbInFd = -1LL; #line 188 "./src/dap.am" self->GdbOutFd = -1LL; #line 189 "./src/dap.am" self->GdbPid = -1LL; #line 190 "./src/dap.am" self->StopRequested = 0; #line 191 "./src/dap.am" self->StdinOpen = 1; #line 192 "./src/dap.am" self->DapInputBuf = ""; #line 193 "./src/dap.am" self->GdbInputBuf = ""; #line 194 "./src/dap.am" self->NextMiToken = 100LL; #line 195 "./src/dap.am" self->MiTokens = AmalgameList_new(); #line 196 "./src/dap.am" self->MiTokensReq = AmalgameList_new(); #line 197 "./src/dap.am" self->MiTokensKind = AmalgameList_new(); #line 198 "./src/dap.am" self->_outSeqCounter = 0LL; #line 199 "./src/dap.am" self->BkptInFlight = 0; #line 200 "./src/dap.am" self->BkptInFlightSeq = -1LL; #line 201 "./src/dap.am" self->BkptInFlightSource = ""; #line 202 "./src/dap.am" self->BkptInFlightPending = 0LL; #line 203 "./src/dap.am" self->BkptInFlightDapShape = AmalgameList_new(); #line 204 "./src/dap.am" self->BkptKnownNumbers = AmalgameList_new(); #line 205 "./src/dap.am" self->StepBudget = 0LL; #line 206 "./src/dap.am" self->PendingVars_Seq = -1LL; #line 207 "./src/dap.am" self->PendingVars_Names = AmalgameList_new(); #line 208 "./src/dap.am" self->PendingVars_Types = AmalgameList_new(); #line 209 "./src/dap.am" self->PendingVars_Values = AmalgameList_new(); #line 210 "./src/dap.am" self->PendingVars_Queries = AmalgameList_new(); #line 211 "./src/dap.am" self->PendingVars_Refs = AmalgameList_new(); #line 212 "./src/dap.am" self->PendingVars_Idx = 0LL; #line 213 "./src/dap.am" self->ChildRef_Refs = AmalgameList_new(); #line 214 "./src/dap.am" self->ChildRef_Types = AmalgameList_new(); #line 215 "./src/dap.am" self->ChildRef_Addrs = AmalgameList_new(); #line 216 "./src/dap.am" self->ChildRef_Sizes = AmalgameList_new(); #line 217 "./src/dap.am" self->NextChildRef = 1000LL; #line 218 "./src/dap.am" self->MapDisc_Seq = -1LL; #line 219 "./src/dap.am" self->MapDisc_Kind = ""; #line 220 "./src/dap.am" self->MapDisc_BaseExpr = ""; #line 221 "./src/dap.am" self->MapDisc_Capacity = 0LL; #line 222 "./src/dap.am" self->MapDisc_SlotIdx = 0LL; #line 223 "./src/dap.am" self->MapDisc_Occupied = AmalgameList_new(); return self; } i64 Amalgame_Compiler_DapServer_Run(Amalgame_Compiler_DapServer* self) { #line 229 "./src/dap.am" Amalgame_Compiler_DapServer_ParseFlags(self); #line 234 "./src/dap.am" if (Amalgame_Compiler_DapServer_HasFlag(self, "--self-test-mi")) { #line 235 "./src/dap.am" return Amalgame_Compiler_DapServer_RunSelfTestMi(); } #line 237 "./src/dap.am" if (self->Raw) { #line 238 "./src/dap.am" return Amalgame_Compiler_DapServer_RunRaw(self); } #line 240 "./src/dap.am" return Amalgame_Compiler_DapServer_RunBridge(self); } static code_bool Amalgame_Compiler_DapServer_HasFlag(Amalgame_Compiler_DapServer* self, code_string needle) { #line 247 "./src/dap.am" code_bool found = 0; #line 248 "./src/dap.am" { /* inline-C */ for (int i = 2; i < code_argc; i++) { if (code_argv[i] == NULL) continue; if (strcmp(code_argv[i], (const char*) needle) == 0) { found = 1; break; } } } #line 257 "./src/dap.am" return found; } static i64 Amalgame_Compiler_DapServer_RunSelfTestMi() { #line 269 "./src/dap.am" i64 failures = 0LL; #line 271 "./src/dap.am" code_string in1 = "1^done,bkpt={number=\"1\",file=\"hello.c\",line=\"5\"}"; #line 272 "./src/dap.am" Amalgame_Compiler_MiParser* p1 = Amalgame_Compiler_MiParser_new(in1); #line 273 "./src/dap.am" Amalgame_Compiler_MiRecord* r1 = Amalgame_Compiler_MiParser_ParseRecord(p1); #line 274 "./src/dap.am" if (((r1->Token == 1LL) && (r1->RecordKind == 0LL)) && (code_string_equals(r1->Class, "done"))) { #line 275 "./src/dap.am" Amalgame_Compiler_MiValue* bkpt = Amalgame_Compiler_MiRecord_ResultOrNull(r1, "bkpt"); #line 276 "./src/dap.am" if (((((bkpt != NULL) && (bkpt->Kind == 1LL)) && (code_string_equals(Amalgame_Compiler_MiValue_FieldString(bkpt, "number"), "1"))) && (code_string_equals(Amalgame_Compiler_MiValue_FieldString(bkpt, "file"), "hello.c"))) && (code_string_equals(Amalgame_Compiler_MiValue_FieldString(bkpt, "line"), "5"))) { #line 280 "./src/dap.am" Console_WriteLine("[PASS] mi: result with tuple field"); } else { #line 282 "./src/dap.am" Console_WriteLine("[FAIL] mi: result tuple fields"); #line 283 "./src/dap.am" failures = (failures + 1LL); } } else { #line 286 "./src/dap.am" Console_WriteLine("[FAIL] mi: result envelope (token/kind/class)"); #line 287 "./src/dap.am" failures = (failures + 1LL); } #line 290 "./src/dap.am" code_string in2 = "*stopped,reason=\"breakpoint-hit\",frame={addr=\"0x4007a0\",func=\"main\",file=\"hello.c\",line=\"5\"},thread-id=\"1\""; #line 291 "./src/dap.am" Amalgame_Compiler_MiParser* p2 = Amalgame_Compiler_MiParser_new(in2); #line 292 "./src/dap.am" Amalgame_Compiler_MiRecord* r2 = Amalgame_Compiler_MiParser_ParseRecord(p2); #line 293 "./src/dap.am" if (((r2->RecordKind == 1LL) && (code_string_equals(r2->Class, "stopped"))) && (r2->Token == -1LL)) { #line 295 "./src/dap.am" code_string reason = ""; #line 296 "./src/dap.am" i64 nResults = AmalgameList_count(r2->Results); #line 297 "./src/dap.am" code_bool seenReason = 0; #line 298 "./src/dap.am" code_bool seenTid = 0; #line 299 "./src/dap.am" for (i64 i = 0LL; i < nResults; i++) { #line 300 "./src/dap.am" Amalgame_Compiler_MiValue* v = (Amalgame_Compiler_MiValue*)AmalgameList_get(r2->Values, i); #line 301 "./src/dap.am" if ((code_string_equals((code_string)AmalgameList_get(r2->Results, i), "reason")) && (code_string_equals(v->Str, "breakpoint-hit"))) { seenReason = 1; } #line 302 "./src/dap.am" if ((code_string_equals((code_string)AmalgameList_get(r2->Results, i), "thread-id")) && (code_string_equals(v->Str, "1"))) { seenTid = 1; } } #line 304 "./src/dap.am" Amalgame_Compiler_MiValue* frame = Amalgame_Compiler_MiRecord_ResultOrNull(r2, "frame"); #line 305 "./src/dap.am" if (((seenReason && seenTid) && (frame != NULL)) && (code_string_equals(Amalgame_Compiler_MiValue_FieldString(frame, "func"), "main"))) { #line 306 "./src/dap.am" Console_WriteLine("[PASS] mi: stopped event w/ nested frame"); } else { #line 308 "./src/dap.am" Console_WriteLine("[FAIL] mi: stopped event fields"); #line 309 "./src/dap.am" failures = (failures + 1LL); } } else { #line 312 "./src/dap.am" Console_WriteLine("[FAIL] mi: stopped event envelope"); #line 313 "./src/dap.am" failures = (failures + 1LL); } #line 316 "./src/dap.am" code_string in3 = "^done,stack=[frame={level=\"0\",func=\"f0\"},frame={level=\"1\",func=\"f1\"}]"; #line 317 "./src/dap.am" Amalgame_Compiler_MiParser* p3 = Amalgame_Compiler_MiParser_new(in3); #line 318 "./src/dap.am" Amalgame_Compiler_MiRecord* r3 = Amalgame_Compiler_MiParser_ParseRecord(p3); #line 319 "./src/dap.am" Amalgame_Compiler_MiValue* stack = Amalgame_Compiler_MiRecord_ResultOrNull(r3, "stack"); #line 320 "./src/dap.am" if (((((((stack != NULL) && (stack->Kind == 2LL)) && (AmalgameList_count(stack->ListItems) == 2LL)) && (code_string_equals((code_string)AmalgameList_get(stack->ListKeys, 0LL), "frame"))) && (code_string_equals((code_string)AmalgameList_get(stack->ListKeys, 1LL), "frame"))) && (code_string_equals(Amalgame_Compiler_MiValue_FieldString((Amalgame_Compiler_MiValue*)AmalgameList_get(stack->ListItems, 0LL), "func"), "f0"))) && (code_string_equals(Amalgame_Compiler_MiValue_FieldString((Amalgame_Compiler_MiValue*)AmalgameList_get(stack->ListItems, 1LL), "func"), "f1"))) { #line 324 "./src/dap.am" Console_WriteLine("[PASS] mi: stack=[frame=…,frame=…]"); } else { #line 326 "./src/dap.am" Console_WriteLine("[FAIL] mi: keyed-list parsing"); #line 327 "./src/dap.am" failures = (failures + 1LL); } #line 330 "./src/dap.am" code_string in4 = "^done,locals=[{name=\"A\",value=\"1\"},{name=\"B\",value=\"2\"}]"; #line 331 "./src/dap.am" Amalgame_Compiler_MiParser* p4 = Amalgame_Compiler_MiParser_new(in4); #line 332 "./src/dap.am" Amalgame_Compiler_MiRecord* r4 = Amalgame_Compiler_MiParser_ParseRecord(p4); #line 333 "./src/dap.am" Amalgame_Compiler_MiValue* locs = Amalgame_Compiler_MiRecord_ResultOrNull(r4, "locals"); #line 334 "./src/dap.am" if (((((((locs != NULL) && (locs->Kind == 2LL)) && (AmalgameList_count(locs->ListItems) == 2LL)) && (code_string_equals((code_string)AmalgameList_get(locs->ListKeys, 0LL), ""))) && (code_string_equals((code_string)AmalgameList_get(locs->ListKeys, 1LL), ""))) && (code_string_equals(Amalgame_Compiler_MiValue_FieldString((Amalgame_Compiler_MiValue*)AmalgameList_get(locs->ListItems, 0LL), "name"), "A"))) && (code_string_equals(Amalgame_Compiler_MiValue_FieldString((Amalgame_Compiler_MiValue*)AmalgameList_get(locs->ListItems, 1LL), "value"), "2"))) { #line 338 "./src/dap.am" Console_WriteLine("[PASS] mi: locals=[{…},{…}]"); } else { #line 340 "./src/dap.am" Console_WriteLine("[FAIL] mi: bare-tuple-list parsing"); #line 341 "./src/dap.am" failures = (failures + 1LL); } #line 344 "./src/dap.am" code_string in5 = "~\"Breakpoint 1 at 0x4007a0: file hello.c, line 5.\\n\""; #line 345 "./src/dap.am" Amalgame_Compiler_MiParser* p5 = Amalgame_Compiler_MiParser_new(in5); #line 346 "./src/dap.am" Amalgame_Compiler_MiRecord* r5 = Amalgame_Compiler_MiParser_ParseRecord(p5); #line 347 "./src/dap.am" if (((r5->RecordKind == 4LL) && (String_IndexOf(r5->StreamText, "Breakpoint 1") == 0LL)) && (String_IndexOf(r5->StreamText, "\n") >= 0LL)) { #line 349 "./src/dap.am" Console_WriteLine("[PASS] mi: console-stream w/ \\n escape"); } else { #line 351 "./src/dap.am" Console_WriteLine("[FAIL] mi: stream unescape"); #line 352 "./src/dap.am" failures = (failures + 1LL); } #line 355 "./src/dap.am" code_string in6 = "(gdb)"; #line 356 "./src/dap.am" Amalgame_Compiler_MiParser* p6 = Amalgame_Compiler_MiParser_new(in6); #line 357 "./src/dap.am" Amalgame_Compiler_MiRecord* r6 = Amalgame_Compiler_MiParser_ParseRecord(p6); #line 358 "./src/dap.am" if (r6->RecordKind == 7LL) { #line 359 "./src/dap.am" Console_WriteLine("[PASS] mi: (gdb) prompt"); } else { #line 361 "./src/dap.am" Console_WriteLine("[FAIL] mi: (gdb) prompt detection"); #line 362 "./src/dap.am" failures = (failures + 1LL); } #line 365 "./src/dap.am" code_string in7 = "^done,foo={},bar=[]"; #line 366 "./src/dap.am" Amalgame_Compiler_MiParser* p7 = Amalgame_Compiler_MiParser_new(in7); #line 367 "./src/dap.am" Amalgame_Compiler_MiRecord* r7 = Amalgame_Compiler_MiParser_ParseRecord(p7); #line 368 "./src/dap.am" Amalgame_Compiler_MiValue* foo = Amalgame_Compiler_MiRecord_ResultOrNull(r7, "foo"); #line 369 "./src/dap.am" Amalgame_Compiler_MiValue* bar = Amalgame_Compiler_MiRecord_ResultOrNull(r7, "bar"); #line 370 "./src/dap.am" if ((((((foo != NULL) && (foo->Kind == 1LL)) && (AmalgameList_count(foo->TupleKeys) == 0LL)) && (bar != NULL)) && (bar->Kind == 2LL)) && (AmalgameList_count(bar->ListItems) == 0LL)) { #line 372 "./src/dap.am" Console_WriteLine("[PASS] mi: empty {} and []"); } else { #line 374 "./src/dap.am" Console_WriteLine("[FAIL] mi: empty containers"); #line 375 "./src/dap.am" failures = (failures + 1LL); } #line 378 "./src/dap.am" code_string in8 = "^done,msg=\"he said \\\"hi\\\"\""; #line 379 "./src/dap.am" Amalgame_Compiler_MiParser* p8 = Amalgame_Compiler_MiParser_new(in8); #line 380 "./src/dap.am" Amalgame_Compiler_MiRecord* r8 = Amalgame_Compiler_MiParser_ParseRecord(p8); #line 381 "./src/dap.am" Amalgame_Compiler_MiValue* msgVal = Amalgame_Compiler_MiRecord_ResultOrNull(r8, "msg"); #line 382 "./src/dap.am" code_string msg = ""; #line 383 "./src/dap.am" if (msgVal != NULL) { msg = msgVal->Str; } #line 384 "./src/dap.am" if (code_string_equals(msg, "he said \"hi\"")) { #line 385 "./src/dap.am" Console_WriteLine("[PASS] mi: escaped \\\" inside string"); } else { #line 387 "./src/dap.am" Console_WriteLine(code_string_concat((code_string_concat("[FAIL] mi: escape inside string (got '", msg)), "')")); #line 388 "./src/dap.am" failures = (failures + 1LL); } #line 395 "./src/dap.am" code_string in9 = "^done,path=\"/tmp/D\\303\\251v\""; #line 396 "./src/dap.am" Amalgame_Compiler_MiParser* p9 = Amalgame_Compiler_MiParser_new(in9); #line 397 "./src/dap.am" Amalgame_Compiler_MiRecord* r9 = Amalgame_Compiler_MiParser_ParseRecord(p9); #line 398 "./src/dap.am" Amalgame_Compiler_MiValue* pathVal = Amalgame_Compiler_MiRecord_ResultOrNull(r9, "path"); #line 399 "./src/dap.am" code_string path = ""; #line 400 "./src/dap.am" if (pathVal != NULL) { path = pathVal->Str; } #line 404 "./src/dap.am" code_string expected = code_string_concat((code_string_concat((code_string_concat("/tmp/D", String_FromByte(195LL))), String_FromByte(169LL))), "v"); #line 405 "./src/dap.am" if (code_string_equals(path, expected)) { #line 406 "./src/dap.am" Console_WriteLine("[PASS] mi: octal \\NNN escape (UTF-8 byte)"); } else { #line 408 "./src/dap.am" Console_WriteLine(code_string_concat((code_string_concat("[FAIL] mi: octal escape (got '", path)), "')")); #line 409 "./src/dap.am" failures = (failures + 1LL); } #line 411 "./src/dap.am" if (failures > 0LL) { #line 412 "./src/dap.am" Console_WriteError(code_string_concat((code_string_concat("amc dap --self-test-mi: ", String_FromInt(failures))), " case(s) failed")); #line 413 "./src/dap.am" return 1LL; } #line 415 "./src/dap.am" return 0LL; } static void Amalgame_Compiler_DapServer_ParseFlags(Amalgame_Compiler_DapServer* self) { #line 423 "./src/dap.am" { /* inline-C */ for (int i = 2; i < code_argc; i++) { if (code_argv[i] == NULL) continue; const char* a = code_argv[i]; if (strcmp(a, "--raw") == 0) { self->Raw = 1; } else if (strcmp(a, "--show-runtime") == 0) { self->ShowRuntime = 1; } else if (strncmp(a, "--target=", 9) == 0) { self->McuTarget = code_strdup(a + 9); /* MCU on-chip debug */ } else if (strncmp(a, "--openocd=", 10) == 0) { self->OpenocdCfg = code_strdup(a + 10); } // `--bridge` is recognised in the argv scan below // (so it's stripped from the backend's view) — it's // a no-op flag while Phase 1 ships, kept for forward // compat with scripts. } return; } } i64 Amalgame_Compiler_DapServer_RunBridge(Amalgame_Compiler_DapServer* self) { #line 463 "./src/dap.am" code_string gdbPath = ""; #line 464 "./src/dap.am" if (String_Length(self->McuTarget) > 0LL) { #line 467 "./src/dap.am" gdbPath = Amalgame_Compiler_DapServer_Probe("arm-none-eabi-gdb"); #line 468 "./src/dap.am" if (String_Length(gdbPath) == 0LL) { gdbPath = Amalgame_Compiler_DapServer_Probe("gdb-multiarch"); } #line 469 "./src/dap.am" if (String_Length(gdbPath) == 0LL) { #line 470 "./src/dap.am" Console_WriteError("amc dap --target: need an ARM gdb on PATH."); #line 471 "./src/dap.am" Console_WriteError(" install: sudo apt install gdb-multiarch (also: openocd)"); #line 472 "./src/dap.am" Console_WriteError(" or run: tools/mcu-setup.sh"); #line 473 "./src/dap.am" return 1LL; } #line 475 "./src/dap.am" if (String_Length(self->OpenocdCfg) == 0LL) { #line 476 "./src/dap.am" Console_WriteError("amc dap --target: need --openocd= (e.g. board/st_nucleo_f7.cfg)"); #line 477 "./src/dap.am" return 1LL; } #line 479 "./src/dap.am" self->ConnectCmd = (code_string_concat((code_string_concat("target extended-remote | openocd -f ", self->OpenocdCfg)), " -c \"gdb_port pipe\"")); #line 480 "./src/dap.am" self->McuSettling = 1; } else { #line 482 "./src/dap.am" gdbPath = Amalgame_Compiler_DapServer_Probe("gdb"); #line 483 "./src/dap.am" if (String_Length(gdbPath) == 0LL) { #line 487 "./src/dap.am" return Amalgame_Compiler_DapServer_RunRaw(self); } } #line 490 "./src/dap.am" i64 spawnRc = Amalgame_Compiler_DapServer_SpawnGdb(self, gdbPath); #line 491 "./src/dap.am" if (spawnRc != 0LL) { #line 492 "./src/dap.am" return spawnRc; } #line 494 "./src/dap.am" return Amalgame_Compiler_DapServer_PollLoop(self); } static i64 Amalgame_Compiler_DapServer_SpawnGdb(Amalgame_Compiler_DapServer* self, code_string gdbPath) { #line 505 "./src/dap.am" { /* inline-C */ #ifdef _WIN32 (void) gdbPath; return 1; // bridge not supported on Windows; caller falls back to --raw #else int parentToChild[2]; // parent writes, child reads → gdb stdin int childToParent[2]; // child writes, parent reads → gdb stdout // pipe(2) + FD_CLOEXEC via fcntl — pipe2(2) is Linux/glibc // only, not portable to macOS. The two-syscall variant is // race-free enough for our single-threaded bridge spawn. if (pipe(parentToChild) < 0) { perror("amc dap --bridge: pipe in"); return 1; } fcntl(parentToChild[0], F_SETFD, FD_CLOEXEC); fcntl(parentToChild[1], F_SETFD, FD_CLOEXEC); if (pipe(childToParent) < 0) { perror("amc dap --bridge: pipe out"); close(parentToChild[0]); close(parentToChild[1]); return 1; } fcntl(childToParent[0], F_SETFD, FD_CLOEXEC); fcntl(childToParent[1], F_SETFD, FD_CLOEXEC); pid_t pid = fork(); if (pid < 0) { perror("amc dap --bridge: fork"); close(parentToChild[0]); close(parentToChild[1]); close(childToParent[0]); close(childToParent[1]); return 1; } if (pid == 0) { // Child — wire pipes to stdin/stdout, exec gdb. // dup2 clears O_CLOEXEC on the target FDs (0, 1) so // they survive the exec. The original pipe FDs still // have O_CLOEXEC set so they auto-close. We also // close them explicitly for clarity. if (dup2(parentToChild[0], 0) < 0) { perror("dup2 stdin"); _exit(127); } if (dup2(childToParent[1], 1) < 0) { perror("dup2 stdout"); _exit(127); } close(parentToChild[0]); close(parentToChild[1]); close(childToParent[0]); close(childToParent[1]); /* Own process group so cleanup can kill gdb AND its * children (e.g. an OpenOCD spawned via `| openocd` pipe * mode) in one shot, freeing the ST-LINK for the next * session. Without this, an orphaned openocd holds the * probe and the next launch fails to flash. */ setpgid(0, 0); /* MCU: extra -ex connects to the chip via OpenOCD pipe mode * at startup (gdb spawns openocd; inner quotes handled by * the shell gdb runs after the `|`). */ if (self->ConnectCmd != NULL && self->ConnectCmd[0] != '\0') { // Connect to the chip at startup (a single -ex; NO // `define` macro — in MI mode a multi-line define-via-ex // wedges gdb in command-definition mode and it stops // answering MI). load + reset + continue are issued as // separate MI commands at configurationDone instead. execlp((const char*) gdbPath, "gdb", "--interpreter=mi3", "--nx", "--quiet", "-ex", (const char*) self->ConnectCmd, (char*) NULL); } else { execlp((const char*) gdbPath, "gdb", "--interpreter=mi3", "--nx", "--quiet", (char*) NULL); } perror("amc dap --bridge: execlp gdb"); _exit(127); } // Parent — close the child-side FDs, stash the rest. close(parentToChild[0]); close(childToParent[1]); self->GdbInFd = parentToChild[1]; self->GdbOutFd = childToParent[0]; self->GdbPid = (i64) pid; // SIGPIPE on a closed stdout (client disconnected) would // kill us silently; turn it into a regular EPIPE that // PollLoop catches via POLLHUP/read==-1. signal(SIGPIPE, SIG_IGN); return 0; #endif } } static i64 Amalgame_Compiler_DapServer_PollLoop(Amalgame_Compiler_DapServer* self) { #line 592 "./src/dap.am" while (!self->StopRequested) { #line 593 "./src/dap.am" i64 what = Amalgame_Compiler_DapServer_PollOnce(self); #line 594 "./src/dap.am" if (what == 0LL) { #line 597 "./src/dap.am" code_string chunk = Amalgame_Compiler_DapServer_ReadFromFd(self, 0LL); #line 598 "./src/dap.am" if (String_Length(chunk) == 0LL) { #line 599 "./src/dap.am" self->StdinOpen = 0; #line 600 "./src/dap.am" Amalgame_Compiler_DapServer_CloseGdbStdin(self); } else { #line 602 "./src/dap.am" Amalgame_Compiler_DapServer_OnDapInput(self, chunk); } } else if (what == 1LL) { #line 607 "./src/dap.am" code_string chunk = Amalgame_Compiler_DapServer_ReadFromFd(self, 1LL); #line 608 "./src/dap.am" if (String_Length(chunk) == 0LL) { break; } #line 609 "./src/dap.am" Amalgame_Compiler_DapServer_OnGdbOutput(self, chunk); } else if (what == 2LL) { #line 613 "./src/dap.am" self->StdinOpen = 0; #line 614 "./src/dap.am" Amalgame_Compiler_DapServer_CloseGdbStdin(self); } else if (what == 3LL) { #line 617 "./src/dap.am" break; } else { #line 619 "./src/dap.am" break; } } #line 622 "./src/dap.am" Amalgame_Compiler_DapServer_Cleanup(self); #line 623 "./src/dap.am" return 0LL; } static i64 Amalgame_Compiler_DapServer_PollOnce(Amalgame_Compiler_DapServer* self) { #line 631 "./src/dap.am" { /* inline-C */ #ifdef _WIN32 return 4; // unreachable: bridge stubs out on Windows #else struct pollfd fds[2]; fds[0].fd = self->StdinOpen ? 0 : -1; fds[0].events = POLLIN; fds[1].fd = (int) self->GdbOutFd; fds[1].events = POLLIN; for (;;) { fds[0].revents = 0; fds[1].revents = 0; int pr = poll(fds, 2, -1); if (pr < 0) { if (errno == EINTR) continue; perror("amc dap --bridge: poll"); return 4; } // Prioritise gdb POLLHUP over POLLIN so we exit cleanly // when gdb crashes mid-response. if (fds[1].revents & (POLLHUP | POLLERR)) return 3; if (fds[0].revents & (POLLHUP | POLLERR) && !(fds[0].revents & POLLIN)) return 2; if (fds[1].revents & POLLIN) return 1; if (fds[0].revents & POLLIN) return 0; // Spurious wake — loop. } #endif } } static code_string Amalgame_Compiler_DapServer_ReadFromFd(Amalgame_Compiler_DapServer* self, i64 which) { #line 667 "./src/dap.am" { /* inline-C */ #ifdef _WIN32 (void) which; return (code_string) ""; #else int fd = (which == 0) ? 0 : (int) self->GdbOutFd; char buf[16384]; ssize_t n; for (;;) { n = read(fd, buf, sizeof(buf)); if (n < 0 && errno == EINTR) continue; break; } if (n <= 0) { return (code_string) ""; } char* r = (char*) GC_MALLOC((size_t) n + 1); if (r == NULL) { return (code_string) ""; } memcpy(r, buf, (size_t) n); r[n] = '\0'; return (code_string) r; #endif } } void Amalgame_Compiler_DapServer_WriteToFd(Amalgame_Compiler_DapServer* self, i64 which, code_string s) { #line 699 "./src/dap.am" { /* inline-C */ #ifdef _WIN32 // Stdout-only fallback path for the raw / non-bridge code // emits via Console.Write* elsewhere. The bridge never runs // here, so the gdb-stdin branch is dead — silently no-op. if (which == 2) { fputs((const char*) s, stdout); fflush(stdout); } #else int fd = (which == 1) ? (int) self->GdbInFd : 1; if (fd < 0) { return; } const char* p = (const char*) s; size_t len = strlen(p); size_t off = 0; while (off < len) { ssize_t w = write(fd, p + off, len - off); if (w < 0) { if (errno == EINTR) continue; self->StopRequested = 1; break; } off += (size_t) w; } #endif } } void Amalgame_Compiler_DapServer_CloseGdbStdin(Amalgame_Compiler_DapServer* self) { #line 730 "./src/dap.am" { /* inline-C */ #ifndef _WIN32 if (self->GdbInFd >= 0) { close((int) self->GdbInFd); self->GdbInFd = -1; } #endif } } static void Amalgame_Compiler_DapServer_OnDapInput(Amalgame_Compiler_DapServer* self, code_string chunk) { #line 746 "./src/dap.am" self->DapInputBuf = (code_string_concat(self->DapInputBuf, chunk)); #line 747 "./src/dap.am" while (1) { #line 748 "./src/dap.am" code_string body = Amalgame_Compiler_DapServer_TryExtractDapFrame(self); #line 749 "./src/dap.am" if (String_Length(body) == 0LL) { break; } #line 750 "./src/dap.am" Amalgame_Compiler_DapServer_HandleDapMessage(self, body); } } static code_string Amalgame_Compiler_DapServer_Crlf() { #line 766 "./src/dap.am" return code_string_concat(String_FromByte(13LL), "\n"); } static code_string Amalgame_Compiler_DapServer_CrlfCrlf() { #line 767 "./src/dap.am" return code_string_concat(Amalgame_Compiler_DapServer_Crlf(), Amalgame_Compiler_DapServer_Crlf()); } static code_string Amalgame_Compiler_DapServer_TryExtractDapFrame(Amalgame_Compiler_DapServer* self) { #line 770 "./src/dap.am" code_string buf = self->DapInputBuf; #line 771 "./src/dap.am" i64 headEnd = String_IndexOf(buf, Amalgame_Compiler_DapServer_CrlfCrlf()); #line 772 "./src/dap.am" if (headEnd < 0LL) { return ""; } #line 773 "./src/dap.am" code_string header = String_Substring(buf, 0LL, headEnd); #line 774 "./src/dap.am" code_string needle = "Content-Length:"; #line 775 "./src/dap.am" i64 lpi = String_IndexOf(header, needle); #line 776 "./src/dap.am" if (lpi < 0LL) { #line 778 "./src/dap.am" self->DapInputBuf = String_Substring(buf, headEnd + 4LL, (String_Length(buf) - headEnd) - 4LL); #line 779 "./src/dap.am" return ""; } #line 781 "./src/dap.am" i64 valueStart = lpi + String_Length(needle); #line 782 "./src/dap.am" i64 lenN = 0LL; #line 783 "./src/dap.am" i64 i = valueStart; #line 785 "./src/dap.am" while (i < String_Length(header)) { #line 786 "./src/dap.am" code_string c = String_Substring(header, i, 1LL); #line 787 "./src/dap.am" if ((code_string_equals(c, " ")) || (code_string_equals(c, "\t"))) { i = (i + 1LL); } else { break; } } #line 789 "./src/dap.am" while (i < String_Length(header)) { #line 790 "./src/dap.am" code_string c = String_Substring(header, i, 1LL); #line 791 "./src/dap.am" if (Amalgame_Compiler_MiParser_IsDigit(c)) { #line 792 "./src/dap.am" lenN = ((lenN * 10LL) + String_ToInt(c)); #line 793 "./src/dap.am" i = (i + 1LL); } else { #line 794 "./src/dap.am" break; } } #line 796 "./src/dap.am" i64 bodyStart = headEnd + 4LL; #line 797 "./src/dap.am" i64 bufLen = String_Length(buf); #line 798 "./src/dap.am" if ((bufLen - bodyStart) < lenN) { return ""; } #line 799 "./src/dap.am" code_string body = String_Substring(buf, bodyStart, lenN); #line 800 "./src/dap.am" self->DapInputBuf = String_Substring(buf, bodyStart + lenN, (bufLen - bodyStart) - lenN); #line 801 "./src/dap.am" return body; } void Amalgame_Compiler_DapServer_SendDapFrame(Amalgame_Compiler_DapServer* self, code_string body) { #line 808 "./src/dap.am" code_string frame = code_string_concat((code_string_concat((code_string_concat("Content-Length: ", String_FromInt(String_Length(body)))), Amalgame_Compiler_DapServer_CrlfCrlf())), body); #line 809 "./src/dap.am" Amalgame_Compiler_DapServer_WriteToFd(self, 2LL, frame); } static void Amalgame_Compiler_DapServer_OnGdbOutput(Amalgame_Compiler_DapServer* self, code_string chunk) { #line 817 "./src/dap.am" self->GdbInputBuf = (code_string_concat(self->GdbInputBuf, chunk)); #line 818 "./src/dap.am" code_string buf = self->GdbInputBuf; #line 819 "./src/dap.am" i64 bufLen = String_Length(buf); #line 820 "./src/dap.am" i64 pos = 0LL; #line 821 "./src/dap.am" while (pos < bufLen) { #line 822 "./src/dap.am" code_string rest = String_Substring(buf, pos, bufLen - pos); #line 823 "./src/dap.am" i64 nl = String_IndexOf(rest, "\n"); #line 824 "./src/dap.am" if (nl < 0LL) { break; } #line 825 "./src/dap.am" code_string raw = String_Substring(buf, pos, nl); #line 826 "./src/dap.am" code_string line = String_Trim(raw); #line 827 "./src/dap.am" if (String_Length(line) > 0LL) { #line 828 "./src/dap.am" Amalgame_Compiler_DapServer_HandleMiLine(self, line); } #line 830 "./src/dap.am" pos = ((pos + nl) + 1LL); } #line 832 "./src/dap.am" self->GdbInputBuf = String_Substring(buf, pos, bufLen - pos); } static void Amalgame_Compiler_DapServer_HandleMiLine(Amalgame_Compiler_DapServer* self, code_string line) { #line 842 "./src/dap.am" Amalgame_Compiler_MiParser* parser = Amalgame_Compiler_MiParser_new(line); #line 843 "./src/dap.am" Amalgame_Compiler_MiRecord* rec = Amalgame_Compiler_MiParser_ParseRecord(parser); #line 844 "./src/dap.am" if (rec->RecordKind == 0LL) { Amalgame_Compiler_DapServer_HandleMiResult(self, rec); } else if (rec->RecordKind == 1LL) { #line 845 "./src/dap.am" Amalgame_Compiler_DapServer_HandleMiExecAsync(self, rec); } else if (rec->RecordKind == 3LL) { #line 846 "./src/dap.am" Amalgame_Compiler_DapServer_HandleMiNotifyAsync(self, rec); } } static void Amalgame_Compiler_DapServer_HandleMiResult(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec) { #line 855 "./src/dap.am" if (rec->Token < 0LL) { return; } #line 856 "./src/dap.am" i64 idx = Amalgame_Compiler_DapServer_FindMiTokenIndex(self, rec->Token); #line 857 "./src/dap.am" if (idx < 0LL) { return; } #line 858 "./src/dap.am" i64 dapSeq = (i64)(intptr_t)AmalgameList_get(self->MiTokensReq, idx); #line 859 "./src/dap.am" code_string kind = (code_string)AmalgameList_get(self->MiTokensKind, idx); #line 860 "./src/dap.am" Amalgame_Compiler_DapServer_ReleaseMiTokenAt(self, idx); #line 861 "./src/dap.am" if (code_string_equals(kind, "launch")) { Amalgame_Compiler_DapServer_RespondLaunch(self, dapSeq, rec); } else if (code_string_equals(kind, "setBreakpoints")) { #line 862 "./src/dap.am" Amalgame_Compiler_DapServer_RespondSetBreakpoints(self, dapSeq, rec); } else if (code_string_equals(kind, "configurationDone")) { #line 863 "./src/dap.am" Amalgame_Compiler_DapServer_RespondConfigurationDone(self, dapSeq, rec); } else if (code_string_equals(kind, "stackTrace")) { #line 864 "./src/dap.am" Amalgame_Compiler_DapServer_RespondStackTrace(self, dapSeq, rec); } else if (code_string_equals(kind, "variables")) { #line 865 "./src/dap.am" Amalgame_Compiler_DapServer_RespondVariables(self, dapSeq, rec); } else if (code_string_equals(kind, "varFollowup")) { #line 866 "./src/dap.am" Amalgame_Compiler_DapServer_HandleVarFollowupResponse(self, rec); } else if (code_string_equals(kind, "mapDiscCap")) { #line 867 "./src/dap.am" Amalgame_Compiler_DapServer_HandleMapDiscCapResponse(self, rec); } else if (code_string_equals(kind, "mapDiscSlot")) { #line 868 "./src/dap.am" Amalgame_Compiler_DapServer_HandleMapDiscSlotResponse(self, rec); } else if (code_string_equals(kind, "evaluate")) { #line 869 "./src/dap.am" Amalgame_Compiler_DapServer_RespondEvaluate(self, dapSeq, rec); } } static void Amalgame_Compiler_DapServer_HandleMiExecAsync(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec) { #line 880 "./src/dap.am" if (code_string_equals(rec->Class, "stopped")) { #line 884 "./src/dap.am" if (self->McuSettling) { return; } #line 885 "./src/dap.am" Amalgame_Compiler_DapServer_EmitStoppedEvent(self, rec); } else if (code_string_equals(rec->Class, "running")) { #line 889 "./src/dap.am" if (self->McuSettling) { self->McuSettling = 0; } } } static void Amalgame_Compiler_DapServer_HandleMiNotifyAsync(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec) { #line 899 "./src/dap.am" if (code_string_equals(rec->Class, "thread-group-exited")) { #line 901 "./src/dap.am" code_string evt = code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"event\"")), ",\"event\":\"terminated\"")), ",\"body\":{}}"); #line 905 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, evt); } } static code_bool Amalgame_Compiler_DapServer_IsHiddenFrameFunc(Amalgame_Compiler_DapServer* self, code_string funcS) { #line 923 "./src/dap.am" if (self->ShowRuntime) { return 0; } #line 924 "./src/dap.am" if (String_StartsWith(funcS, "Amalgame_")) { return 1; } #line 925 "./src/dap.am" if (String_StartsWith(funcS, "_runtime_")) { return 1; } #line 926 "./src/dap.am" if (String_StartsWith(funcS, "GC_")) { return 1; } #line 927 "./src/dap.am" return 0; } static void Amalgame_Compiler_DapServer_EmitStoppedEvent(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec) { #line 935 "./src/dap.am" if (self->StepBudget > 0LL) { #line 936 "./src/dap.am" Amalgame_Compiler_MiValue* frameV = Amalgame_Compiler_MiRecord_ResultOrNull(rec, "frame"); #line 937 "./src/dap.am" code_string funcS = ""; #line 938 "./src/dap.am" if (frameV != NULL) { funcS = Amalgame_Compiler_MiValue_FieldString(frameV, "func"); } #line 939 "./src/dap.am" if (Amalgame_Compiler_DapServer_IsHiddenFrameFunc(self, funcS)) { #line 940 "./src/dap.am" self->StepBudget = (self->StepBudget - 1LL); #line 941 "./src/dap.am" Amalgame_Compiler_DapServer_WriteToFd(self, 1LL, "-exec-step\n"); #line 942 "./src/dap.am" return; } #line 946 "./src/dap.am" self->StepBudget = 0LL; } #line 948 "./src/dap.am" code_string reason = "pause"; #line 949 "./src/dap.am" code_string bkptList = ""; #line 950 "./src/dap.am" code_bool isExit = 0; #line 951 "./src/dap.am" i64 resN = AmalgameList_count(rec->Results); #line 952 "./src/dap.am" for (i64 i = 0LL; i < resN; i++) { #line 953 "./src/dap.am" code_string key = (code_string)AmalgameList_get(rec->Results, i); #line 954 "./src/dap.am" Amalgame_Compiler_MiValue* val = (Amalgame_Compiler_MiValue*)AmalgameList_get(rec->Values, i); #line 955 "./src/dap.am" if ((code_string_equals(key, "reason")) && (val->Kind == 0LL)) { #line 956 "./src/dap.am" code_string r = val->Str; #line 957 "./src/dap.am" if (code_string_equals(r, "breakpoint-hit")) { reason = "breakpoint"; } else if (code_string_equals(r, "end-stepping-range")) { #line 958 "./src/dap.am" reason = "step"; } else if (code_string_equals(r, "signal-received")) { #line 959 "./src/dap.am" reason = "exception"; } else if (code_string_equals(r, "function-finished")) { #line 960 "./src/dap.am" reason = "step"; } else if (code_string_equals(r, "exited-normally")) { #line 961 "./src/dap.am" isExit = 1; } else if (code_string_equals(r, "exited")) { #line 962 "./src/dap.am" isExit = 1; } else if (code_string_equals(r, "exited-signalled")) { #line 963 "./src/dap.am" isExit = 1; } else { #line 964 "./src/dap.am" reason = r; } } #line 966 "./src/dap.am" if ((code_string_equals(key, "bkptno")) && (val->Kind == 0LL)) { #line 967 "./src/dap.am" bkptList = (code_string_concat((code_string_concat(",\"hitBreakpointIds\":[", val->Str)), "]")); } } #line 974 "./src/dap.am" if (isExit) { return; } #line 975 "./src/dap.am" code_string evt = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"event\"")), ",\"event\":\"stopped\"")), ",\"body\":{")), "\"reason\":\"")), Amalgame_Compiler_Json_EscapeString(reason))), "\"")), ",\"threadId\":1")), ",\"allThreadsStopped\":true")), bkptList)), "}}"); #line 984 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, evt); } static i64 Amalgame_Compiler_DapServer_IssueMiCommand(Amalgame_Compiler_DapServer* self, i64 dapSeq, code_string command, code_string mi) { #line 994 "./src/dap.am" i64 tok = self->NextMiToken; #line 995 "./src/dap.am" self->NextMiToken = (self->NextMiToken + 1LL); #line 996 "./src/dap.am" AmalgameList_add(self->MiTokens, (void*)(intptr_t)(tok)); #line 997 "./src/dap.am" AmalgameList_add(self->MiTokensReq, (void*)(intptr_t)(dapSeq)); #line 998 "./src/dap.am" AmalgameList_add(self->MiTokensKind, (void*)(intptr_t)(command)); #line 999 "./src/dap.am" Amalgame_Compiler_DapServer_WriteToFd(self, 1LL, code_string_concat((code_string_concat(String_FromInt(tok), mi)), "\n")); #line 1000 "./src/dap.am" return tok; } static i64 Amalgame_Compiler_DapServer_FindMiTokenIndex(Amalgame_Compiler_DapServer* self, i64 tok) { #line 1004 "./src/dap.am" i64 n = AmalgameList_count(self->MiTokens); #line 1005 "./src/dap.am" i64 found = -1LL; #line 1006 "./src/dap.am" for (i64 i = 0LL; i < n; i++) { #line 1007 "./src/dap.am" if ((i64)(intptr_t)AmalgameList_get(self->MiTokens, i) == tok) { found = i; } } #line 1009 "./src/dap.am" return found; } static void Amalgame_Compiler_DapServer_ReleaseMiTokenAt(Amalgame_Compiler_DapServer* self, i64 idx) { #line 1013 "./src/dap.am" if (idx < 0LL) { return; } #line 1014 "./src/dap.am" AmalgameList_removeAt(self->MiTokens, idx); #line 1015 "./src/dap.am" AmalgameList_removeAt(self->MiTokensReq, idx); #line 1016 "./src/dap.am" AmalgameList_removeAt(self->MiTokensKind, idx); } static void Amalgame_Compiler_DapServer_HandleDapMessage(Amalgame_Compiler_DapServer* self, code_string body) { #line 1025 "./src/dap.am" Amalgame_Compiler_JsonResult* parsed = Amalgame_Compiler_Json_Parse(body); #line 1026 "./src/dap.am" if (!parsed->Ok) { #line 1029 "./src/dap.am" return; } #line 1031 "./src/dap.am" Amalgame_Compiler_JsonValue* root = parsed->Value; #line 1032 "./src/dap.am" if (Amalgame_Compiler_JsonValue_IsNull(root)) { return; } #line 1033 "./src/dap.am" code_string typeStr = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(root, "type")); #line 1034 "./src/dap.am" if (!code_string_equals(typeStr, "request")) { #line 1037 "./src/dap.am" return; } #line 1039 "./src/dap.am" i64 seq = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(root, "seq")); #line 1040 "./src/dap.am" code_string command = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(root, "command")); #line 1041 "./src/dap.am" Amalgame_Compiler_JsonValue* args = Amalgame_Compiler_JsonValue_Get(root, "arguments"); #line 1042 "./src/dap.am" if (code_string_equals(command, "initialize")) { Amalgame_Compiler_DapServer_HandleInitialize(self, seq, args); } else if (code_string_equals(command, "disconnect")) { #line 1043 "./src/dap.am" Amalgame_Compiler_DapServer_HandleDisconnect(self, seq, args); } else if (code_string_equals(command, "threads")) { #line 1044 "./src/dap.am" Amalgame_Compiler_DapServer_HandleThreads(self, seq); } else if (code_string_equals(command, "continue")) { #line 1045 "./src/dap.am" Amalgame_Compiler_DapServer_HandleContinue(self, seq, args); } else if (code_string_equals(command, "next")) { #line 1046 "./src/dap.am" Amalgame_Compiler_DapServer_HandleStep(self, seq, "next", "-exec-next"); } else if (code_string_equals(command, "stepIn")) { #line 1047 "./src/dap.am" Amalgame_Compiler_DapServer_HandleStep(self, seq, "stepIn", "-exec-step"); } else if (code_string_equals(command, "stepOut")) { #line 1048 "./src/dap.am" Amalgame_Compiler_DapServer_HandleStep(self, seq, "stepOut", "-exec-finish"); } else if (code_string_equals(command, "pause")) { #line 1049 "./src/dap.am" Amalgame_Compiler_DapServer_HandlePause(self, seq, args); } else if (code_string_equals(command, "launch")) { #line 1050 "./src/dap.am" Amalgame_Compiler_DapServer_HandleLaunch(self, seq, args); } else if (code_string_equals(command, "setBreakpoints")) { #line 1051 "./src/dap.am" Amalgame_Compiler_DapServer_HandleSetBreakpoints(self, seq, args); } else if (code_string_equals(command, "configurationDone")) { #line 1052 "./src/dap.am" Amalgame_Compiler_DapServer_HandleConfigurationDone(self, seq, args); } else if (code_string_equals(command, "setExceptionBreakpoints")) { #line 1053 "./src/dap.am" Amalgame_Compiler_DapServer_HandleSetExceptionBreakpoints(self, seq); } else if (code_string_equals(command, "setFunctionBreakpoints")) { #line 1054 "./src/dap.am" Amalgame_Compiler_DapServer_HandleSetFunctionBreakpoints(self, seq); } else if (code_string_equals(command, "stackTrace")) { #line 1055 "./src/dap.am" Amalgame_Compiler_DapServer_HandleStackTrace(self, seq, args); } else if (code_string_equals(command, "scopes")) { #line 1056 "./src/dap.am" Amalgame_Compiler_DapServer_HandleScopes(self, seq, args); } else if (code_string_equals(command, "variables")) { #line 1057 "./src/dap.am" Amalgame_Compiler_DapServer_HandleVariables(self, seq, args); } else if (code_string_equals(command, "evaluate")) { #line 1058 "./src/dap.am" Amalgame_Compiler_DapServer_HandleEvaluate(self, seq, args); } else if (code_string_equals(command, "terminate")) { #line 1059 "./src/dap.am" Amalgame_Compiler_DapServer_HandleTerminate(self, seq); } else { #line 1065 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapAck(self, seq, command); } } static void Amalgame_Compiler_DapServer_SendDapAck(Amalgame_Compiler_DapServer* self, i64 seq, code_string command) { #line 1070 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":true")), ",\"command\":\"")), Amalgame_Compiler_Json_EscapeString(command))), "\"}"); #line 1075 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static void Amalgame_Compiler_DapServer_HandleTerminate(Amalgame_Compiler_DapServer* self, i64 seq) { #line 1081 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":true")), ",\"command\":\"terminate\"}"); #line 1086 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); #line 1087 "./src/dap.am" Amalgame_Compiler_DapServer_WriteToFd(self, 1LL, "-gdb-exit\n"); #line 1088 "./src/dap.am" Amalgame_Compiler_DapServer_CloseGdbStdin(self); #line 1089 "./src/dap.am" self->StopRequested = 1; } static void Amalgame_Compiler_DapServer_HandleThreads(Amalgame_Compiler_DapServer* self, i64 seq) { #line 1103 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":true")), ",\"command\":\"threads\"")), ",\"body\":{\"threads\":[{\"id\":1,\"name\":\"main\"}]}}"); #line 1109 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static void Amalgame_Compiler_DapServer_HandleContinue(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args) { #line 1113 "./src/dap.am" Amalgame_Compiler_DapServer_WriteToFd(self, 1LL, "-exec-continue\n"); #line 1114 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":true")), ",\"command\":\"continue\"")), ",\"body\":{\"allThreadsContinued\":true}}"); #line 1120 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static void Amalgame_Compiler_DapServer_HandleStep(Amalgame_Compiler_DapServer* self, i64 seq, code_string dapCmd, code_string miCmd) { #line 1128 "./src/dap.am" if ((code_string_equals(dapCmd, "stepIn")) && !self->ShowRuntime) { #line 1129 "./src/dap.am" self->StepBudget = 8LL; } #line 1131 "./src/dap.am" Amalgame_Compiler_DapServer_WriteToFd(self, 1LL, code_string_concat(miCmd, "\n")); #line 1132 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":true")), ",\"command\":\"")), dapCmd)), "\"}"); #line 1137 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static void Amalgame_Compiler_DapServer_HandlePause(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args) { #line 1141 "./src/dap.am" Amalgame_Compiler_DapServer_WriteToFd(self, 1LL, "-exec-interrupt\n"); #line 1142 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":true")), ",\"command\":\"pause\"}"); #line 1147 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static void Amalgame_Compiler_DapServer_HandleLaunch(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args) { #line 1153 "./src/dap.am" code_string program = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(args, "program")); #line 1154 "./src/dap.am" if (String_Length(program) == 0LL) { #line 1155 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapErrorResponse(self, seq, "launch", "missing 'program' field"); #line 1156 "./src/dap.am" return; } #line 1159 "./src/dap.am" code_string mi = code_string_concat((code_string_concat("-file-exec-and-symbols \"", program)), "\""); #line 1160 "./src/dap.am" i64 _tok = Amalgame_Compiler_DapServer_IssueMiCommand(self, seq, "launch", mi); } static void Amalgame_Compiler_DapServer_HandleSetBreakpoints(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args) { #line 1164 "./src/dap.am" if (self->BkptInFlight) { #line 1165 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapErrorResponse(self, seq, "setBreakpoints", "previous setBreakpoints still in flight"); #line 1167 "./src/dap.am" return; } #line 1169 "./src/dap.am" Amalgame_Compiler_JsonValue* src = Amalgame_Compiler_JsonValue_Get(args, "source"); #line 1170 "./src/dap.am" code_string srcPath = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(src, "path")); #line 1171 "./src/dap.am" if (String_Length(srcPath) == 0LL) { #line 1172 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapErrorResponse(self, seq, "setBreakpoints", "missing 'source.path'"); #line 1173 "./src/dap.am" return; } #line 1175 "./src/dap.am" Amalgame_Compiler_JsonValue* bpsVal = Amalgame_Compiler_JsonValue_Get(args, "breakpoints"); #line 1176 "./src/dap.am" AmalgameList* bps = Amalgame_Compiler_JsonValue_AsArray(bpsVal); #line 1177 "./src/dap.am" i64 nNew = AmalgameList_count(bps); #line 1181 "./src/dap.am" i64 nKnown = AmalgameList_count(self->BkptKnownNumbers); #line 1182 "./src/dap.am" for (i64 i = 0LL; i < nKnown; i++) { #line 1183 "./src/dap.am" i64 num = (i64)(intptr_t)AmalgameList_get(self->BkptKnownNumbers, i); #line 1184 "./src/dap.am" Amalgame_Compiler_DapServer_WriteToFd(self, 1LL, code_string_concat((code_string_concat("-break-delete ", String_FromInt(num))), "\n")); } #line 1186 "./src/dap.am" self->BkptKnownNumbers = AmalgameList_new(); #line 1188 "./src/dap.am" if (nNew == 0LL) { #line 1189 "./src/dap.am" Amalgame_Compiler_DapServer_SendBkptResponse(self, seq, AmalgameList_new()); #line 1190 "./src/dap.am" return; } #line 1193 "./src/dap.am" self->BkptInFlight = 1; #line 1194 "./src/dap.am" self->BkptInFlightSeq = seq; #line 1195 "./src/dap.am" self->BkptInFlightSource = srcPath; #line 1196 "./src/dap.am" self->BkptInFlightPending = nNew; #line 1197 "./src/dap.am" self->BkptInFlightDapShape = AmalgameList_new(); #line 1201 "./src/dap.am" for (i64 i = 0LL; i < nNew; i++) { #line 1202 "./src/dap.am" Amalgame_Compiler_JsonValue* bp = (Amalgame_Compiler_JsonValue*)AmalgameList_get(bps, i); #line 1203 "./src/dap.am" i64 line = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(bp, "line")); #line 1204 "./src/dap.am" code_string mi = code_string_concat((code_string_concat((code_string_concat("-break-insert ", srcPath)), ":")), String_FromInt(line)); #line 1205 "./src/dap.am" i64 _tok = Amalgame_Compiler_DapServer_IssueMiCommand(self, seq, "setBreakpoints", mi); } } static void Amalgame_Compiler_DapServer_RespondSetBreakpoints(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec) { #line 1210 "./src/dap.am" if (!self->BkptInFlight || (self->BkptInFlightSeq != dapSeq)) { #line 1212 "./src/dap.am" return; } #line 1217 "./src/dap.am" code_string dapEntry = ""; #line 1218 "./src/dap.am" Amalgame_Compiler_MiValue* bkpt = Amalgame_Compiler_MiRecord_ResultOrNull(rec, "bkpt"); #line 1219 "./src/dap.am" if (((code_string_equals(rec->Class, "done")) && (bkpt != NULL)) && (bkpt->Kind == 1LL)) { #line 1220 "./src/dap.am" code_string numS = Amalgame_Compiler_MiValue_FieldString(bkpt, "number"); #line 1221 "./src/dap.am" code_string fileS = Amalgame_Compiler_MiValue_FieldString(bkpt, "file"); #line 1222 "./src/dap.am" code_string lineS = Amalgame_Compiler_MiValue_FieldString(bkpt, "line"); #line 1224 "./src/dap.am" if (String_Length(numS) > 0LL) { #line 1225 "./src/dap.am" AmalgameList_add(self->BkptKnownNumbers, (void*)(intptr_t)(String_ToInt(numS))); } #line 1227 "./src/dap.am" dapEntry = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"id\":", numS)), ",\"verified\":true")), ",\"line\":")), lineS)), ",\"source\":{\"path\":\"")), Amalgame_Compiler_Json_EscapeString(fileS))), "\"}}")); } else { #line 1234 "./src/dap.am" dapEntry = "{\"verified\":false,\"message\":\"-break-insert failed\"}"; } #line 1236 "./src/dap.am" AmalgameList_add(self->BkptInFlightDapShape, (void*)(intptr_t)(dapEntry)); #line 1237 "./src/dap.am" self->BkptInFlightPending = (self->BkptInFlightPending - 1LL); #line 1238 "./src/dap.am" if (self->BkptInFlightPending <= 0LL) { #line 1239 "./src/dap.am" Amalgame_Compiler_DapServer_SendBkptResponse(self, self->BkptInFlightSeq, self->BkptInFlightDapShape); #line 1240 "./src/dap.am" self->BkptInFlight = 0; #line 1241 "./src/dap.am" self->BkptInFlightSeq = -1LL; #line 1242 "./src/dap.am" self->BkptInFlightSource = ""; } } static void Amalgame_Compiler_DapServer_SendBkptResponse(Amalgame_Compiler_DapServer* self, i64 seq, AmalgameList* entries) { #line 1250 "./src/dap.am" code_string arr = "["; #line 1251 "./src/dap.am" i64 n = AmalgameList_count(entries); #line 1252 "./src/dap.am" for (i64 i = 0LL; i < n; i++) { #line 1253 "./src/dap.am" if (i > 0LL) { arr = (code_string_concat(arr, ",")); } #line 1254 "./src/dap.am" arr = (code_string_concat(arr, (code_string)AmalgameList_get(entries, i))); } #line 1256 "./src/dap.am" arr = (code_string_concat(arr, "]")); #line 1257 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":true")), ",\"command\":\"setBreakpoints\"")), ",\"body\":{\"breakpoints\":")), arr)), "}}"); #line 1263 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static void Amalgame_Compiler_DapServer_HandleSetFunctionBreakpoints(Amalgame_Compiler_DapServer* self, i64 seq) { #line 1271 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":true")), ",\"command\":\"setFunctionBreakpoints\"")), ",\"body\":{\"breakpoints\":[]}}"); #line 1277 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static void Amalgame_Compiler_DapServer_HandleSetExceptionBreakpoints(Amalgame_Compiler_DapServer* self, i64 seq) { #line 1284 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":true")), ",\"command\":\"setExceptionBreakpoints\"")), ",\"body\":{\"breakpoints\":[]}}"); #line 1290 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static void Amalgame_Compiler_DapServer_HandleConfigurationDone(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args) { #line 1297 "./src/dap.am" if (String_Length(self->McuTarget) > 0LL) { #line 1301 "./src/dap.am" i64 _t = Amalgame_Compiler_DapServer_IssueMiCommand(self, seq, "configurationDone", "-interpreter-exec console \"load\""); #line 1302 "./src/dap.am" return; } #line 1305 "./src/dap.am" i64 _tok = Amalgame_Compiler_DapServer_IssueMiCommand(self, seq, "configurationDone", "-exec-run"); } static void Amalgame_Compiler_DapServer_HandleStackTrace(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args) { #line 1313 "./src/dap.am" i64 startF = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(args, "startFrame")); #line 1314 "./src/dap.am" i64 levels = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(args, "levels")); #line 1315 "./src/dap.am" code_string miArgs = ""; #line 1316 "./src/dap.am" if (levels > 0LL) { #line 1317 "./src/dap.am" i64 endF = (startF + levels) - 1LL; #line 1318 "./src/dap.am" miArgs = (code_string_concat((code_string_concat((code_string_concat(" ", String_FromInt(startF))), " ")), String_FromInt(endF))); } #line 1320 "./src/dap.am" i64 _tok = Amalgame_Compiler_DapServer_IssueMiCommand(self, seq, "stackTrace", code_string_concat("-stack-list-frames", miArgs)); } static void Amalgame_Compiler_DapServer_HandleScopes(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args) { #line 1331 "./src/dap.am" i64 frameId = 0LL; #line 1332 "./src/dap.am" Amalgame_Compiler_JsonValue* fidV = Amalgame_Compiler_JsonValue_Get(args, "frameId"); #line 1333 "./src/dap.am" if ((fidV != NULL) && Amalgame_Compiler_JsonValue_IsInt(fidV)) { frameId = Amalgame_Compiler_JsonValue_AsInt(fidV); } #line 1334 "./src/dap.am" if (frameId < 0LL) { frameId = 0LL; } #line 1335 "./src/dap.am" if (frameId > 899LL) { frameId = 899LL; } #line 1336 "./src/dap.am" i64 vref = 100LL + frameId; #line 1337 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":true")), ",\"command\":\"scopes\"")), ",\"body\":{\"scopes\":[{\"name\":\"Locals\",\"variablesReference\":")), String_FromInt(vref))), ",\"expensive\":false}]}}"); #line 1344 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static void Amalgame_Compiler_DapServer_HandleVariables(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args) { #line 1348 "./src/dap.am" i64 vref = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(args, "variablesReference")); #line 1349 "./src/dap.am" if (vref == 1LL) { #line 1353 "./src/dap.am" i64 _tok = Amalgame_Compiler_DapServer_IssueMiCommand(self, seq, "variables", "-stack-list-variables --simple-values"); #line 1355 "./src/dap.am" return; } #line 1357 "./src/dap.am" if ((vref >= 100LL) && (vref <= 999LL)) { #line 1361 "./src/dap.am" i64 frameId = vref - 100LL; #line 1362 "./src/dap.am" code_string mi = code_string_concat((code_string_concat("-stack-list-variables --thread 1 --frame ", String_FromInt(frameId))), " --simple-values"); #line 1364 "./src/dap.am" i64 _tok = Amalgame_Compiler_DapServer_IssueMiCommand(self, seq, "variables", mi); #line 1365 "./src/dap.am" return; } #line 1367 "./src/dap.am" if (vref >= 1000LL) { #line 1369 "./src/dap.am" Amalgame_Compiler_DapServer_HandleChildVariables(self, seq, vref); #line 1370 "./src/dap.am" return; } #line 1372 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapErrorResponse(self, seq, "variables", "invalid variablesReference"); } static void Amalgame_Compiler_DapServer_HandleChildVariables(Amalgame_Compiler_DapServer* self, i64 seq, i64 vref) { #line 1381 "./src/dap.am" i64 cidx = Amalgame_Compiler_DapServer_FindChildRefIndex(self, vref); #line 1382 "./src/dap.am" if (cidx < 0LL) { #line 1383 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapErrorResponse(self, seq, "variables", "stale variablesReference"); #line 1384 "./src/dap.am" return; } #line 1386 "./src/dap.am" code_string typeS = (code_string)AmalgameList_get(self->ChildRef_Types, cidx); #line 1387 "./src/dap.am" code_string addr = (code_string)AmalgameList_get(self->ChildRef_Addrs, cidx); #line 1388 "./src/dap.am" i64 size = (i64)(intptr_t)AmalgameList_get(self->ChildRef_Sizes, cidx); #line 1393 "./src/dap.am" if (code_string_equals(typeS, "AmalgameMap")) { #line 1394 "./src/dap.am" Amalgame_Compiler_DapServer_StartMapDiscovery(self, seq, "AmalgameMap", code_string_concat((code_string_concat("((AmalgameMap*)", addr)), ")")); #line 1395 "./src/dap.am" return; } #line 1397 "./src/dap.am" if (code_string_equals(typeS, "AmalgameSet")) { #line 1398 "./src/dap.am" Amalgame_Compiler_DapServer_StartMapDiscovery(self, seq, "AmalgameSet", code_string_concat((code_string_concat("((AmalgameSet*)", addr)), ")->map")); #line 1399 "./src/dap.am" return; } #line 1401 "./src/dap.am" self->PendingVars_Seq = seq; #line 1402 "./src/dap.am" self->PendingVars_Names = AmalgameList_new(); #line 1403 "./src/dap.am" self->PendingVars_Types = AmalgameList_new(); #line 1404 "./src/dap.am" self->PendingVars_Values = AmalgameList_new(); #line 1405 "./src/dap.am" self->PendingVars_Queries = AmalgameList_new(); #line 1406 "./src/dap.am" self->PendingVars_Refs = AmalgameList_new(); #line 1407 "./src/dap.am" self->PendingVars_Idx = 0LL; #line 1408 "./src/dap.am" if (code_string_equals(typeS, "AmalgameList")) { #line 1409 "./src/dap.am" for (i64 i = 0LL; i < size; i++) { #line 1410 "./src/dap.am" AmalgameList_add(self->PendingVars_Names, (void*)(intptr_t)(code_string_concat((code_string_concat("[", String_FromInt(i))), "]"))); #line 1411 "./src/dap.am" AmalgameList_add(self->PendingVars_Types, (void*)(intptr_t)("void*")); #line 1412 "./src/dap.am" AmalgameList_add(self->PendingVars_Values, (void*)(intptr_t)("?")); #line 1413 "./src/dap.am" AmalgameList_add(self->PendingVars_Queries, (void*)(intptr_t)(code_string_concat((code_string_concat((code_string_concat((code_string_concat("(void*)((AmalgameList*)", addr)), ")->data[")), String_FromInt(i))), "]"))); #line 1414 "./src/dap.am" AmalgameList_add(self->PendingVars_Refs, (void*)(intptr_t)(0LL)); } } #line 1417 "./src/dap.am" Amalgame_Compiler_DapServer_ProcessNextVarFollowup(self); } static void Amalgame_Compiler_DapServer_StartMapDiscovery(Amalgame_Compiler_DapServer* self, i64 seq, code_string kind, code_string baseExpr) { #line 1425 "./src/dap.am" self->MapDisc_Seq = seq; #line 1426 "./src/dap.am" self->MapDisc_Kind = kind; #line 1427 "./src/dap.am" self->MapDisc_BaseExpr = baseExpr; #line 1428 "./src/dap.am" self->MapDisc_Capacity = 0LL; #line 1429 "./src/dap.am" self->MapDisc_SlotIdx = 0LL; #line 1430 "./src/dap.am" self->MapDisc_Occupied = AmalgameList_new(); #line 1431 "./src/dap.am" code_string mi = code_string_concat((code_string_concat("-data-evaluate-expression \"", Amalgame_Compiler_Json_EscapeString(code_string_concat((code_string_concat("(int)", baseExpr)), "->capacity")))), "\""); #line 1433 "./src/dap.am" i64 _tok = Amalgame_Compiler_DapServer_IssueMiCommand(self, seq, "mapDiscCap", mi); } static void Amalgame_Compiler_DapServer_HandleMapDiscCapResponse(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec) { #line 1437 "./src/dap.am" if (!code_string_equals(rec->Class, "done")) { #line 1438 "./src/dap.am" Amalgame_Compiler_DapServer_FailMapDiscovery(self, "capacity probe failed"); #line 1439 "./src/dap.am" return; } #line 1441 "./src/dap.am" Amalgame_Compiler_MiValue* valWrap = Amalgame_Compiler_MiRecord_ResultOrNull(rec, "value"); #line 1442 "./src/dap.am" if (valWrap == NULL) { #line 1443 "./src/dap.am" Amalgame_Compiler_DapServer_FailMapDiscovery(self, "capacity probe returned no value"); #line 1444 "./src/dap.am" return; } #line 1446 "./src/dap.am" i64 cap = String_ToInt(valWrap->Str); #line 1447 "./src/dap.am" if (cap <= 0LL) { #line 1452 "./src/dap.am" Amalgame_Compiler_DapServer_FinishMapDiscoveryEmpty(self); #line 1453 "./src/dap.am" return; } #line 1455 "./src/dap.am" self->MapDisc_Capacity = cap; #line 1456 "./src/dap.am" self->MapDisc_SlotIdx = 0LL; #line 1457 "./src/dap.am" Amalgame_Compiler_DapServer_FireNextSlotProbe(self); } static void Amalgame_Compiler_DapServer_FireNextSlotProbe(Amalgame_Compiler_DapServer* self) { #line 1461 "./src/dap.am" if (self->MapDisc_SlotIdx >= self->MapDisc_Capacity) { #line 1462 "./src/dap.am" Amalgame_Compiler_DapServer_EmitMapChildren(self); #line 1463 "./src/dap.am" return; } #line 1465 "./src/dap.am" i64 i = self->MapDisc_SlotIdx; #line 1466 "./src/dap.am" code_string q = code_string_concat((code_string_concat((code_string_concat((code_string_concat("(int)", self->MapDisc_BaseExpr)), "->entries[")), String_FromInt(i))), "].used"); #line 1468 "./src/dap.am" code_string mi = code_string_concat((code_string_concat("-data-evaluate-expression \"", Amalgame_Compiler_Json_EscapeString(q))), "\""); #line 1469 "./src/dap.am" i64 _tok = Amalgame_Compiler_DapServer_IssueMiCommand(self, self->MapDisc_Seq, "mapDiscSlot", mi); } static void Amalgame_Compiler_DapServer_HandleMapDiscSlotResponse(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec) { #line 1473 "./src/dap.am" if (code_string_equals(rec->Class, "done")) { #line 1474 "./src/dap.am" Amalgame_Compiler_MiValue* valWrap = Amalgame_Compiler_MiRecord_ResultOrNull(rec, "value"); #line 1475 "./src/dap.am" if (valWrap != NULL) { #line 1476 "./src/dap.am" i64 usedState = String_ToInt(valWrap->Str); #line 1477 "./src/dap.am" if (usedState == 1LL) { #line 1478 "./src/dap.am" AmalgameList_add(self->MapDisc_Occupied, (void*)(intptr_t)(self->MapDisc_SlotIdx)); } } } #line 1485 "./src/dap.am" self->MapDisc_SlotIdx = (self->MapDisc_SlotIdx + 1LL); #line 1486 "./src/dap.am" Amalgame_Compiler_DapServer_FireNextSlotProbe(self); } static void Amalgame_Compiler_DapServer_EmitMapChildren(Amalgame_Compiler_DapServer* self) { #line 1494 "./src/dap.am" i64 seq = self->MapDisc_Seq; #line 1495 "./src/dap.am" code_string baseExpr = self->MapDisc_BaseExpr; #line 1496 "./src/dap.am" code_string kind = self->MapDisc_Kind; #line 1497 "./src/dap.am" self->PendingVars_Seq = seq; #line 1498 "./src/dap.am" self->PendingVars_Names = AmalgameList_new(); #line 1499 "./src/dap.am" self->PendingVars_Types = AmalgameList_new(); #line 1500 "./src/dap.am" self->PendingVars_Values = AmalgameList_new(); #line 1501 "./src/dap.am" self->PendingVars_Queries = AmalgameList_new(); #line 1502 "./src/dap.am" self->PendingVars_Refs = AmalgameList_new(); #line 1503 "./src/dap.am" self->PendingVars_Idx = 0LL; #line 1504 "./src/dap.am" i64 n = AmalgameList_count(self->MapDisc_Occupied); #line 1505 "./src/dap.am" for (i64 j = 0LL; j < n; j++) { #line 1506 "./src/dap.am" i64 slot = (i64)(intptr_t)AmalgameList_get(self->MapDisc_Occupied, j); #line 1507 "./src/dap.am" code_string slotS = String_FromInt(slot); #line 1511 "./src/dap.am" AmalgameList_add(self->PendingVars_Names, (void*)(intptr_t)(code_string_concat((code_string_concat("[", slotS)), "].k"))); #line 1512 "./src/dap.am" AmalgameList_add(self->PendingVars_Types, (void*)(intptr_t)("code_string")); #line 1513 "./src/dap.am" AmalgameList_add(self->PendingVars_Values, (void*)(intptr_t)("?")); #line 1514 "./src/dap.am" AmalgameList_add(self->PendingVars_Queries, (void*)(intptr_t)(code_string_concat((code_string_concat((code_string_concat((code_string_concat("(code_string)", baseExpr)), "->entries[")), slotS)), "].key"))); #line 1515 "./src/dap.am" AmalgameList_add(self->PendingVars_Refs, (void*)(intptr_t)(0LL)); #line 1516 "./src/dap.am" if (code_string_equals(kind, "AmalgameMap")) { #line 1517 "./src/dap.am" AmalgameList_add(self->PendingVars_Names, (void*)(intptr_t)(code_string_concat((code_string_concat("[", slotS)), "].v"))); #line 1518 "./src/dap.am" AmalgameList_add(self->PendingVars_Types, (void*)(intptr_t)("void*")); #line 1519 "./src/dap.am" AmalgameList_add(self->PendingVars_Values, (void*)(intptr_t)("?")); #line 1520 "./src/dap.am" AmalgameList_add(self->PendingVars_Queries, (void*)(intptr_t)(code_string_concat((code_string_concat((code_string_concat((code_string_concat("(void*)", baseExpr)), "->entries[")), slotS)), "].value"))); #line 1521 "./src/dap.am" AmalgameList_add(self->PendingVars_Refs, (void*)(intptr_t)(0LL)); } } #line 1524 "./src/dap.am" Amalgame_Compiler_DapServer_ResetMapDiscovery(self); #line 1525 "./src/dap.am" Amalgame_Compiler_DapServer_ProcessNextVarFollowup(self); } static void Amalgame_Compiler_DapServer_FinishMapDiscoveryEmpty(Amalgame_Compiler_DapServer* self) { #line 1529 "./src/dap.am" i64 seq = self->MapDisc_Seq; #line 1530 "./src/dap.am" self->PendingVars_Seq = seq; #line 1531 "./src/dap.am" self->PendingVars_Names = AmalgameList_new(); #line 1532 "./src/dap.am" self->PendingVars_Types = AmalgameList_new(); #line 1533 "./src/dap.am" self->PendingVars_Values = AmalgameList_new(); #line 1534 "./src/dap.am" self->PendingVars_Queries = AmalgameList_new(); #line 1535 "./src/dap.am" self->PendingVars_Refs = AmalgameList_new(); #line 1536 "./src/dap.am" self->PendingVars_Idx = 0LL; #line 1537 "./src/dap.am" Amalgame_Compiler_DapServer_ResetMapDiscovery(self); #line 1538 "./src/dap.am" Amalgame_Compiler_DapServer_ProcessNextVarFollowup(self); } static void Amalgame_Compiler_DapServer_FailMapDiscovery(Amalgame_Compiler_DapServer* self, code_string msg) { #line 1542 "./src/dap.am" i64 seq = self->MapDisc_Seq; #line 1543 "./src/dap.am" Amalgame_Compiler_DapServer_ResetMapDiscovery(self); #line 1544 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapErrorResponse(self, seq, "variables", msg); } static void Amalgame_Compiler_DapServer_ResetMapDiscovery(Amalgame_Compiler_DapServer* self) { #line 1548 "./src/dap.am" self->MapDisc_Seq = -1LL; #line 1549 "./src/dap.am" self->MapDisc_Kind = ""; #line 1550 "./src/dap.am" self->MapDisc_BaseExpr = ""; #line 1551 "./src/dap.am" self->MapDisc_Capacity = 0LL; #line 1552 "./src/dap.am" self->MapDisc_SlotIdx = 0LL; #line 1553 "./src/dap.am" self->MapDisc_Occupied = AmalgameList_new(); } static i64 Amalgame_Compiler_DapServer_FindChildRefIndex(Amalgame_Compiler_DapServer* self, i64 vref) { #line 1557 "./src/dap.am" i64 n = AmalgameList_count(self->ChildRef_Refs); #line 1558 "./src/dap.am" i64 found = -1LL; #line 1559 "./src/dap.am" for (i64 i = 0LL; i < n; i++) { #line 1560 "./src/dap.am" if ((i64)(intptr_t)AmalgameList_get(self->ChildRef_Refs, i) == vref) { found = i; } } #line 1562 "./src/dap.am" return found; } static i64 Amalgame_Compiler_DapServer_AllocChildRef(Amalgame_Compiler_DapServer* self, code_string typeS, code_string addr, i64 size) { #line 1570 "./src/dap.am" i64 r = self->NextChildRef; #line 1571 "./src/dap.am" self->NextChildRef = (self->NextChildRef + 1LL); #line 1572 "./src/dap.am" AmalgameList_add(self->ChildRef_Refs, (void*)(intptr_t)(r)); #line 1573 "./src/dap.am" AmalgameList_add(self->ChildRef_Types, (void*)(intptr_t)(typeS)); #line 1574 "./src/dap.am" AmalgameList_add(self->ChildRef_Addrs, (void*)(intptr_t)(addr)); #line 1575 "./src/dap.am" AmalgameList_add(self->ChildRef_Sizes, (void*)(intptr_t)(size)); #line 1576 "./src/dap.am" return r; } static void Amalgame_Compiler_DapServer_HandleEvaluate(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args) { #line 1580 "./src/dap.am" code_string expr = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(args, "expression")); #line 1581 "./src/dap.am" if (String_Length(expr) == 0LL) { #line 1582 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapErrorResponse(self, seq, "evaluate", "missing expression"); #line 1583 "./src/dap.am" return; } #line 1587 "./src/dap.am" code_string mi = code_string_concat((code_string_concat("-data-evaluate-expression \"", Amalgame_Compiler_Json_EscapeString(expr))), "\""); #line 1589 "./src/dap.am" i64 _tok = Amalgame_Compiler_DapServer_IssueMiCommand(self, seq, "evaluate", mi); } static void Amalgame_Compiler_DapServer_RespondLaunch(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec) { #line 1599 "./src/dap.am" code_bool ok = code_string_equals(rec->Class, "done"); #line 1600 "./src/dap.am" if (!ok) { #line 1601 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapErrorResponse(self, dapSeq, "launch", "-file-exec-and-symbols failed"); #line 1602 "./src/dap.am" return; } #line 1604 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(dapSeq))), ",\"success\":true")), ",\"command\":\"launch\"}"); #line 1609 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static void Amalgame_Compiler_DapServer_RespondConfigurationDone(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec) { #line 1616 "./src/dap.am" code_bool ok = (code_string_equals(rec->Class, "running")) || (code_string_equals(rec->Class, "done")); #line 1617 "./src/dap.am" if (!ok) { #line 1618 "./src/dap.am" code_string why = "-exec-run failed"; #line 1619 "./src/dap.am" if (String_Length(self->McuTarget) > 0LL) { #line 1620 "./src/dap.am" why = "flash/load failed — is the board connected and free? (a stale openocd/gdb from a previous session can hold the ST-LINK; unplug/replug or close other debug sessions)"; } #line 1622 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapErrorResponse(self, dapSeq, "configurationDone", why); #line 1623 "./src/dap.am" return; } #line 1625 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(dapSeq))), ",\"success\":true")), ",\"command\":\"configurationDone\"}"); #line 1630 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); #line 1635 "./src/dap.am" if (String_Length(self->McuTarget) > 0LL) { #line 1636 "./src/dap.am" Amalgame_Compiler_DapServer_WriteToFd(self, 1LL, "-interpreter-exec console \"monitor reset halt\"\n"); #line 1637 "./src/dap.am" Amalgame_Compiler_DapServer_WriteToFd(self, 1LL, "-exec-continue\n"); } } static void Amalgame_Compiler_DapServer_RespondStackTrace(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec) { #line 1645 "./src/dap.am" if (!code_string_equals(rec->Class, "done")) { #line 1646 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapErrorResponse(self, dapSeq, "stackTrace", "-stack-list-frames failed"); #line 1647 "./src/dap.am" return; } #line 1649 "./src/dap.am" Amalgame_Compiler_MiValue* stack = Amalgame_Compiler_MiRecord_ResultOrNull(rec, "stack"); #line 1650 "./src/dap.am" code_string frames = "["; #line 1651 "./src/dap.am" i64 count = 0LL; #line 1652 "./src/dap.am" if ((stack != NULL) && (stack->Kind == 2LL)) { #line 1653 "./src/dap.am" i64 n = AmalgameList_count(stack->ListItems); #line 1654 "./src/dap.am" for (i64 i = 0LL; i < n; i++) { #line 1655 "./src/dap.am" Amalgame_Compiler_MiValue* f = (Amalgame_Compiler_MiValue*)AmalgameList_get(stack->ListItems, i); #line 1656 "./src/dap.am" if (f->Kind != 1LL) { continue; } #line 1657 "./src/dap.am" code_string lvlS = Amalgame_Compiler_MiValue_FieldString(f, "level"); #line 1658 "./src/dap.am" code_string funcS = Amalgame_Compiler_MiValue_FieldString(f, "func"); #line 1659 "./src/dap.am" code_string fileS = Amalgame_Compiler_MiValue_FieldString(f, "fullname"); #line 1660 "./src/dap.am" code_string lineS = Amalgame_Compiler_MiValue_FieldString(f, "line"); #line 1661 "./src/dap.am" if (String_Length(lineS) == 0LL) { lineS = "0"; } #line 1665 "./src/dap.am" if (Amalgame_Compiler_DapServer_IsHiddenFrameFunc(self, funcS)) { continue; } #line 1666 "./src/dap.am" if (count > 0LL) { frames = (code_string_concat(frames, ",")); } #line 1667 "./src/dap.am" frames = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(frames, "{\"id\":")), lvlS)), ",\"name\":\"")), Amalgame_Compiler_Json_EscapeString(funcS))), "\"")), ",\"line\":")), lineS)), ",\"column\":1")); #line 1671 "./src/dap.am" if (String_Length(fileS) > 0LL) { #line 1672 "./src/dap.am" frames = (code_string_concat((code_string_concat((code_string_concat(frames, ",\"source\":{\"path\":\"")), Amalgame_Compiler_Json_EscapeString(fileS))), "\"}")); } #line 1674 "./src/dap.am" frames = (code_string_concat(frames, "}")); #line 1675 "./src/dap.am" count = (count + 1LL); } } #line 1678 "./src/dap.am" frames = (code_string_concat(frames, "]")); #line 1679 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(dapSeq))), ",\"success\":true")), ",\"command\":\"stackTrace\"")), ",\"body\":{\"stackFrames\":")), frames)), ",\"totalFrames\":")), String_FromInt(count))), "}}"); #line 1686 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static void Amalgame_Compiler_DapServer_RespondVariables(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec) { #line 1690 "./src/dap.am" if (!code_string_equals(rec->Class, "done")) { #line 1691 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapErrorResponse(self, dapSeq, "variables", "-stack-list-variables failed"); #line 1692 "./src/dap.am" return; } #line 1698 "./src/dap.am" Amalgame_Compiler_MiValue* vars = Amalgame_Compiler_MiRecord_ResultOrNull(rec, "variables"); #line 1699 "./src/dap.am" self->PendingVars_Seq = dapSeq; #line 1700 "./src/dap.am" self->PendingVars_Names = AmalgameList_new(); #line 1701 "./src/dap.am" self->PendingVars_Types = AmalgameList_new(); #line 1702 "./src/dap.am" self->PendingVars_Values = AmalgameList_new(); #line 1703 "./src/dap.am" self->PendingVars_Queries = AmalgameList_new(); #line 1704 "./src/dap.am" self->PendingVars_Refs = AmalgameList_new(); #line 1705 "./src/dap.am" self->PendingVars_Idx = 0LL; #line 1706 "./src/dap.am" if ((vars != NULL) && (vars->Kind == 2LL)) { #line 1707 "./src/dap.am" i64 n = AmalgameList_count(vars->ListItems); #line 1708 "./src/dap.am" for (i64 i = 0LL; i < n; i++) { #line 1709 "./src/dap.am" Amalgame_Compiler_MiValue* v = (Amalgame_Compiler_MiValue*)AmalgameList_get(vars->ListItems, i); #line 1710 "./src/dap.am" if (v->Kind != 1LL) { continue; } #line 1711 "./src/dap.am" code_string nameS = Amalgame_Compiler_MiValue_FieldString(v, "name"); #line 1712 "./src/dap.am" code_string typeS = Amalgame_Compiler_MiValue_FieldString(v, "type"); #line 1713 "./src/dap.am" AmalgameList_add(self->PendingVars_Names, (void*)(intptr_t)(nameS)); #line 1714 "./src/dap.am" AmalgameList_add(self->PendingVars_Types, (void*)(intptr_t)(typeS)); #line 1715 "./src/dap.am" AmalgameList_add(self->PendingVars_Values, (void*)(intptr_t)(Amalgame_Compiler_MiValue_FieldString(v, "value"))); #line 1716 "./src/dap.am" AmalgameList_add(self->PendingVars_Queries, (void*)(intptr_t)(Amalgame_Compiler_DapServer_PrettyPrintQuery(nameS, typeS))); #line 1717 "./src/dap.am" AmalgameList_add(self->PendingVars_Refs, (void*)(intptr_t)(0LL)); } } #line 1720 "./src/dap.am" Amalgame_Compiler_DapServer_ProcessNextVarFollowup(self); } static void Amalgame_Compiler_DapServer_ProcessNextVarFollowup(Amalgame_Compiler_DapServer* self) { #line 1728 "./src/dap.am" i64 n = AmalgameList_count(self->PendingVars_Names); #line 1729 "./src/dap.am" while (self->PendingVars_Idx < n) { #line 1730 "./src/dap.am" code_string q = (code_string)AmalgameList_get(self->PendingVars_Queries, self->PendingVars_Idx); #line 1731 "./src/dap.am" if (String_Length(q) > 0LL) { #line 1732 "./src/dap.am" i64 _tok = Amalgame_Compiler_DapServer_IssueMiCommand(self, self->PendingVars_Seq, "varFollowup", code_string_concat((code_string_concat("-data-evaluate-expression \"", Amalgame_Compiler_Json_EscapeString(q))), "\"")); #line 1734 "./src/dap.am" return; } #line 1736 "./src/dap.am" self->PendingVars_Idx = (self->PendingVars_Idx + 1LL); } #line 1738 "./src/dap.am" Amalgame_Compiler_DapServer_SendVariablesResponse(self); } static code_string Amalgame_Compiler_DapServer_PrettyPrintQuery(code_string name, code_string typeS) { #line 1754 "./src/dap.am" if (code_string_equals(typeS, "AmalgameList *")) { return code_string_concat((code_string_concat("(int)((AmalgameList*)", name)), ")->size"); } #line 1755 "./src/dap.am" if (code_string_equals(typeS, "AmalgameMap *")) { return code_string_concat((code_string_concat("(int)((AmalgameMap*)", name)), ")->size"); } #line 1756 "./src/dap.am" if (code_string_equals(typeS, "AmalgameSet *")) { return code_string_concat((code_string_concat("(int)((AmalgameSet*)", name)), ")->map->size"); } #line 1757 "./src/dap.am" if (code_string_equals(typeS, "AmalgameClosure *")) { return code_string_concat((code_string_concat("(void*)((AmalgameClosure*)", name)), ")->env"); } #line 1758 "./src/dap.am" return ""; } static code_string Amalgame_Compiler_DapServer_PrettyPrintFormat(code_string typeS, code_string evalResult) { #line 1764 "./src/dap.am" if (code_string_equals(typeS, "AmalgameList *")) { return code_string_concat((code_string_concat("List[", evalResult)), "]"); } #line 1765 "./src/dap.am" if (code_string_equals(typeS, "AmalgameMap *")) { return code_string_concat((code_string_concat("Map[", evalResult)), "]"); } #line 1766 "./src/dap.am" if (code_string_equals(typeS, "AmalgameSet *")) { return code_string_concat((code_string_concat("Set[", evalResult)), "]"); } #line 1767 "./src/dap.am" if (code_string_equals(typeS, "AmalgameClosure *")) { return code_string_concat("λ env=", evalResult); } #line 1768 "./src/dap.am" return evalResult; } static void Amalgame_Compiler_DapServer_HandleVarFollowupResponse(Amalgame_Compiler_DapServer* self, Amalgame_Compiler_MiRecord* rec) { #line 1775 "./src/dap.am" i64 idx = self->PendingVars_Idx; #line 1776 "./src/dap.am" if (idx < AmalgameList_count(self->PendingVars_Names)) { #line 1777 "./src/dap.am" if (code_string_equals(rec->Class, "done")) { #line 1778 "./src/dap.am" Amalgame_Compiler_MiValue* valWrap = Amalgame_Compiler_MiRecord_ResultOrNull(rec, "value"); #line 1779 "./src/dap.am" if (valWrap != NULL) { #line 1780 "./src/dap.am" code_string typeS = (code_string)AmalgameList_get(self->PendingVars_Types, idx); #line 1781 "./src/dap.am" code_string nameS = (code_string)AmalgameList_get(self->PendingVars_Names, idx); #line 1782 "./src/dap.am" code_string evalRes = valWrap->Str; #line 1783 "./src/dap.am" code_string pretty = Amalgame_Compiler_DapServer_PrettyPrintFormat(typeS, evalRes); #line 1784 "./src/dap.am" Amalgame_Compiler_DapServer_RewriteValueAt(self, idx, pretty); #line 1789 "./src/dap.am" code_string ctype = Amalgame_Compiler_DapServer_ContainerKind(typeS); #line 1790 "./src/dap.am" if (String_Length(ctype) > 0LL) { #line 1791 "./src/dap.am" i64 size = String_ToInt(evalRes); #line 1792 "./src/dap.am" if (size > 0LL) { #line 1793 "./src/dap.am" i64 vref = Amalgame_Compiler_DapServer_AllocChildRef(self, ctype, nameS, size); #line 1794 "./src/dap.am" Amalgame_Compiler_DapServer_RewriteRefAt(self, idx, vref); } } } } #line 1800 "./src/dap.am" self->PendingVars_Idx = (idx + 1LL); } #line 1802 "./src/dap.am" Amalgame_Compiler_DapServer_ProcessNextVarFollowup(self); } static code_string Amalgame_Compiler_DapServer_ContainerKind(code_string typeS) { #line 1810 "./src/dap.am" if (code_string_equals(typeS, "AmalgameList *")) { return "AmalgameList"; } #line 1811 "./src/dap.am" if (code_string_equals(typeS, "AmalgameMap *")) { return "AmalgameMap"; } #line 1812 "./src/dap.am" if (code_string_equals(typeS, "AmalgameSet *")) { return "AmalgameSet"; } #line 1813 "./src/dap.am" return ""; } static void Amalgame_Compiler_DapServer_RewriteRefAt(Amalgame_Compiler_DapServer* self, i64 idx, i64 newRef) { #line 1817 "./src/dap.am" i64 n = AmalgameList_count(self->PendingVars_Refs); #line 1818 "./src/dap.am" AmalgameList* fresh = AmalgameList_new(); #line 1819 "./src/dap.am" for (i64 i = 0LL; i < n; i++) { #line 1820 "./src/dap.am" if (i == idx) { AmalgameList_add(fresh, (void*)(intptr_t)(newRef)); } else { #line 1821 "./src/dap.am" AmalgameList_add(fresh, (void*)(intptr_t)((i64)(intptr_t)AmalgameList_get(self->PendingVars_Refs, i))); } } #line 1823 "./src/dap.am" self->PendingVars_Refs = fresh; } static void Amalgame_Compiler_DapServer_RewriteValueAt(Amalgame_Compiler_DapServer* self, i64 idx, code_string newValue) { #line 1829 "./src/dap.am" i64 n = AmalgameList_count(self->PendingVars_Values); #line 1830 "./src/dap.am" AmalgameList* fresh = AmalgameList_new(); #line 1831 "./src/dap.am" for (i64 i = 0LL; i < n; i++) { #line 1832 "./src/dap.am" if (i == idx) { AmalgameList_add(fresh, (void*)(intptr_t)(newValue)); } else { #line 1833 "./src/dap.am" AmalgameList_add(fresh, (void*)(intptr_t)((code_string)AmalgameList_get(self->PendingVars_Values, i))); } } #line 1835 "./src/dap.am" self->PendingVars_Values = fresh; } static void Amalgame_Compiler_DapServer_SendVariablesResponse(Amalgame_Compiler_DapServer* self) { #line 1843 "./src/dap.am" code_string arr = "["; #line 1844 "./src/dap.am" i64 n = AmalgameList_count(self->PendingVars_Names); #line 1845 "./src/dap.am" for (i64 i = 0LL; i < n; i++) { #line 1846 "./src/dap.am" code_string name = (code_string)AmalgameList_get(self->PendingVars_Names, i); #line 1847 "./src/dap.am" code_string typeS = (code_string)AmalgameList_get(self->PendingVars_Types, i); #line 1848 "./src/dap.am" code_string value = (code_string)AmalgameList_get(self->PendingVars_Values, i); #line 1849 "./src/dap.am" i64 vref = (i64)(intptr_t)AmalgameList_get(self->PendingVars_Refs, i); #line 1850 "./src/dap.am" if (i > 0LL) { arr = (code_string_concat(arr, ",")); } #line 1851 "./src/dap.am" arr = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(arr, "{\"name\":\"")), Amalgame_Compiler_Json_EscapeString(name))), "\"")), ",\"value\":\"")), Amalgame_Compiler_Json_EscapeString(value))), "\"")), ",\"type\":\"")), Amalgame_Compiler_Json_EscapeString(typeS))), "\"")), ",\"variablesReference\":")), String_FromInt(vref))), "}")); } #line 1856 "./src/dap.am" arr = (code_string_concat(arr, "]")); #line 1857 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(self->PendingVars_Seq))), ",\"success\":true")), ",\"command\":\"variables\"")), ",\"body\":{\"variables\":")), arr)), "}}"); #line 1863 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); #line 1866 "./src/dap.am" self->PendingVars_Seq = -1LL; #line 1867 "./src/dap.am" self->PendingVars_Idx = 0LL; } static void Amalgame_Compiler_DapServer_RespondEvaluate(Amalgame_Compiler_DapServer* self, i64 dapSeq, Amalgame_Compiler_MiRecord* rec) { #line 1871 "./src/dap.am" if (!code_string_equals(rec->Class, "done")) { #line 1872 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapErrorResponse(self, dapSeq, "evaluate", "-data-evaluate-expression failed"); #line 1873 "./src/dap.am" return; } #line 1875 "./src/dap.am" Amalgame_Compiler_MiValue* valWrap = Amalgame_Compiler_MiRecord_ResultOrNull(rec, "value"); #line 1876 "./src/dap.am" code_string valStr = ""; #line 1877 "./src/dap.am" if (valWrap != NULL) { valStr = valWrap->Str; } #line 1878 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(dapSeq))), ",\"success\":true")), ",\"command\":\"evaluate\"")), ",\"body\":{\"result\":\"")), Amalgame_Compiler_Json_EscapeString(valStr))), "\",\"variablesReference\":0}}"); #line 1885 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static void Amalgame_Compiler_DapServer_HandleInitialize(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args) { #line 1892 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":true")), ",\"command\":\"initialize\"")), ",\"body\":{")), "\"supportsConfigurationDoneRequest\":true,")), "\"supportsTerminateRequest\":true,")), "\"supportTerminateDebuggee\":true")), "}}"); #line 1902 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); #line 1907 "./src/dap.am" code_string evt = code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"event\"")), ",\"event\":\"initialized\"}"); #line 1910 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, evt); } static void Amalgame_Compiler_DapServer_HandleDisconnect(Amalgame_Compiler_DapServer* self, i64 seq, Amalgame_Compiler_JsonValue* args) { #line 1917 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":true")), ",\"command\":\"disconnect\"}"); #line 1922 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); #line 1924 "./src/dap.am" Amalgame_Compiler_DapServer_WriteToFd(self, 1LL, "-gdb-exit\n"); #line 1925 "./src/dap.am" Amalgame_Compiler_DapServer_CloseGdbStdin(self); #line 1926 "./src/dap.am" self->StopRequested = 1; } static void Amalgame_Compiler_DapServer_SendDapErrorResponse(Amalgame_Compiler_DapServer* self, i64 seq, code_string command, code_string reason) { #line 1933 "./src/dap.am" code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"seq\":", String_FromInt(Amalgame_Compiler_DapServer_NextOutSeq(self)))), ",\"type\":\"response\"")), ",\"request_seq\":")), String_FromInt(seq))), ",\"success\":false")), ",\"command\":\"")), Amalgame_Compiler_Json_EscapeString(command))), "\"")), ",\"message\":\"")), Amalgame_Compiler_Json_EscapeString(reason))), "\"}"); #line 1939 "./src/dap.am" Amalgame_Compiler_DapServer_SendDapFrame(self, body); } static i64 Amalgame_Compiler_DapServer_NextOutSeq(Amalgame_Compiler_DapServer* self) { #line 1947 "./src/dap.am" { /* inline-C */ self->_outSeqCounter += 1; return self->_outSeqCounter; } } static void Amalgame_Compiler_DapServer_Cleanup(Amalgame_Compiler_DapServer* self) { #line 1955 "./src/dap.am" { /* inline-C */ #ifndef _WIN32 if (self->GdbInFd >= 0) { close((int) self->GdbInFd); self->GdbInFd = -1; } if (self->GdbOutFd >= 0) { close((int) self->GdbOutFd); self->GdbOutFd = -1; } int status = 0; if (self->GdbPid > 0) { /* Kill the whole gdb process group (gdb + any OpenOCD it * spawned in pipe mode) so the ST-LINK is freed for the * next session. SIGTERM first; if it lingers, SIGKILL. */ kill(-(pid_t) self->GdbPid, SIGTERM); for (int i = 0; i < 50; i++) { if (waitpid((pid_t) self->GdbPid, &status, WNOHANG) != 0) break; usleep(20000); } kill(-(pid_t) self->GdbPid, SIGKILL); waitpid((pid_t) self->GdbPid, &status, 0); } #endif } } i64 Amalgame_Compiler_DapServer_RunRaw(Amalgame_Compiler_DapServer* self) { #line 1979 "./src/dap.am" code_string exe = Amalgame_Compiler_DapServer_DetectBackend(self); #line 1980 "./src/dap.am" if (String_Length(exe) == 0LL) { #line 1981 "./src/dap.am" Console_WriteError("amc dap: no DAP backend found in PATH."); #line 1982 "./src/dap.am" Console_WriteError(""); #line 1983 "./src/dap.am" Console_WriteError("Install one of the following debug adapters:"); #line 1984 "./src/dap.am" Console_WriteError(" Linux: apt install lldb-18 (from https://apt.llvm.org/)"); #line 1985 "./src/dap.am" Console_WriteError(" → /usr/lib/llvm-18/bin/lldb-dap"); #line 1986 "./src/dap.am" Console_WriteError(" — or — apt install gdb (any distro's recent gdb is fine)"); #line 1987 "./src/dap.am" Console_WriteError(" macOS: xcode-select --install (lldb-dap ships with Xcode CLT 14+)"); #line 1988 "./src/dap.am" Console_WriteError(" Windows: pacman -S mingw-w64-x86_64-gdb (gdb 14+ has --dap, MSYS2)"); #line 1989 "./src/dap.am" Console_WriteError(""); #line 1990 "./src/dap.am" Console_WriteError("Then re-run `amc dap`. Use `amc build -g entry.am` first to embed"); #line 1991 "./src/dap.am" Console_WriteError("DWARF debug info so breakpoints can target .am source lines."); #line 1992 "./src/dap.am" return 127LL; } #line 1998 "./src/dap.am" return Amalgame_Compiler_DapServer_ExecBackend(self, exe); } static code_string Amalgame_Compiler_DapServer_DetectBackend(Amalgame_Compiler_DapServer* self) { #line 2009 "./src/dap.am" AmalgameList* cands = AmalgameList_new(); #line 2010 "./src/dap.am" AmalgameList_add(cands, (void*)(intptr_t)("lldb-dap")); #line 2011 "./src/dap.am" AmalgameList_add(cands, (void*)(intptr_t)("lldb-dap-20")); #line 2012 "./src/dap.am" AmalgameList_add(cands, (void*)(intptr_t)("lldb-dap-19")); #line 2013 "./src/dap.am" AmalgameList_add(cands, (void*)(intptr_t)("lldb-dap-18")); #line 2014 "./src/dap.am" AmalgameList_add(cands, (void*)(intptr_t)("/usr/lib/llvm-20/bin/lldb-dap")); #line 2015 "./src/dap.am" AmalgameList_add(cands, (void*)(intptr_t)("/usr/lib/llvm-19/bin/lldb-dap")); #line 2016 "./src/dap.am" AmalgameList_add(cands, (void*)(intptr_t)("/usr/lib/llvm-18/bin/lldb-dap")); #line 2017 "./src/dap.am" i64 n = AmalgameList_count(cands); #line 2018 "./src/dap.am" for (i64 i = 0LL; i < n; i++) { #line 2019 "./src/dap.am" code_string c = (code_string)AmalgameList_get(cands, i); #line 2020 "./src/dap.am" code_string hit = Amalgame_Compiler_DapServer_Probe(c); #line 2021 "./src/dap.am" if (String_Length(hit) > 0LL) { #line 2022 "./src/dap.am" return hit; } } #line 2032 "./src/dap.am" AmalgameList* gdbCands = AmalgameList_new(); #line 2033 "./src/dap.am" AmalgameList_add(gdbCands, (void*)(intptr_t)("gdb")); #line 2034 "./src/dap.am" AmalgameList_add(gdbCands, (void*)(intptr_t)("/usr/bin/gdb")); #line 2035 "./src/dap.am" AmalgameList_add(gdbCands, (void*)(intptr_t)("/opt/homebrew/bin/gdb")); #line 2036 "./src/dap.am" i64 m = AmalgameList_count(gdbCands); #line 2037 "./src/dap.am" for (i64 i = 0LL; i < m; i++) { #line 2038 "./src/dap.am" code_string c = (code_string)AmalgameList_get(gdbCands, i); #line 2039 "./src/dap.am" code_string hit = Amalgame_Compiler_DapServer_Probe(c); #line 2040 "./src/dap.am" if (String_Length(hit) > 0LL) { #line 2041 "./src/dap.am" return code_string_concat("gdb:", hit); } } #line 2044 "./src/dap.am" return ""; } static code_string Amalgame_Compiler_DapServer_Probe(code_string candidate) { #line 2051 "./src/dap.am" AmalgameProcessResult* probe = Process_RunCapture(code_string_concat((code_string_concat("command -v '", candidate)), "' 2>/dev/null")); #line 2052 "./src/dap.am" if ((probe->Exit != 0LL) || (String_Length(probe->Stdout) == 0LL)) { #line 2053 "./src/dap.am" return ""; } #line 2055 "./src/dap.am" code_string s = probe->Stdout; #line 2056 "./src/dap.am" i64 last = String_Length(s) - 1LL; #line 2057 "./src/dap.am" if (last >= 0LL) { #line 2058 "./src/dap.am" code_string tail = String_Substring(s, last, 1LL); #line 2059 "./src/dap.am" if (code_string_equals(tail, "\n")) { #line 2060 "./src/dap.am" s = String_Substring(s, 0LL, last); } } #line 2063 "./src/dap.am" return s; } static i64 Amalgame_Compiler_DapServer_ExecBackend(Amalgame_Compiler_DapServer* self, code_string exe) { #line 2072 "./src/dap.am" { /* inline-C */ #ifdef _WIN32 // Windows: no execvp here — execvp on MSVCRT would spawn // a child without replacing the process image, which // breaks DAP's contract that stdio is wired straight to // the backend. amc dap on Windows is a Phase-7+ item; // for now emit a clean error and return 127 (same exit // code the no-backend branch uses on POSIX). (void) exe; fprintf(stderr, "amc dap: not supported on Windows yet (see docs/proposals/dap-strategy.md).\n"); return 127; #else // Strip the `gdb:` sentinel DetectBackend added for the // gdb fallback path and remember it so we can inject the // `--dap` arg lldb-dap doesn't need. const char* exeStr = (const char*) exe; int isGdb = 0; if (strncmp(exeStr, "gdb:", 4) == 0) { isGdb = 1; exeStr += 4; } int parentArgc = code_argc; char** parentArgv = code_argv; int fwd = parentArgc - 2; if (fwd < 0) { fwd = 0; } // Pre-count surviving args after filtering our own flags. int filteredFwd = 0; for (int i = 0; i < fwd; i++) { const char* a = parentArgv[2 + i]; if (a == NULL) continue; if (strcmp(a, "--raw") == 0) continue; if (strcmp(a, "--show-runtime") == 0) continue; if (strcmp(a, "--bridge") == 0) continue; if (strcmp(a, "--self-test-mi") == 0) continue; filteredFwd++; } int extra = isGdb ? 1 : 0; int n = 1 + extra + filteredFwd + 1; char** argv = (char**) malloc(sizeof(char*) * (size_t) n); if (argv == NULL) { fprintf(stderr, "amc dap: out of memory building argv\n"); return 127; } int pos = 0; argv[pos++] = (char*) exeStr; if (isGdb) { argv[pos++] = (char*) "--dap"; } for (int i = 0; i < fwd; i++) { const char* a = parentArgv[2 + i]; if (a == NULL) continue; if (strcmp(a, "--raw") == 0) continue; if (strcmp(a, "--show-runtime") == 0) continue; if (strcmp(a, "--bridge") == 0) continue; if (strcmp(a, "--self-test-mi") == 0) continue; argv[pos++] = (char*) a; } argv[pos] = (char*) 0; execvp(exeStr, argv); // execvp returns only on error. perror("amc dap: execvp"); free(argv); return 127; #endif } } struct _Amalgame_Compiler_CurlResponse { i64 Status; code_string Body; code_string Error; code_bool Ok; }; Amalgame_Compiler_CurlResponse* Amalgame_Compiler_CurlResponse_new() { Amalgame_Compiler_CurlResponse* self = (Amalgame_Compiler_CurlResponse*) GC_MALLOC(sizeof(Amalgame_Compiler_CurlResponse)); #line 42 "./src/migrate.am" self->Status = 0LL; #line 43 "./src/migrate.am" self->Body = ""; #line 44 "./src/migrate.am" self->Error = ""; #line 45 "./src/migrate.am" self->Ok = 0; return self; } struct _Amalgame_Compiler_MigrateResult { code_bool Ok; code_string Content; code_string Error; i64 InputTokens; i64 OutputTokens; }; Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateResult_new() { Amalgame_Compiler_MigrateResult* self = (Amalgame_Compiler_MigrateResult*) GC_MALLOC(sizeof(Amalgame_Compiler_MigrateResult)); #line 60 "./src/migrate.am" self->Ok = 0; #line 61 "./src/migrate.am" self->Content = ""; #line 62 "./src/migrate.am" self->Error = ""; #line 63 "./src/migrate.am" self->InputTokens = -1LL; #line 64 "./src/migrate.am" self->OutputTokens = -1LL; return self; } struct _Amalgame_Compiler_MigrateCommand { }; void Amalgame_Compiler_MigrateCommand_PrintUsage(); i64 Amalgame_Compiler_MigrateCommand_Run(i64 argc); static i64 Amalgame_Compiler_MigrateCommand_RunMigrateOne(code_string input, code_string output, code_string langHint, code_string provider, code_string model, code_bool force, code_bool dryRun, code_bool promptOnly, code_bool noCheck, i64 maxLines, code_bool noCache); static i64 Amalgame_Compiler_MigrateCommand_RunMigrateDirectory(code_string dir, code_string langHint, code_string provider, code_string model, code_bool force, code_bool dryRun, code_bool promptOnly, code_bool noCheck, i64 maxLines, code_bool noCache); static code_bool Amalgame_Compiler_MigrateCommand_IsDirectory(code_string path); static code_string Amalgame_Compiler_MigrateCommand_DetectLanguage(code_string path); static code_string Amalgame_Compiler_MigrateCommand_DefaultOutputPath(code_string input); static i64 Amalgame_Compiler_MigrateCommand_CountLines(code_string s); static code_string Amalgame_Compiler_MigrateCommand_BuildPrompt(code_string lang, code_string source); static code_string Amalgame_Compiler_MigrateCommand_BuildSystemPrompt(code_string lang); static code_string Amalgame_Compiler_MigrateCommand_BuildUserPrompt(code_string lang, code_string source); code_string Amalgame_Compiler_MigrateCommand_LoadDocsHeader(); static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallProvider(code_string provider, code_string model, code_string lang, code_string source); Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallProviderRaw(code_string provider, code_string model, code_string systemPrompt, code_string userPrompt); code_string Amalgame_Compiler_MigrateCommand_AutoSelectProvider(); code_string Amalgame_Compiler_MigrateCommand_EstimateCost(code_string provider, code_string model, code_string systemPrompt, code_string userPrompt); code_string Amalgame_Compiler_MigrateCommand_FormatActualCost(code_string provider, code_string model, i64 inputToks, i64 outputToks); static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallClaudeApiRaw(code_string model, code_string systemPrompt, code_string userPrompt); static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallChatGptApi(code_string model, code_string systemPrompt, code_string userPrompt); static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallGeminiApi(code_string model, code_string systemPrompt, code_string userPrompt); static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallCustomScript(code_string systemPrompt, code_string userPrompt); static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallClaudeCli(code_string model, code_string prompt); static code_bool Amalgame_Compiler_MigrateCommand_IsCommandAvailable(code_string cmd); code_string Amalgame_Compiler_MigrateCommand_CacheHash(code_string source, code_string systemPrompt); code_string Amalgame_Compiler_MigrateCommand_CachePath(code_string hash); code_string Amalgame_Compiler_MigrateCommand_CacheLookup(code_string source, code_string systemPrompt); void Amalgame_Compiler_MigrateCommand_CacheStore(code_string source, code_string systemPrompt, code_string content); i64 Amalgame_Compiler_MigrateCommand_StreamClaudeCli(code_string model, code_string prompt); static Amalgame_Compiler_CurlResponse* Amalgame_Compiler_MigrateCommand_CurlPost(code_string url, code_string body, AmalgameMap* headers); static code_string Amalgame_Compiler_MigrateCommand_ShellEscape(code_string s); static code_string Amalgame_Compiler_MigrateCommand_StripFences(code_string s); Amalgame_Compiler_MigrateCommand* Amalgame_Compiler_MigrateCommand_new() { Amalgame_Compiler_MigrateCommand* self = (Amalgame_Compiler_MigrateCommand*) GC_MALLOC(sizeof(Amalgame_Compiler_MigrateCommand)); return self; } void Amalgame_Compiler_MigrateCommand_PrintUsage() { #line 74 "./src/migrate.am" Console_WriteError("Usage: amc migrate [flags]"); #line 75 "./src/migrate.am" Console_WriteError(""); #line 76 "./src/migrate.am" Console_WriteError("Translates a source file in any supported language to Amalgame"); #line 77 "./src/migrate.am" Console_WriteError("via an LLM (v0: requires `claude` CLI on PATH)."); #line 78 "./src/migrate.am" Console_WriteError(""); #line 79 "./src/migrate.am" Console_WriteError("Supported source extensions:"); #line 80 "./src/migrate.am" Console_WriteError(" .ts .tsx .js .jsx .mjs .py .java .cs .go .rs"); #line 81 "./src/migrate.am" Console_WriteError(" .cpp .cc .cxx .hpp .h++ .c .h .kt .kts .swift .rb .php"); #line 82 "./src/migrate.am" Console_WriteError(""); #line 83 "./src/migrate.am" Console_WriteError("Flags:"); #line 84 "./src/migrate.am" Console_WriteError(" -o, --output Output path (default: .am next to source)."); #line 85 "./src/migrate.am" Console_WriteError(" --lang Override extension-based language detection."); #line 86 "./src/migrate.am" Console_WriteError(" --provider LLM provider. Built-in: claude (CLI), claude-api"); #line 87 "./src/migrate.am" Console_WriteError(" (Anthropic), chatgpt (OpenAI), gemini (Google),"); #line 88 "./src/migrate.am" Console_WriteError(" custom (delegates to AMC_CUSTOM_PROVIDER_CMD)."); #line 89 "./src/migrate.am" Console_WriteError(" Auto-selects API by env var: ANTHROPIC_API_KEY →"); #line 90 "./src/migrate.am" Console_WriteError(" claude-api, OPENAI_API_KEY → chatgpt,"); #line 91 "./src/migrate.am" Console_WriteError(" GEMINI_API_KEY → gemini, otherwise → claude (CLI)."); #line 92 "./src/migrate.am" Console_WriteError(" --model Pass a specific model id to the provider."); #line 93 "./src/migrate.am" Console_WriteError(" --max-lines Refuse files larger than n lines (default: 2000)."); #line 94 "./src/migrate.am" Console_WriteError(" --no-check Skip the post-migration `amc --check` validation."); #line 95 "./src/migrate.am" Console_WriteError(" --no-cache Skip the on-disk result cache (always re-call LLM)."); #line 96 "./src/migrate.am" Console_WriteError(" --force Overwrite an existing .am at the output path."); #line 97 "./src/migrate.am" Console_WriteError(" --dry-run Print what would happen without invoking the LLM."); #line 98 "./src/migrate.am" Console_WriteError(" --prompt-only Dump the assembled prompt to stdout and exit."); #line 99 "./src/migrate.am" Console_WriteError(" -h, --help Print this help and exit."); #line 100 "./src/migrate.am" Console_WriteError(""); #line 101 "./src/migrate.am" Console_WriteError("See docs/proposals/amc-migrate.md for design rationale."); } i64 Amalgame_Compiler_MigrateCommand_Run(i64 argc) { #line 106 "./src/migrate.am" code_string input = ""; #line 107 "./src/migrate.am" code_string output = ""; #line 108 "./src/migrate.am" code_string langHint = ""; #line 109 "./src/migrate.am" code_string provider = ""; #line 110 "./src/migrate.am" code_bool providerSet = 0; #line 111 "./src/migrate.am" code_string model = ""; #line 112 "./src/migrate.am" code_bool dryRun = 0; #line 113 "./src/migrate.am" code_bool promptOnly = 0; #line 114 "./src/migrate.am" code_bool noCheck = 0; #line 115 "./src/migrate.am" code_bool force = 0; #line 116 "./src/migrate.am" i64 maxLines = 2000LL; #line 117 "./src/migrate.am" code_bool noCache = 0; #line 120 "./src/migrate.am" i64 i = 2LL; #line 121 "./src/migrate.am" while (i < argc) { #line 122 "./src/migrate.am" code_string a = Args_Get(i); #line 123 "./src/migrate.am" if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) { #line 124 "./src/migrate.am" Amalgame_Compiler_MigrateCommand_PrintUsage(); #line 125 "./src/migrate.am" return 0LL; } else if ((code_string_equals(a, "-o")) || (code_string_equals(a, "--output"))) { #line 127 "./src/migrate.am" i = (i + 1LL); #line 128 "./src/migrate.am" if (i >= argc) { #line 129 "./src/migrate.am" Console_WriteError(code_string_concat((code_string_concat("amc migrate: ", a)), " requires a value")); #line 130 "./src/migrate.am" return 1LL; } #line 132 "./src/migrate.am" output = Args_Get(i); } else if (code_string_equals(a, "--dry-run")) { #line 134 "./src/migrate.am" dryRun = 1; } else if (code_string_equals(a, "--prompt-only")) { #line 136 "./src/migrate.am" promptOnly = 1; } else if (code_string_equals(a, "--no-check")) { #line 138 "./src/migrate.am" noCheck = 1; } else if (code_string_equals(a, "--no-cache")) { #line 140 "./src/migrate.am" noCache = 1; } else if (code_string_equals(a, "--force")) { #line 142 "./src/migrate.am" force = 1; } else if (code_string_equals(a, "--lang")) { #line 144 "./src/migrate.am" i = (i + 1LL); #line 145 "./src/migrate.am" if (i >= argc) { #line 146 "./src/migrate.am" Console_WriteError("amc migrate: --lang requires a value"); #line 147 "./src/migrate.am" return 1LL; } #line 149 "./src/migrate.am" langHint = Args_Get(i); } else if (code_string_equals(a, "--provider")) { #line 151 "./src/migrate.am" i = (i + 1LL); #line 152 "./src/migrate.am" if (i >= argc) { #line 153 "./src/migrate.am" Console_WriteError("amc migrate: --provider requires a value"); #line 154 "./src/migrate.am" return 1LL; } #line 156 "./src/migrate.am" provider = Args_Get(i); #line 157 "./src/migrate.am" providerSet = 1; } else if (code_string_equals(a, "--model")) { #line 159 "./src/migrate.am" i = (i + 1LL); #line 160 "./src/migrate.am" if (i >= argc) { #line 161 "./src/migrate.am" Console_WriteError("amc migrate: --model requires a value"); #line 162 "./src/migrate.am" return 1LL; } #line 164 "./src/migrate.am" model = Args_Get(i); } else if (code_string_equals(a, "--max-lines")) { #line 166 "./src/migrate.am" i = (i + 1LL); #line 167 "./src/migrate.am" if (i >= argc) { #line 168 "./src/migrate.am" Console_WriteError("amc migrate: --max-lines requires a value"); #line 169 "./src/migrate.am" return 1LL; } #line 171 "./src/migrate.am" maxLines = String_ToInt(Args_Get(i)); #line 172 "./src/migrate.am" if (maxLines <= 0LL) { #line 173 "./src/migrate.am" Console_WriteError("amc migrate: --max-lines must be > 0"); #line 174 "./src/migrate.am" return 1LL; } } else if (String_StartsWith(a, "-")) { #line 177 "./src/migrate.am" Console_WriteError(code_string_concat((code_string_concat("amc migrate: unknown option '", a)), "'")); #line 178 "./src/migrate.am" return 1LL; } else { #line 180 "./src/migrate.am" if (String_Length(input) > 0LL) { #line 181 "./src/migrate.am" Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat("amc migrate: too many positional arguments (got '", a)), "', already had '")), input)), "')")); #line 182 "./src/migrate.am" return 1LL; } #line 184 "./src/migrate.am" input = a; } #line 186 "./src/migrate.am" i = (i + 1LL); } #line 189 "./src/migrate.am" if (String_Length(input) == 0LL) { #line 190 "./src/migrate.am" Console_WriteError("amc migrate: no input file"); #line 191 "./src/migrate.am" Console_WriteError("usage: amc migrate [--output ] [--lang ] [--provider ] [--model ]"); #line 192 "./src/migrate.am" Console_WriteError(" [--dry-run] [--prompt-only] [--no-check] [--force] [--max-lines ]"); #line 193 "./src/migrate.am" return 1LL; } #line 201 "./src/migrate.am" if (!providerSet) { #line 202 "./src/migrate.am" provider = Amalgame_Compiler_MigrateCommand_AutoSelectProvider(); } #line 205 "./src/migrate.am" if (!File_Exists(input)) { #line 206 "./src/migrate.am" Console_WriteError(code_string_concat("amc migrate: path not found: ", input)); #line 207 "./src/migrate.am" return 1LL; } #line 215 "./src/migrate.am" if (Amalgame_Compiler_MigrateCommand_IsDirectory(input)) { #line 216 "./src/migrate.am" if (String_Length(output) > 0LL) { #line 217 "./src/migrate.am" Console_WriteError("amc migrate: --output cannot be used with directory input (writes are in-place next to each source)."); #line 218 "./src/migrate.am" return 1LL; } #line 220 "./src/migrate.am" return Amalgame_Compiler_MigrateCommand_RunMigrateDirectory(input, langHint, provider, model, force, dryRun, promptOnly, noCheck, maxLines, noCache); } #line 223 "./src/migrate.am" return Amalgame_Compiler_MigrateCommand_RunMigrateOne(input, output, langHint, provider, model, force, dryRun, promptOnly, noCheck, maxLines, noCache); } static i64 Amalgame_Compiler_MigrateCommand_RunMigrateOne(code_string input, code_string output, code_string langHint, code_string provider, code_string model, code_bool force, code_bool dryRun, code_bool promptOnly, code_bool noCheck, i64 maxLines, code_bool noCache) { #line 232 "./src/migrate.am" code_string lang = langHint; #line 233 "./src/migrate.am" if (String_Length(lang) == 0LL) { #line 234 "./src/migrate.am" lang = Amalgame_Compiler_MigrateCommand_DetectLanguage(input); } #line 236 "./src/migrate.am" if (String_Length(lang) == 0LL) { #line 237 "./src/migrate.am" Console_WriteError(code_string_concat((code_string_concat("amc migrate: unrecognized source extension for '", input)), "'")); #line 238 "./src/migrate.am" Console_WriteError("Supported extensions: .ts .tsx .js .jsx .mjs .py .java .cs .go .rs .cpp .cc .cxx .hpp .h++ .c .h .kt .kts .swift .rb .php"); #line 239 "./src/migrate.am" Console_WriteError("Or pass --lang with a language name."); #line 240 "./src/migrate.am" return 1LL; } #line 243 "./src/migrate.am" code_string source = File_ReadAll(input); #line 244 "./src/migrate.am" i64 lineCount = Amalgame_Compiler_MigrateCommand_CountLines(source); #line 245 "./src/migrate.am" if (lineCount > maxLines) { #line 246 "./src/migrate.am" Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat("amc migrate: source exceeds ", String_FromInt(maxLines))), " lines (got ")), String_FromInt(lineCount))), ")")); #line 247 "./src/migrate.am" Console_WriteError("Suggestion: split the file or override with --max-lines ."); #line 248 "./src/migrate.am" return 1LL; } #line 255 "./src/migrate.am" if (promptOnly) { #line 256 "./src/migrate.am" Console_WriteLine(Amalgame_Compiler_MigrateCommand_BuildPrompt(lang, source)); #line 257 "./src/migrate.am" return 0LL; } #line 261 "./src/migrate.am" code_string outPath = output; #line 262 "./src/migrate.am" if (String_Length(outPath) == 0LL) { #line 263 "./src/migrate.am" outPath = Amalgame_Compiler_MigrateCommand_DefaultOutputPath(input); } #line 265 "./src/migrate.am" if (File_Exists(outPath) && !force) { #line 266 "./src/migrate.am" Console_WriteError(code_string_concat("amc migrate: output exists: ", outPath)); #line 267 "./src/migrate.am" Console_WriteError("Pass --force to overwrite."); #line 268 "./src/migrate.am" return 1LL; } #line 272 "./src/migrate.am" if (dryRun) { #line 273 "./src/migrate.am" code_string sysP = Amalgame_Compiler_MigrateCommand_BuildSystemPrompt(lang); #line 274 "./src/migrate.am" code_string usrP = Amalgame_Compiler_MigrateCommand_BuildUserPrompt(lang, source); #line 275 "./src/migrate.am" code_string est = Amalgame_Compiler_MigrateCommand_EstimateCost(provider, model, sysP, usrP); #line 276 "./src/migrate.am" Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("[migrate] would migrate: ", input)), " (")), lang)), ", ")), String_FromInt(lineCount))), " lines)")); #line 277 "./src/migrate.am" Console_WriteLine(code_string_concat("[migrate] would write: ", outPath)); #line 278 "./src/migrate.am" Console_WriteLine(code_string_concat("[migrate] provider: ", provider)); #line 279 "./src/migrate.am" if (String_Length(model) > 0LL) { #line 280 "./src/migrate.am" Console_WriteLine(code_string_concat("[migrate] model: ", model)); } #line 282 "./src/migrate.am" Console_WriteLine(code_string_concat("[migrate] estimated cost: ", est)); #line 283 "./src/migrate.am" return 0LL; } #line 289 "./src/migrate.am" code_string sysForCache = Amalgame_Compiler_MigrateCommand_BuildSystemPrompt(lang); #line 290 "./src/migrate.am" if (!noCache) { #line 291 "./src/migrate.am" code_string cached = Amalgame_Compiler_MigrateCommand_CacheLookup(source, sysForCache); #line 292 "./src/migrate.am" if (String_Length(cached) > 0LL) { #line 293 "./src/migrate.am" code_bool writeOkC = File_WriteAll(outPath, cached); #line 294 "./src/migrate.am" if (!writeOkC) { #line 295 "./src/migrate.am" Console_WriteError(code_string_concat("amc migrate: failed to write ", outPath)); #line 296 "./src/migrate.am" return 1LL; } #line 298 "./src/migrate.am" Console_WriteLine(code_string_concat((code_string_concat("[migrate] wrote ", outPath)), " (cache hit)")); #line 299 "./src/migrate.am" if (!noCheck) { #line 300 "./src/migrate.am" code_string amcPathC = Args_Get(0LL); #line 301 "./src/migrate.am" code_string cmdC = code_string_concat((code_string_concat(amcPathC, " --check ")), outPath); #line 302 "./src/migrate.am" AmalgameProcessResult* checkC = Process_RunCapture(cmdC); #line 303 "./src/migrate.am" if (checkC->Exit != 0LL) { #line 304 "./src/migrate.am" Console_WriteError("[migrate] check failed:"); #line 305 "./src/migrate.am" Console_WriteError(checkC->Stdout); #line 306 "./src/migrate.am" return 1LL; } #line 308 "./src/migrate.am" Console_WriteLine("[migrate] check passed"); } #line 310 "./src/migrate.am" return 0LL; } } #line 318 "./src/migrate.am" Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("[migrate] processing ", input)), " (")), lang)), ", ")), String_FromInt(lineCount))), " lines, provider=")), provider)), ")...")); #line 319 "./src/migrate.am" Amalgame_Compiler_MigrateResult* result = Amalgame_Compiler_MigrateCommand_CallProvider(provider, model, lang, source); #line 320 "./src/migrate.am" if (!result->Ok) { #line 321 "./src/migrate.am" Console_WriteError(code_string_concat("amc migrate: ", result->Error)); #line 322 "./src/migrate.am" return 1LL; } #line 326 "./src/migrate.am" code_bool writeOk = File_WriteAll(outPath, result->Content); #line 327 "./src/migrate.am" if (!writeOk) { #line 328 "./src/migrate.am" Console_WriteError(code_string_concat("amc migrate: failed to write ", outPath)); #line 329 "./src/migrate.am" return 1LL; } #line 331 "./src/migrate.am" Console_WriteLine(code_string_concat("[migrate] wrote ", outPath)); #line 334 "./src/migrate.am" code_string realCost = Amalgame_Compiler_MigrateCommand_FormatActualCost(provider, model, result->InputTokens, result->OutputTokens); #line 335 "./src/migrate.am" if (String_Length(realCost) > 0LL) { #line 336 "./src/migrate.am" Console_WriteLine(code_string_concat("[migrate] cost: ", realCost)); } #line 339 "./src/migrate.am" if (!noCache) { #line 340 "./src/migrate.am" Amalgame_Compiler_MigrateCommand_CacheStore(source, sysForCache, result->Content); } #line 344 "./src/migrate.am" if (!noCheck) { #line 345 "./src/migrate.am" code_string amcPath = Args_Get(0LL); #line 346 "./src/migrate.am" code_string cmd = code_string_concat((code_string_concat(amcPath, " --check ")), outPath); #line 347 "./src/migrate.am" AmalgameProcessResult* check = Process_RunCapture(cmd); #line 348 "./src/migrate.am" if (check->Exit != 0LL) { #line 349 "./src/migrate.am" Console_WriteError("[migrate] check failed (typechecker errors in the migrated file):"); #line 350 "./src/migrate.am" Console_WriteError(check->Stdout); #line 351 "./src/migrate.am" Console_WriteError("The .am file was still written so you can inspect / fix manually."); #line 352 "./src/migrate.am" return 1LL; } #line 354 "./src/migrate.am" Console_WriteLine("[migrate] check passed"); } #line 357 "./src/migrate.am" return 0LL; } static i64 Amalgame_Compiler_MigrateCommand_RunMigrateDirectory(code_string dir, code_string langHint, code_string provider, code_string model, code_bool force, code_bool dryRun, code_bool promptOnly, code_bool noCheck, i64 maxLines, code_bool noCache) { #line 370 "./src/migrate.am" Console_WriteError(code_string_concat((code_string_concat("[migrate] discovering source files in ", dir)), "...")); #line 371 "./src/migrate.am" code_string findCmd = code_string_concat((code_string_concat("find ", dir)), " -type f 2>/dev/null"); #line 372 "./src/migrate.am" AmalgameProcessResult* result = Process_RunCapture(findCmd); #line 373 "./src/migrate.am" if (result->Exit != 0LL) { #line 374 "./src/migrate.am" Console_WriteError(code_string_concat("amc migrate: failed to enumerate ", dir)); #line 375 "./src/migrate.am" return 1LL; } #line 377 "./src/migrate.am" AmalgameList* lines = String_Split(String_Trim(result->Stdout), "\n"); #line 378 "./src/migrate.am" i64 n = AmalgameList_count(lines); #line 379 "./src/migrate.am" AmalgameList* candidates = AmalgameList_new(); #line 380 "./src/migrate.am" AmalgameList* langs = AmalgameList_new(); #line 381 "./src/migrate.am" for (i64 i = 0LL; i < n; i++) { #line 382 "./src/migrate.am" code_string path = String_Trim((code_string)AmalgameList_get(lines, i)); #line 383 "./src/migrate.am" if (String_Length(path) == 0LL) { continue; } #line 386 "./src/migrate.am" if (String_EndsWith(path, ".am")) { continue; } #line 387 "./src/migrate.am" code_string lang = Amalgame_Compiler_MigrateCommand_DetectLanguage(path); #line 388 "./src/migrate.am" if (String_Length(lang) == 0LL) { continue; } #line 389 "./src/migrate.am" AmalgameList_add(candidates, (void*)(intptr_t)(path)); #line 390 "./src/migrate.am" AmalgameList_add(langs, (void*)(intptr_t)(lang)); } #line 392 "./src/migrate.am" i64 total = AmalgameList_count(candidates); #line 393 "./src/migrate.am" if (total == 0LL) { #line 394 "./src/migrate.am" Console_WriteError(code_string_concat("[migrate] no recognized source files found in ", dir)); #line 395 "./src/migrate.am" return 0LL; } #line 397 "./src/migrate.am" Console_WriteError(code_string_concat((code_string_concat("[migrate] found ", String_FromInt(total))), " file(s) to migrate")); #line 399 "./src/migrate.am" i64 ok = 0LL; #line 400 "./src/migrate.am" i64 failed = 0LL; #line 401 "./src/migrate.am" for (i64 j = 0LL; j < total; j++) { #line 402 "./src/migrate.am" code_string path = (code_string)AmalgameList_get(candidates, j); #line 403 "./src/migrate.am" code_string perFileLang = langHint; #line 404 "./src/migrate.am" if (String_Length(perFileLang) == 0LL) { #line 405 "./src/migrate.am" perFileLang = (code_string)AmalgameList_get(langs, j); } #line 408 "./src/migrate.am" i64 r = Amalgame_Compiler_MigrateCommand_RunMigrateOne(path, "", perFileLang, provider, model, force, dryRun, promptOnly, noCheck, maxLines, noCache); #line 409 "./src/migrate.am" if (r == 0LL) { #line 410 "./src/migrate.am" ok = (ok + 1LL); } else { #line 412 "./src/migrate.am" failed = (failed + 1LL); } } #line 415 "./src/migrate.am" Console_WriteLine(""); #line 416 "./src/migrate.am" Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("[migrate] summary: ", String_FromInt(ok))), "/")), String_FromInt(total))), " succeeded, ")), String_FromInt(failed))), " failed")); #line 417 "./src/migrate.am" if (failed > 0LL) { return 1LL; } #line 418 "./src/migrate.am" return 0LL; } static code_bool Amalgame_Compiler_MigrateCommand_IsDirectory(code_string path) { #line 425 "./src/migrate.am" code_string cmd = code_string_concat((code_string_concat("[ -d \"", path)), "\" ] && echo y || echo n"); #line 426 "./src/migrate.am" AmalgameProcessResult* res = Process_RunCapture(cmd); #line 427 "./src/migrate.am" code_string answer = String_Trim(res->Stdout); #line 428 "./src/migrate.am" return code_string_equals(answer, "y"); } static code_string Amalgame_Compiler_MigrateCommand_DetectLanguage(code_string path) { #line 433 "./src/migrate.am" if (String_EndsWith(path, ".ts")) { return "TypeScript"; } #line 434 "./src/migrate.am" if (String_EndsWith(path, ".tsx")) { return "TypeScript"; } #line 435 "./src/migrate.am" if (String_EndsWith(path, ".js")) { return "JavaScript"; } #line 436 "./src/migrate.am" if (String_EndsWith(path, ".jsx")) { return "JavaScript"; } #line 437 "./src/migrate.am" if (String_EndsWith(path, ".mjs")) { return "JavaScript"; } #line 438 "./src/migrate.am" if (String_EndsWith(path, ".py")) { return "Python"; } #line 439 "./src/migrate.am" if (String_EndsWith(path, ".java")) { return "Java"; } #line 440 "./src/migrate.am" if (String_EndsWith(path, ".cs")) { return "C#"; } #line 441 "./src/migrate.am" if (String_EndsWith(path, ".go")) { return "Go"; } #line 442 "./src/migrate.am" if (String_EndsWith(path, ".rs")) { return "Rust"; } #line 443 "./src/migrate.am" if (String_EndsWith(path, ".cpp")) { return "C++"; } #line 444 "./src/migrate.am" if (String_EndsWith(path, ".cc")) { return "C++"; } #line 445 "./src/migrate.am" if (String_EndsWith(path, ".cxx")) { return "C++"; } #line 446 "./src/migrate.am" if (String_EndsWith(path, ".hpp")) { return "C++"; } #line 447 "./src/migrate.am" if (String_EndsWith(path, ".h++")) { return "C++"; } #line 448 "./src/migrate.am" if (String_EndsWith(path, ".c")) { return "C"; } #line 449 "./src/migrate.am" if (String_EndsWith(path, ".h")) { return "C"; } #line 450 "./src/migrate.am" if (String_EndsWith(path, ".kt")) { return "Kotlin"; } #line 451 "./src/migrate.am" if (String_EndsWith(path, ".kts")) { return "Kotlin"; } #line 452 "./src/migrate.am" if (String_EndsWith(path, ".swift")) { return "Swift"; } #line 453 "./src/migrate.am" if (String_EndsWith(path, ".rb")) { return "Ruby"; } #line 454 "./src/migrate.am" if (String_EndsWith(path, ".php")) { return "PHP"; } #line 455 "./src/migrate.am" return ""; } static code_string Amalgame_Compiler_MigrateCommand_DefaultOutputPath(code_string input) { #line 461 "./src/migrate.am" i64 lastDot = String_LastIndexOf(input, "."); #line 462 "./src/migrate.am" i64 lastSlash = String_LastIndexOf(input, "/"); #line 464 "./src/migrate.am" if ((lastDot <= lastSlash) || (lastDot <= 0LL)) { #line 465 "./src/migrate.am" return code_string_concat(input, ".am"); } #line 467 "./src/migrate.am" return code_string_concat(String_Substring(input, 0LL, lastDot), ".am"); } static i64 Amalgame_Compiler_MigrateCommand_CountLines(code_string s) { #line 472 "./src/migrate.am" i64 len = String_Length(s); #line 473 "./src/migrate.am" if (len == 0LL) { return 0LL; } #line 474 "./src/migrate.am" i64 n = 1LL; #line 475 "./src/migrate.am" for (i64 i = 0LL; i < len; i++) { #line 476 "./src/migrate.am" code_string ch = String_CharAt1(s, i); #line 477 "./src/migrate.am" if (code_string_equals(ch, "\n")) { n = (n + 1LL); } } #line 479 "./src/migrate.am" return n; } static code_string Amalgame_Compiler_MigrateCommand_BuildPrompt(code_string lang, code_string source) { #line 492 "./src/migrate.am" return code_string_concat((code_string_concat(Amalgame_Compiler_MigrateCommand_BuildSystemPrompt(lang), "\n\n")), Amalgame_Compiler_MigrateCommand_BuildUserPrompt(lang, source)); } static code_string Amalgame_Compiler_MigrateCommand_BuildSystemPrompt(code_string lang) { #line 503 "./src/migrate.am" code_string lb = "{"; #line 504 "./src/migrate.am" code_string rb = "}"; #line 505 "./src/migrate.am" code_string p = ""; #line 506 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat(p, "You are translating ")), lang)), " source code to Amalgame.\n")); #line 507 "./src/migrate.am" p = (code_string_concat(p, "Amalgame is a self-hosted programming language that transpiles to C.\n")); #line 508 "./src/migrate.am" p = (code_string_concat(p, "It uses class-based OOP with explicit visibility modifiers, generic\n")); #line 509 "./src/migrate.am" p = (code_string_concat(p, "collections (List, Map, Set), ML-style match expressions,\n")); #line 510 "./src/migrate.am" p = (code_string_concat(p, "and exception-based error handling. Higher-order list operations like\n")); #line 511 "./src/migrate.am" p = (code_string_concat(p, ".Map / .Filter / .Reduce / .Any / .All / .CountIf take lambdas.\n")); #line 512 "./src/migrate.am" p = (code_string_concat(p, "\n")); #line 513 "./src/migrate.am" p = (code_string_concat(p, "## Amalgame conventions\n")); #line 514 "./src/migrate.am" p = (code_string_concat(p, "- Files start with `namespace ` then declarations.\n")); #line 515 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- Classes: `public class Name ")), lb)), " public Field: int = 0; ... ")), rb)), "`.\n")); #line 516 "./src/migrate.am" p = (code_string_concat(p, "- Data classes (record-like): `public data class User(string Name, int Age)`.\n")); #line 517 "./src/migrate.am" p = (code_string_concat(p, "- Constructors: `let u = new User(\"Alice\", 30)`.\n")); #line 518 "./src/migrate.am" p = (code_string_concat(p, "- Locals: `let x = 1` (immutable), `var y = 2` (mutable).\n")); #line 519 "./src/migrate.am" p = (code_string_concat(p, "- Type annotations are optional but supported: `let n: int = 1`.\n")); #line 520 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- Lambdas: `(x, y) => x + y`, or block: `x => ")), lb)), " let d = x*2; return d+1 ")), rb)), "`.\n")); #line 521 "./src/migrate.am" p = (code_string_concat(p, "- Higher-order list: `users.Map(u => u.Name)`, `xs.Filter(x => x > 0)`.\n")); #line 522 "./src/migrate.am" p = (code_string_concat(p, "- Generics: `let xs = new List()`, `let m = new Map()`.\n")); #line 523 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- Match expression: `match x ")), lb)), " 0 => \"zero\", 1 => \"one\", _ => \"other\" ")), rb)), "`.\n")); #line 524 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- Try/catch: `try ")), lb)), " ... ")), rb)), " catch (e) ")), lb)), " ... ")), rb)), "`. Throw with `throw `.\n")); #line 525 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- Console output: `Console.WriteLine(\"x=")), lb)), "x")), rb)), "\")` (string interpolation).\n")); #line 526 "./src/migrate.am" p = (code_string_concat(p, "- File I/O: `File.ReadAll(path)`, `File.WriteAll(path, text)`.\n")); #line 527 "./src/migrate.am" p = (code_string_concat(p, "- Process: `Process.RunCapture(cmd)` returns an exit + stdout.\n")); #line 528 "./src/migrate.am" p = (code_string_concat(p, "- HTTP: install the `amalgame-net-http` package (`amc package add net-http`) for client + server.\n")); #line 529 "./src/migrate.am" p = (code_string_concat(p, "- Comments: `//` line, `/* ... */` block.\n")); #line 530 "./src/migrate.am" p = (code_string_concat(p, "- Null-safe: `obj?.Field`, `a ?? b`. Nullable type: `Foo?`.\n")); #line 531 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- Enum: `enum Direction ")), lb)), " North, South, East, West ")), rb)), "`.\n")); #line 532 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- Interface (method-only, no fields): `interface IDrawable ")), lb)), " void Draw() ")), rb)), "`.\n")); #line 533 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, " Implement with `class Square implements IDrawable ")), lb)), " ... ")), rb)), "`.\n")); #line 534 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- For-in over a collection: `for x in xs ")), lb)), " ... ")), rb)), "`. Range: `for i in 0..n`.\n")); #line 535 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- Public entry point: `public class Program ")), lb)), " public static void Main(string[] args) ")), lb)), " ... ")), rb)), " ")), rb)), "`.\n")); #line 536 "./src/migrate.am" p = (code_string_concat(p, "\n")); #line 537 "./src/migrate.am" p = (code_string_concat(p, "## Idiomatic patterns\n")); #line 538 "./src/migrate.am" p = (code_string_concat(p, "- Prefer immutable `let` over `var`. Loops and accumulators are exceptions.\n")); #line 539 "./src/migrate.am" p = (code_string_concat(p, "- For functional pipelines, use the higher-order list methods, not for-in.\n")); #line 540 "./src/migrate.am" p = (code_string_concat(p, "- For value types, use `data class`. For behavior, regular `class`.\n")); #line 541 "./src/migrate.am" p = (code_string_concat(p, "- One namespace per project area; multiple files can share a namespace.\n")); #line 542 "./src/migrate.am" p = (code_string_concat(p, "\n")); #line 543 "./src/migrate.am" p = (code_string_concat(p, "## Known Amalgame limitations to work around\n")); #line 544 "./src/migrate.am" p = (code_string_concat(p, "- String interpolation does NOT propagate inferred types into embedded\n")); #line 545 "./src/migrate.am" p = (code_string_concat(p, " calls. Workaround: stage in named locals before printing.\n")); #line 546 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, " BAD: Console.WriteLine(\"first: ")), lb)), "users.Map(u => u.Name).Get(0)")), rb)), "\")\n")); #line 547 "./src/migrate.am" p = (code_string_concat(p, " GOOD: let names = users.Map(u => u.Name)\n")); #line 548 "./src/migrate.am" p = (code_string_concat(p, " let first: string = names.Get(0)\n")); #line 549 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, " Console.WriteLine(\"first: ")), lb)), "first")), rb)), "\")\n")); #line 550 "./src/migrate.am" p = (code_string_concat(p, "- Lambda Reduce signatures still need init-arg type inference. If you\n")); #line 551 "./src/migrate.am" p = (code_string_concat(p, " hit issues with .Reduce, fall back to a for-in with `var acc`.\n")); #line 552 "./src/migrate.am" p = (code_string_concat(p, "- ForEach captures by value: `var sum = 0; xs.ForEach(x => sum = sum + x)`\n")); #line 553 "./src/migrate.am" p = (code_string_concat(p, " does NOT accumulate. Use Reduce for accumulation.\n")); #line 557 "./src/migrate.am" code_string extras = Amalgame_Compiler_MigrateCommand_LoadDocsHeader(); #line 558 "./src/migrate.am" if (String_Length(extras) > 0LL) { #line 559 "./src/migrate.am" p = (code_string_concat((code_string_concat(p, "\n")), extras)); } #line 561 "./src/migrate.am" return p; } static code_string Amalgame_Compiler_MigrateCommand_BuildUserPrompt(code_string lang, code_string source) { #line 568 "./src/migrate.am" code_string p = ""; #line 569 "./src/migrate.am" p = (code_string_concat(p, "## Source file to translate\n")); #line 570 "./src/migrate.am" p = (code_string_concat((code_string_concat((code_string_concat(p, "```")), lang)), "\n")); #line 571 "./src/migrate.am" p = (code_string_concat(p, source)); #line 572 "./src/migrate.am" p = (code_string_concat(p, "\n```\n")); #line 573 "./src/migrate.am" p = (code_string_concat(p, "\n")); #line 574 "./src/migrate.am" p = (code_string_concat(p, "## Output instructions\n")); #line 575 "./src/migrate.am" p = (code_string_concat(p, "Reply with ONLY the Amalgame source code. No prose, no markdown\n")); #line 576 "./src/migrate.am" p = (code_string_concat(p, "fences, no preamble like \"Here's the translation:\". Just `.am` content.\n")); #line 577 "./src/migrate.am" p = (code_string_concat(p, "\n")); #line 578 "./src/migrate.am" p = (code_string_concat(p, "If you encounter a construct that has no clean Amalgame equivalent,\n")); #line 579 "./src/migrate.am" p = (code_string_concat(p, "insert a `// TODO[migrate]: ` comment instead of\n")); #line 580 "./src/migrate.am" p = (code_string_concat(p, "best-effort guessing. Examples of such constructs:\n")); #line 581 "./src/migrate.am" p = (code_string_concat(p, " - Python decorators (other than @dataclass which maps to `data class`)\n")); #line 582 "./src/migrate.am" p = (code_string_concat(p, " - JS/TS Promises and async/await (no async runtime in Amalgame yet)\n")); #line 583 "./src/migrate.am" p = (code_string_concat(p, " - Java reflection / annotations\n")); #line 584 "./src/migrate.am" p = (code_string_concat(p, " - Rust lifetimes / ownership / borrowing\n")); #line 585 "./src/migrate.am" p = (code_string_concat(p, " - Go goroutines / channels\n")); #line 586 "./src/migrate.am" p = (code_string_concat(p, " - C++ templates with non-type parameters\n")); #line 587 "./src/migrate.am" p = (code_string_concat(p, " - C macros / preprocessor directives\n")); #line 588 "./src/migrate.am" p = (code_string_concat(p, "Preserve the source's logical structure: same number of functions,\n")); #line 589 "./src/migrate.am" p = (code_string_concat(p, "same class hierarchy, same public surface. The output should compile\n")); #line 590 "./src/migrate.am" p = (code_string_concat(p, "with `amc --check` modulo the TODO[migrate] markers.\n")); #line 591 "./src/migrate.am" return p; } code_string Amalgame_Compiler_MigrateCommand_LoadDocsHeader() { #line 604 "./src/migrate.am" AmalgameList* candidates = AmalgameList_new(); #line 605 "./src/migrate.am" code_string execPath = Args_Get(0LL); #line 606 "./src/migrate.am" code_string execDir = Path_GetDirectory(execPath); #line 613 "./src/migrate.am" if (String_Length(execDir) > 0LL) { #line 614 "./src/migrate.am" AmalgameList_add(candidates, (void*)(intptr_t)(code_string_concat(execDir, "/../share/amalgame"))); #line 615 "./src/migrate.am" AmalgameList_add(candidates, (void*)(intptr_t)(execDir)); } #line 617 "./src/migrate.am" AmalgameList_add(candidates, (void*)(intptr_t)(".")); #line 618 "./src/migrate.am" i64 cn = AmalgameList_count(candidates); #line 619 "./src/migrate.am" for (i64 i = 0LL; i < cn; i++) { #line 620 "./src/migrate.am" code_string base = (code_string)AmalgameList_get(candidates, i); #line 621 "./src/migrate.am" code_string grammarPath = code_string_concat(base, "/docs/language/grammar.ebnf"); #line 622 "./src/migrate.am" code_string tourPath = code_string_concat(base, "/docs/guide/02-language-tour.md"); #line 623 "./src/migrate.am" if (File_Exists(grammarPath) && File_Exists(tourPath)) { #line 624 "./src/migrate.am" code_string g = File_ReadAll(grammarPath); #line 625 "./src/migrate.am" code_string t = File_ReadAll(tourPath); #line 626 "./src/migrate.am" code_string out = ""; #line 627 "./src/migrate.am" out = (code_string_concat(out, "\n## Amalgame grammar (EBNF)\n\n")); #line 628 "./src/migrate.am" out = (code_string_concat(out, g)); #line 629 "./src/migrate.am" out = (code_string_concat(out, "\n\n## Amalgame language tour (excerpts)\n\n")); #line 630 "./src/migrate.am" out = (code_string_concat(out, t)); #line 631 "./src/migrate.am" return out; } } #line 634 "./src/migrate.am" return ""; } static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallProvider(code_string provider, code_string model, code_string lang, code_string source) { #line 644 "./src/migrate.am" code_string sys = Amalgame_Compiler_MigrateCommand_BuildSystemPrompt(lang); #line 645 "./src/migrate.am" code_string usr = Amalgame_Compiler_MigrateCommand_BuildUserPrompt(lang, source); #line 646 "./src/migrate.am" return Amalgame_Compiler_MigrateCommand_CallProviderRaw(provider, model, sys, usr); } Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallProviderRaw(code_string provider, code_string model, code_string systemPrompt, code_string userPrompt) { #line 656 "./src/migrate.am" if (code_string_equals(provider, "claude")) { #line 657 "./src/migrate.am" return Amalgame_Compiler_MigrateCommand_CallClaudeCli(model, code_string_concat((code_string_concat(systemPrompt, "\n\n")), userPrompt)); } #line 659 "./src/migrate.am" if (code_string_equals(provider, "claude-api")) { #line 660 "./src/migrate.am" return Amalgame_Compiler_MigrateCommand_CallClaudeApiRaw(model, systemPrompt, userPrompt); } #line 662 "./src/migrate.am" if (code_string_equals(provider, "chatgpt")) { #line 663 "./src/migrate.am" return Amalgame_Compiler_MigrateCommand_CallChatGptApi(model, systemPrompt, userPrompt); } #line 665 "./src/migrate.am" if (code_string_equals(provider, "gemini")) { #line 666 "./src/migrate.am" return Amalgame_Compiler_MigrateCommand_CallGeminiApi(model, systemPrompt, userPrompt); } #line 668 "./src/migrate.am" if (code_string_equals(provider, "custom")) { #line 669 "./src/migrate.am" return Amalgame_Compiler_MigrateCommand_CallCustomScript(systemPrompt, userPrompt); } #line 671 "./src/migrate.am" Amalgame_Compiler_MigrateResult* res = Amalgame_Compiler_MigrateResult_new(); #line 672 "./src/migrate.am" res->Ok = 0; #line 673 "./src/migrate.am" res->Error = (code_string_concat((code_string_concat("provider '", provider)), "' not supported (built-in: claude, claude-api, chatgpt, gemini, custom)")); #line 674 "./src/migrate.am" return res; } code_string Amalgame_Compiler_MigrateCommand_AutoSelectProvider() { #line 685 "./src/migrate.am" if (Env_Has("ANTHROPIC_API_KEY")) { return "claude-api"; } #line 686 "./src/migrate.am" if (Env_Has("OPENAI_API_KEY")) { return "chatgpt"; } #line 687 "./src/migrate.am" if (Env_Has("GEMINI_API_KEY")) { return "gemini"; } #line 688 "./src/migrate.am" return "claude"; } code_string Amalgame_Compiler_MigrateCommand_EstimateCost(code_string provider, code_string model, code_string systemPrompt, code_string userPrompt) { #line 711 "./src/migrate.am" if (code_string_equals(provider, "claude")) { return "free (subscription via Claude Code CLI)"; } #line 712 "./src/migrate.am" if (code_string_equals(provider, "custom")) { return "free (user-managed local backend)"; } #line 717 "./src/migrate.am" i64 sysLen = String_Length(systemPrompt); #line 718 "./src/migrate.am" i64 usrLen = String_Length(userPrompt); #line 719 "./src/migrate.am" i64 totalChars = sysLen + usrLen; #line 720 "./src/migrate.am" i64 inputToks = totalChars / 4LL; #line 721 "./src/migrate.am" i64 outputToks = 1000LL; #line 725 "./src/migrate.am" i64 inUsdPerM = 0LL; #line 726 "./src/migrate.am" i64 outUsdPerM = 0LL; #line 727 "./src/migrate.am" code_string resolvedModel = model; #line 728 "./src/migrate.am" if (code_string_equals(provider, "claude-api")) { #line 729 "./src/migrate.am" if (String_Length(resolvedModel) == 0LL) { resolvedModel = "claude-sonnet-4-6"; } #line 730 "./src/migrate.am" if (code_string_equals(resolvedModel, "claude-opus-4-7")) { #line 731 "./src/migrate.am" inUsdPerM = 15000000LL; #line 732 "./src/migrate.am" outUsdPerM = 75000000LL; } else if (code_string_equals(resolvedModel, "claude-haiku-4-5")) { #line 734 "./src/migrate.am" inUsdPerM = 1000000LL; #line 735 "./src/migrate.am" outUsdPerM = 5000000LL; } else { #line 737 "./src/migrate.am" inUsdPerM = 3000000LL; #line 738 "./src/migrate.am" outUsdPerM = 15000000LL; } } else if (code_string_equals(provider, "chatgpt")) { #line 741 "./src/migrate.am" if (String_Length(resolvedModel) == 0LL) { resolvedModel = "gpt-4o-mini"; } #line 742 "./src/migrate.am" if (code_string_equals(resolvedModel, "gpt-4o")) { #line 743 "./src/migrate.am" inUsdPerM = 2500000LL; #line 744 "./src/migrate.am" outUsdPerM = 10000000LL; } else if (code_string_equals(resolvedModel, "gpt-4-turbo")) { #line 746 "./src/migrate.am" inUsdPerM = 10000000LL; #line 747 "./src/migrate.am" outUsdPerM = 30000000LL; } else { #line 749 "./src/migrate.am" inUsdPerM = 150000LL; #line 750 "./src/migrate.am" outUsdPerM = 600000LL; } } else if (code_string_equals(provider, "gemini")) { #line 753 "./src/migrate.am" if (String_Length(resolvedModel) == 0LL) { resolvedModel = "gemini-1.5-flash"; } #line 754 "./src/migrate.am" if (code_string_equals(resolvedModel, "gemini-1.5-pro")) { #line 755 "./src/migrate.am" inUsdPerM = 1250000LL; #line 756 "./src/migrate.am" outUsdPerM = 5000000LL; } else { #line 758 "./src/migrate.am" inUsdPerM = 75000LL; #line 759 "./src/migrate.am" outUsdPerM = 300000LL; } } #line 764 "./src/migrate.am" i64 inProd = inputToks * inUsdPerM; #line 765 "./src/migrate.am" i64 inMicro = inProd / 1000000LL; #line 766 "./src/migrate.am" i64 outProd = outputToks * outUsdPerM; #line 767 "./src/migrate.am" i64 outMicro = outProd / 1000000LL; #line 768 "./src/migrate.am" i64 totalMicro = inMicro + outMicro; #line 770 "./src/migrate.am" i64 totalCents = totalMicro / 10000LL; #line 771 "./src/migrate.am" i64 dollars = totalCents / 100LL; #line 772 "./src/migrate.am" i64 cents = totalCents % 100LL; #line 773 "./src/migrate.am" code_string centStr = String_FromInt(cents); #line 774 "./src/migrate.am" if (cents < 10LL) { centStr = (code_string_concat("0", centStr)); } #line 775 "./src/migrate.am" code_string inS = String_FromInt(inputToks); #line 776 "./src/migrate.am" code_string outS = String_FromInt(outputToks); #line 777 "./src/migrate.am" code_string dolS = String_FromInt(dollars); #line 778 "./src/migrate.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("~", inS)), " in + ~")), outS)), " out -> ~$")), dolS)), ".")), centStr)), " (")), resolvedModel)), ")"); } code_string Amalgame_Compiler_MigrateCommand_FormatActualCost(code_string provider, code_string model, i64 inputToks, i64 outputToks) { #line 786 "./src/migrate.am" if ((inputToks < 0LL) || (outputToks < 0LL)) { return ""; } #line 787 "./src/migrate.am" i64 inUsdPerM = 0LL; #line 788 "./src/migrate.am" i64 outUsdPerM = 0LL; #line 789 "./src/migrate.am" code_string resolvedModel = model; #line 790 "./src/migrate.am" if (code_string_equals(provider, "claude-api")) { #line 791 "./src/migrate.am" if (String_Length(resolvedModel) == 0LL) { resolvedModel = "claude-sonnet-4-6"; } #line 792 "./src/migrate.am" if (code_string_equals(resolvedModel, "claude-opus-4-7")) { #line 793 "./src/migrate.am" inUsdPerM = 15000000LL; #line 794 "./src/migrate.am" outUsdPerM = 75000000LL; } else if (code_string_equals(resolvedModel, "claude-haiku-4-5")) { #line 796 "./src/migrate.am" inUsdPerM = 1000000LL; #line 797 "./src/migrate.am" outUsdPerM = 5000000LL; } else { #line 799 "./src/migrate.am" inUsdPerM = 3000000LL; #line 800 "./src/migrate.am" outUsdPerM = 15000000LL; } } else if (code_string_equals(provider, "chatgpt")) { #line 803 "./src/migrate.am" if (String_Length(resolvedModel) == 0LL) { resolvedModel = "gpt-4o-mini"; } #line 804 "./src/migrate.am" if (code_string_equals(resolvedModel, "gpt-4o")) { #line 805 "./src/migrate.am" inUsdPerM = 2500000LL; #line 806 "./src/migrate.am" outUsdPerM = 10000000LL; } else if (code_string_equals(resolvedModel, "gpt-4-turbo")) { #line 808 "./src/migrate.am" inUsdPerM = 10000000LL; #line 809 "./src/migrate.am" outUsdPerM = 30000000LL; } else { #line 811 "./src/migrate.am" inUsdPerM = 150000LL; #line 812 "./src/migrate.am" outUsdPerM = 600000LL; } } else if (code_string_equals(provider, "gemini")) { #line 815 "./src/migrate.am" if (String_Length(resolvedModel) == 0LL) { resolvedModel = "gemini-1.5-flash"; } #line 816 "./src/migrate.am" if (code_string_equals(resolvedModel, "gemini-1.5-pro")) { #line 817 "./src/migrate.am" inUsdPerM = 1250000LL; #line 818 "./src/migrate.am" outUsdPerM = 5000000LL; } else { #line 820 "./src/migrate.am" inUsdPerM = 75000LL; #line 821 "./src/migrate.am" outUsdPerM = 300000LL; } } else { #line 824 "./src/migrate.am" return ""; } #line 826 "./src/migrate.am" i64 inProd = inputToks * inUsdPerM; #line 827 "./src/migrate.am" i64 inMicro = inProd / 1000000LL; #line 828 "./src/migrate.am" i64 outProd = outputToks * outUsdPerM; #line 829 "./src/migrate.am" i64 outMicro = outProd / 1000000LL; #line 830 "./src/migrate.am" i64 totalMicro = inMicro + outMicro; #line 831 "./src/migrate.am" i64 totalCents = totalMicro / 10000LL; #line 832 "./src/migrate.am" i64 dollars = totalCents / 100LL; #line 833 "./src/migrate.am" i64 cents = totalCents % 100LL; #line 834 "./src/migrate.am" code_string centStr = String_FromInt(cents); #line 835 "./src/migrate.am" if (cents < 10LL) { centStr = (code_string_concat("0", centStr)); } #line 836 "./src/migrate.am" code_string inS = String_FromInt(inputToks); #line 837 "./src/migrate.am" code_string outS = String_FromInt(outputToks); #line 838 "./src/migrate.am" code_string dolS = String_FromInt(dollars); #line 839 "./src/migrate.am" return code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(inS, " in + ")), outS)), " out = $")), dolS)), ".")), centStr)), " (")), resolvedModel)), ")"); } static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallClaudeApiRaw(code_string model, code_string systemPrompt, code_string userPrompt) { #line 856 "./src/migrate.am" Amalgame_Compiler_MigrateResult* res = Amalgame_Compiler_MigrateResult_new(); #line 857 "./src/migrate.am" code_string apiKey = Env_Get("ANTHROPIC_API_KEY"); #line 858 "./src/migrate.am" if (String_Length(apiKey) == 0LL) { #line 859 "./src/migrate.am" res->Ok = 0; #line 860 "./src/migrate.am" res->Error = "claude-api: ANTHROPIC_API_KEY not set. Export it or use --provider claude (CLI shell out)."; #line 861 "./src/migrate.am" return res; } #line 863 "./src/migrate.am" code_string modelId = model; #line 864 "./src/migrate.am" if (String_Length(modelId) == 0LL) { #line 865 "./src/migrate.am" modelId = "claude-sonnet-4-6"; } #line 871 "./src/migrate.am" code_string body = "{"; #line 872 "./src/migrate.am" body = (code_string_concat((code_string_concat((code_string_concat(body, "\"model\":\"")), modelId)), "\",")); #line 873 "./src/migrate.am" body = (code_string_concat(body, "\"max_tokens\":8192,")); #line 874 "./src/migrate.am" body = (code_string_concat(body, "\"system\":[{\"type\":\"text\",\"text\":\"")); #line 875 "./src/migrate.am" body = (code_string_concat(body, Amalgame_Compiler_Json_EscapeString(systemPrompt))); #line 876 "./src/migrate.am" body = (code_string_concat(body, "\",\"cache_control\":{\"type\":\"ephemeral\"}}],")); #line 877 "./src/migrate.am" body = (code_string_concat(body, "\"messages\":[{\"role\":\"user\",\"content\":\"")); #line 878 "./src/migrate.am" body = (code_string_concat(body, Amalgame_Compiler_Json_EscapeString(userPrompt))); #line 879 "./src/migrate.am" body = (code_string_concat(body, "\"}]}")); #line 881 "./src/migrate.am" AmalgameMap* headers = AmalgameMap_new(); #line 882 "./src/migrate.am" AmalgameMap_set(headers, "x-api-key", (void*)(intptr_t)(apiKey)); #line 883 "./src/migrate.am" AmalgameMap_set(headers, "anthropic-version", (void*)(intptr_t)("2023-06-01")); #line 884 "./src/migrate.am" AmalgameMap_set(headers, "Content-Type", (void*)(intptr_t)("application/json")); #line 886 "./src/migrate.am" Amalgame_Compiler_CurlResponse* resp = Amalgame_Compiler_MigrateCommand_CurlPost("https://api.anthropic.com/v1/messages", body, headers); #line 887 "./src/migrate.am" if (String_Length(resp->Error) > 0LL) { #line 888 "./src/migrate.am" res->Ok = 0; res->Error = (code_string_concat("claude-api: ", resp->Error)); return res; } #line 890 "./src/migrate.am" i64 status = resp->Status; #line 891 "./src/migrate.am" if (status != 200LL) { #line 892 "./src/migrate.am" res->Ok = 0; #line 893 "./src/migrate.am" res->Error = (code_string_concat((code_string_concat((code_string_concat("claude-api: HTTP ", String_FromInt(status))), ". Response:\n")), resp->Body)); #line 894 "./src/migrate.am" return res; } #line 897 "./src/migrate.am" Amalgame_Compiler_JsonResult* parsed = Amalgame_Compiler_Json_Parse(resp->Body); #line 898 "./src/migrate.am" if (!parsed->Ok) { #line 899 "./src/migrate.am" res->Ok = 0; #line 900 "./src/migrate.am" res->Error = (code_string_concat((code_string_concat((code_string_concat("claude-api: unparseable response (", parsed->Error->Message)), "). Raw body:\n")), resp->Body)); #line 901 "./src/migrate.am" return res; } #line 903 "./src/migrate.am" Amalgame_Compiler_JsonValue* root = parsed->Value; #line 904 "./src/migrate.am" code_string text = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(Amalgame_Compiler_JsonValue_At(Amalgame_Compiler_JsonValue_Get(root, "content"), 0LL), "text")); #line 905 "./src/migrate.am" if (String_Length(text) == 0LL) { #line 906 "./src/migrate.am" res->Ok = 0; #line 907 "./src/migrate.am" res->Error = (code_string_concat("claude-api: empty response (no content[0].text). Raw body:\n", resp->Body)); #line 908 "./src/migrate.am" return res; } #line 911 "./src/migrate.am" Amalgame_Compiler_JsonValue* usage = Amalgame_Compiler_JsonValue_Get(root, "usage"); #line 912 "./src/migrate.am" res->InputTokens = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(usage, "input_tokens")); #line 913 "./src/migrate.am" res->OutputTokens = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(usage, "output_tokens")); #line 914 "./src/migrate.am" res->Ok = 1; #line 915 "./src/migrate.am" res->Content = Amalgame_Compiler_MigrateCommand_StripFences(text); #line 916 "./src/migrate.am" return res; } static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallChatGptApi(code_string model, code_string systemPrompt, code_string userPrompt) { #line 925 "./src/migrate.am" Amalgame_Compiler_MigrateResult* res = Amalgame_Compiler_MigrateResult_new(); #line 926 "./src/migrate.am" code_string apiKey = Env_Get("OPENAI_API_KEY"); #line 927 "./src/migrate.am" if (String_Length(apiKey) == 0LL) { #line 928 "./src/migrate.am" res->Ok = 0; #line 929 "./src/migrate.am" res->Error = "chatgpt: OPENAI_API_KEY not set."; #line 930 "./src/migrate.am" return res; } #line 932 "./src/migrate.am" code_string modelId = model; #line 933 "./src/migrate.am" if (String_Length(modelId) == 0LL) { #line 934 "./src/migrate.am" modelId = "gpt-4o-mini"; } #line 936 "./src/migrate.am" code_string body = "{"; #line 937 "./src/migrate.am" body = (code_string_concat((code_string_concat((code_string_concat(body, "\"model\":\"")), modelId)), "\",")); #line 938 "./src/migrate.am" body = (code_string_concat(body, "\"messages\":[{\"role\":\"system\",\"content\":\"")); #line 939 "./src/migrate.am" body = (code_string_concat(body, Amalgame_Compiler_Json_EscapeString(systemPrompt))); #line 940 "./src/migrate.am" body = (code_string_concat(body, "\"},{\"role\":\"user\",\"content\":\"")); #line 941 "./src/migrate.am" body = (code_string_concat(body, Amalgame_Compiler_Json_EscapeString(userPrompt))); #line 942 "./src/migrate.am" body = (code_string_concat(body, "\"}]}")); #line 944 "./src/migrate.am" AmalgameMap* headers = AmalgameMap_new(); #line 945 "./src/migrate.am" AmalgameMap_set(headers, "Authorization", (void*)(intptr_t)(code_string_concat("Bearer ", apiKey))); #line 946 "./src/migrate.am" AmalgameMap_set(headers, "Content-Type", (void*)(intptr_t)("application/json")); #line 948 "./src/migrate.am" Amalgame_Compiler_CurlResponse* resp = Amalgame_Compiler_MigrateCommand_CurlPost("https://api.openai.com/v1/chat/completions", body, headers); #line 949 "./src/migrate.am" if (String_Length(resp->Error) > 0LL) { #line 950 "./src/migrate.am" res->Ok = 0; res->Error = (code_string_concat("chatgpt: ", resp->Error)); return res; } #line 952 "./src/migrate.am" i64 status = resp->Status; #line 953 "./src/migrate.am" if (status != 200LL) { #line 954 "./src/migrate.am" res->Ok = 0; #line 955 "./src/migrate.am" res->Error = (code_string_concat((code_string_concat((code_string_concat("chatgpt: HTTP ", String_FromInt(status))), ". Response:\n")), resp->Body)); #line 956 "./src/migrate.am" return res; } #line 959 "./src/migrate.am" Amalgame_Compiler_JsonResult* parsed = Amalgame_Compiler_Json_Parse(resp->Body); #line 960 "./src/migrate.am" if (!parsed->Ok) { #line 961 "./src/migrate.am" res->Ok = 0; #line 962 "./src/migrate.am" res->Error = (code_string_concat((code_string_concat((code_string_concat("chatgpt: unparseable response (", parsed->Error->Message)), "). Raw:\n")), resp->Body)); #line 963 "./src/migrate.am" return res; } #line 965 "./src/migrate.am" Amalgame_Compiler_JsonValue* root = parsed->Value; #line 966 "./src/migrate.am" code_string text = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(Amalgame_Compiler_JsonValue_Get(Amalgame_Compiler_JsonValue_At(Amalgame_Compiler_JsonValue_Get(root, "choices"), 0LL), "message"), "content")); #line 967 "./src/migrate.am" if (String_Length(text) == 0LL) { #line 968 "./src/migrate.am" res->Ok = 0; #line 969 "./src/migrate.am" res->Error = (code_string_concat("chatgpt: empty response (no choices[0].message.content). Raw:\n", resp->Body)); #line 970 "./src/migrate.am" return res; } #line 973 "./src/migrate.am" Amalgame_Compiler_JsonValue* usage = Amalgame_Compiler_JsonValue_Get(root, "usage"); #line 974 "./src/migrate.am" res->InputTokens = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(usage, "prompt_tokens")); #line 975 "./src/migrate.am" res->OutputTokens = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(usage, "completion_tokens")); #line 976 "./src/migrate.am" res->Ok = 1; #line 977 "./src/migrate.am" res->Content = Amalgame_Compiler_MigrateCommand_StripFences(text); #line 978 "./src/migrate.am" return res; } static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallGeminiApi(code_string model, code_string systemPrompt, code_string userPrompt) { #line 987 "./src/migrate.am" Amalgame_Compiler_MigrateResult* res = Amalgame_Compiler_MigrateResult_new(); #line 988 "./src/migrate.am" code_string apiKey = Env_Get("GEMINI_API_KEY"); #line 989 "./src/migrate.am" if (String_Length(apiKey) == 0LL) { #line 990 "./src/migrate.am" res->Ok = 0; #line 991 "./src/migrate.am" res->Error = "gemini: GEMINI_API_KEY not set."; #line 992 "./src/migrate.am" return res; } #line 994 "./src/migrate.am" code_string modelId = model; #line 995 "./src/migrate.am" if (String_Length(modelId) == 0LL) { #line 996 "./src/migrate.am" modelId = "gemini-1.5-flash"; } #line 1000 "./src/migrate.am" code_string body = "{"; #line 1001 "./src/migrate.am" body = (code_string_concat(body, "\"systemInstruction\":{\"parts\":[{\"text\":\"")); #line 1002 "./src/migrate.am" body = (code_string_concat(body, Amalgame_Compiler_Json_EscapeString(systemPrompt))); #line 1003 "./src/migrate.am" body = (code_string_concat(body, "\"}]},")); #line 1004 "./src/migrate.am" body = (code_string_concat(body, "\"contents\":[{\"parts\":[{\"text\":\"")); #line 1005 "./src/migrate.am" body = (code_string_concat(body, Amalgame_Compiler_Json_EscapeString(userPrompt))); #line 1006 "./src/migrate.am" body = (code_string_concat(body, "\"}]}]}")); #line 1008 "./src/migrate.am" AmalgameMap* headers = AmalgameMap_new(); #line 1009 "./src/migrate.am" AmalgameMap_set(headers, "Content-Type", (void*)(intptr_t)("application/json")); #line 1010 "./src/migrate.am" code_string url = code_string_concat((code_string_concat((code_string_concat("https://generativelanguage.googleapis.com/v1beta/models/", modelId)), ":generateContent?key=")), apiKey); #line 1012 "./src/migrate.am" Amalgame_Compiler_CurlResponse* resp = Amalgame_Compiler_MigrateCommand_CurlPost(url, body, headers); #line 1013 "./src/migrate.am" if (String_Length(resp->Error) > 0LL) { #line 1014 "./src/migrate.am" res->Ok = 0; res->Error = (code_string_concat("gemini: ", resp->Error)); return res; } #line 1016 "./src/migrate.am" i64 status = resp->Status; #line 1017 "./src/migrate.am" if (status != 200LL) { #line 1018 "./src/migrate.am" res->Ok = 0; #line 1019 "./src/migrate.am" res->Error = (code_string_concat((code_string_concat((code_string_concat("gemini: HTTP ", String_FromInt(status))), ". Response:\n")), resp->Body)); #line 1020 "./src/migrate.am" return res; } #line 1023 "./src/migrate.am" Amalgame_Compiler_JsonResult* parsed = Amalgame_Compiler_Json_Parse(resp->Body); #line 1024 "./src/migrate.am" if (!parsed->Ok) { #line 1025 "./src/migrate.am" res->Ok = 0; #line 1026 "./src/migrate.am" res->Error = (code_string_concat((code_string_concat((code_string_concat("gemini: unparseable response (", parsed->Error->Message)), "). Raw:\n")), resp->Body)); #line 1027 "./src/migrate.am" return res; } #line 1029 "./src/migrate.am" Amalgame_Compiler_JsonValue* root = parsed->Value; #line 1030 "./src/migrate.am" code_string text = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(Amalgame_Compiler_JsonValue_At(Amalgame_Compiler_JsonValue_Get(Amalgame_Compiler_JsonValue_Get(Amalgame_Compiler_JsonValue_At(Amalgame_Compiler_JsonValue_Get(root, "candidates"), 0LL), "content"), "parts"), 0LL), "text")); #line 1031 "./src/migrate.am" if (String_Length(text) == 0LL) { #line 1032 "./src/migrate.am" res->Ok = 0; #line 1033 "./src/migrate.am" res->Error = (code_string_concat("gemini: empty response (no candidates[0].content.parts[0].text). Raw:\n", resp->Body)); #line 1034 "./src/migrate.am" return res; } #line 1037 "./src/migrate.am" Amalgame_Compiler_JsonValue* usage = Amalgame_Compiler_JsonValue_Get(root, "usageMetadata"); #line 1038 "./src/migrate.am" res->InputTokens = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(usage, "promptTokenCount")); #line 1039 "./src/migrate.am" res->OutputTokens = Amalgame_Compiler_JsonValue_AsInt(Amalgame_Compiler_JsonValue_Get(usage, "candidatesTokenCount")); #line 1040 "./src/migrate.am" res->Ok = 1; #line 1041 "./src/migrate.am" res->Content = Amalgame_Compiler_MigrateCommand_StripFences(text); #line 1042 "./src/migrate.am" return res; } static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallCustomScript(code_string systemPrompt, code_string userPrompt) { #line 1055 "./src/migrate.am" Amalgame_Compiler_MigrateResult* res = Amalgame_Compiler_MigrateResult_new(); #line 1056 "./src/migrate.am" code_string cmd = Env_Get("AMC_CUSTOM_PROVIDER_CMD"); #line 1057 "./src/migrate.am" if (String_Length(cmd) == 0LL) { #line 1058 "./src/migrate.am" res->Ok = 0; #line 1059 "./src/migrate.am" res->Error = "custom: AMC_CUSTOM_PROVIDER_CMD not set. Point it at a script that reads prompt from stdin and writes the response to stdout."; #line 1060 "./src/migrate.am" return res; } #line 1062 "./src/migrate.am" code_string tmpPath = "/tmp/amc_custom_prompt.txt"; #line 1063 "./src/migrate.am" code_string combined = code_string_concat((code_string_concat(systemPrompt, "\n\n")), userPrompt); #line 1064 "./src/migrate.am" code_bool writeOk = File_WriteAll(tmpPath, combined); #line 1065 "./src/migrate.am" if (!writeOk) { #line 1066 "./src/migrate.am" res->Ok = 0; #line 1067 "./src/migrate.am" res->Error = (code_string_concat("custom: failed to write prompt temp file: ", tmpPath)); #line 1068 "./src/migrate.am" return res; } #line 1070 "./src/migrate.am" code_string full = code_string_concat((code_string_concat(cmd, " < ")), tmpPath); #line 1071 "./src/migrate.am" AmalgameProcessResult* rr = Process_RunCapture(full); #line 1072 "./src/migrate.am" if (rr->Exit != 0LL) { #line 1073 "./src/migrate.am" res->Ok = 0; #line 1074 "./src/migrate.am" res->Error = (code_string_concat((code_string_concat((code_string_concat("custom: script exited ", String_FromInt(rr->Exit))), ". Output:\n")), rr->Stdout)); #line 1075 "./src/migrate.am" return res; } #line 1077 "./src/migrate.am" res->Ok = 1; #line 1078 "./src/migrate.am" res->Content = Amalgame_Compiler_MigrateCommand_StripFences(rr->Stdout); #line 1079 "./src/migrate.am" return res; } static Amalgame_Compiler_MigrateResult* Amalgame_Compiler_MigrateCommand_CallClaudeCli(code_string model, code_string prompt) { #line 1090 "./src/migrate.am" Amalgame_Compiler_MigrateResult* res = Amalgame_Compiler_MigrateResult_new(); #line 1091 "./src/migrate.am" if (!Amalgame_Compiler_MigrateCommand_IsCommandAvailable("claude")) { #line 1092 "./src/migrate.am" res->Ok = 0; #line 1093 "./src/migrate.am" res->Error = "claude CLI not found on PATH. Install Claude Code: https://docs.claude.com/claude-code\nOr pick another provider with --provider (none ships in v0 yet)."; #line 1094 "./src/migrate.am" return res; } #line 1096 "./src/migrate.am" code_string tmpPath = "/tmp/amc_migrate_prompt.txt"; #line 1097 "./src/migrate.am" code_bool writeOk = File_WriteAll(tmpPath, prompt); #line 1098 "./src/migrate.am" if (!writeOk) { #line 1099 "./src/migrate.am" res->Ok = 0; #line 1100 "./src/migrate.am" res->Error = (code_string_concat("failed to write prompt temp file: ", tmpPath)); #line 1101 "./src/migrate.am" return res; } #line 1103 "./src/migrate.am" code_string cmd = "claude -p"; #line 1104 "./src/migrate.am" if (String_Length(model) > 0LL) { #line 1105 "./src/migrate.am" cmd = (code_string_concat((code_string_concat(cmd, " --model ")), model)); } #line 1107 "./src/migrate.am" cmd = (code_string_concat((code_string_concat(cmd, " < ")), tmpPath)); #line 1108 "./src/migrate.am" AmalgameProcessResult* rr = Process_RunCapture(cmd); #line 1109 "./src/migrate.am" if (rr->Exit != 0LL) { #line 1110 "./src/migrate.am" res->Ok = 0; #line 1111 "./src/migrate.am" res->Error = (code_string_concat((code_string_concat((code_string_concat("claude CLI failed (exit ", String_FromInt(rr->Exit))), "). Output:\n")), rr->Stdout)); #line 1112 "./src/migrate.am" return res; } #line 1116 "./src/migrate.am" res->Ok = 1; #line 1117 "./src/migrate.am" res->Content = Amalgame_Compiler_MigrateCommand_StripFences(rr->Stdout); #line 1118 "./src/migrate.am" return res; } static code_bool Amalgame_Compiler_MigrateCommand_IsCommandAvailable(code_string cmd) { #line 1124 "./src/migrate.am" code_string probe = code_string_concat((code_string_concat("command -v ", cmd)), " >/dev/null 2>&1"); #line 1125 "./src/migrate.am" AmalgameProcessResult* rr = Process_RunCapture(probe); #line 1126 "./src/migrate.am" return rr->Exit == 0LL; } code_string Amalgame_Compiler_MigrateCommand_CacheHash(code_string source, code_string systemPrompt) { #line 1146 "./src/migrate.am" code_string tmpPath = "/tmp/amc_cache_input.txt"; #line 1147 "./src/migrate.am" code_string combined = code_string_concat((code_string_concat(source, "\n---SYSTEM---\n")), systemPrompt); #line 1148 "./src/migrate.am" code_bool writeOk = File_WriteAll(tmpPath, combined); #line 1149 "./src/migrate.am" if (!writeOk) { return ""; } #line 1150 "./src/migrate.am" AmalgameProcessResult* result = Process_RunCapture(code_string_concat((code_string_concat("sha256sum ", tmpPath)), " 2>/dev/null")); #line 1151 "./src/migrate.am" if (result->Exit != 0LL) { return ""; } #line 1152 "./src/migrate.am" code_string out = String_Trim(result->Stdout); #line 1153 "./src/migrate.am" if (String_Length(out) < 64LL) { return ""; } #line 1154 "./src/migrate.am" return String_Substring(out, 0LL, 64LL); } code_string Amalgame_Compiler_MigrateCommand_CachePath(code_string hash) { #line 1160 "./src/migrate.am" code_string home = Env_Get("HOME"); #line 1161 "./src/migrate.am" if (String_Length(home) == 0LL) { return ""; } #line 1162 "./src/migrate.am" code_string dir = code_string_concat(home, "/.cache/amalgame/migrate"); #line 1163 "./src/migrate.am" Process_RunCapture(code_string_concat("mkdir -p ", dir)); #line 1164 "./src/migrate.am" return code_string_concat((code_string_concat((code_string_concat(dir, "/")), hash)), ".am"); } code_string Amalgame_Compiler_MigrateCommand_CacheLookup(code_string source, code_string systemPrompt) { #line 1171 "./src/migrate.am" code_string hash = Amalgame_Compiler_MigrateCommand_CacheHash(source, systemPrompt); #line 1172 "./src/migrate.am" if (String_Length(hash) == 0LL) { return ""; } #line 1173 "./src/migrate.am" code_string path = Amalgame_Compiler_MigrateCommand_CachePath(hash); #line 1174 "./src/migrate.am" if (String_Length(path) == 0LL) { return ""; } #line 1175 "./src/migrate.am" if (!File_Exists(path)) { return ""; } #line 1176 "./src/migrate.am" return File_ReadAll(path); } void Amalgame_Compiler_MigrateCommand_CacheStore(code_string source, code_string systemPrompt, code_string content) { #line 1183 "./src/migrate.am" code_string hash = Amalgame_Compiler_MigrateCommand_CacheHash(source, systemPrompt); #line 1184 "./src/migrate.am" if (String_Length(hash) == 0LL) { return; } #line 1185 "./src/migrate.am" code_string path = Amalgame_Compiler_MigrateCommand_CachePath(hash); #line 1186 "./src/migrate.am" if (String_Length(path) == 0LL) { return; } #line 1187 "./src/migrate.am" File_WriteAll(path, content); } i64 Amalgame_Compiler_MigrateCommand_StreamClaudeCli(code_string model, code_string prompt) { #line 1198 "./src/migrate.am" if (!Amalgame_Compiler_MigrateCommand_IsCommandAvailable("claude")) { #line 1199 "./src/migrate.am" Console_WriteError("claude CLI not found on PATH. Install Claude Code: https://docs.claude.com/claude-code"); #line 1200 "./src/migrate.am" return 1LL; } #line 1202 "./src/migrate.am" code_string tmpPath = "/tmp/amc_stream_prompt.txt"; #line 1203 "./src/migrate.am" code_bool writeOk = File_WriteAll(tmpPath, prompt); #line 1204 "./src/migrate.am" if (!writeOk) { #line 1205 "./src/migrate.am" Console_WriteError(code_string_concat("failed to write prompt temp file: ", tmpPath)); #line 1206 "./src/migrate.am" return 1LL; } #line 1208 "./src/migrate.am" code_string cmd = "claude -p"; #line 1209 "./src/migrate.am" if (String_Length(model) > 0LL) { #line 1210 "./src/migrate.am" cmd = (code_string_concat((code_string_concat(cmd, " --model ")), model)); } #line 1212 "./src/migrate.am" cmd = (code_string_concat((code_string_concat(cmd, " < ")), tmpPath)); #line 1213 "./src/migrate.am" return Process_Run(cmd); } static Amalgame_Compiler_CurlResponse* Amalgame_Compiler_MigrateCommand_CurlPost(code_string url, code_string body, AmalgameMap* headers) { #line 1226 "./src/migrate.am" Amalgame_Compiler_CurlResponse* resp = Amalgame_Compiler_CurlResponse_new(); #line 1233 "./src/migrate.am" code_string openBrace = String_FromByte(123LL); #line 1234 "./src/migrate.am" code_string closeBrace = String_FromByte(125LL); #line 1235 "./src/migrate.am" code_string cmd = code_string_concat((code_string_concat((code_string_concat((code_string_concat("curl -sS -X POST -w '\\n__AMC_STATUS__:%", openBrace)), "http_code")), closeBrace)), "'"); #line 1237 "./src/migrate.am" AmalgameList* keys = AmalgameMap_keys(headers); #line 1238 "./src/migrate.am" i64 kn = AmalgameList_count(keys); #line 1239 "./src/migrate.am" for (i64 i = 0LL; i < kn; i++) { #line 1240 "./src/migrate.am" code_string k = (code_string)AmalgameList_get(keys, i); #line 1241 "./src/migrate.am" code_string v = (code_string)AmalgameMap_get(headers, k); #line 1242 "./src/migrate.am" cmd = (code_string_concat((code_string_concat(cmd, " -H ")), Amalgame_Compiler_MigrateCommand_ShellEscape(code_string_concat((code_string_concat(k, ": ")), v)))); } #line 1250 "./src/migrate.am" AmalgameProcessResult* mk = Process_RunCapture("mktemp /tmp/amc-migrate-body-XXXXXX.json"); #line 1251 "./src/migrate.am" if (mk->Exit != 0LL) { #line 1252 "./src/migrate.am" resp->Error = (code_string_concat((code_string_concat("curl: mktemp failed (", String_FromInt(mk->Exit))), ")")); #line 1253 "./src/migrate.am" return resp; } #line 1255 "./src/migrate.am" code_string bodyPath = String_Trim(mk->Stdout); #line 1256 "./src/migrate.am" if (!File_WriteAll(bodyPath, body)) { #line 1257 "./src/migrate.am" resp->Error = (code_string_concat("curl: failed to write body to ", bodyPath)); #line 1258 "./src/migrate.am" return resp; } #line 1260 "./src/migrate.am" cmd = (code_string_concat((code_string_concat(cmd, " --data-binary @")), bodyPath)); #line 1261 "./src/migrate.am" cmd = (code_string_concat((code_string_concat(cmd, " ")), Amalgame_Compiler_MigrateCommand_ShellEscape(url))); #line 1263 "./src/migrate.am" AmalgameProcessResult* res = Process_RunCapture(cmd); #line 1264 "./src/migrate.am" File_Delete(bodyPath); #line 1266 "./src/migrate.am" if (res->Exit != 0LL) { #line 1267 "./src/migrate.am" resp->Error = (code_string_concat((code_string_concat((code_string_concat("curl exit ", String_FromInt(res->Exit))), ": ")), res->Stderr)); #line 1268 "./src/migrate.am" return resp; } #line 1273 "./src/migrate.am" code_string raw = res->Stdout; #line 1274 "./src/migrate.am" code_string marker = "\n__AMC_STATUS__:"; #line 1275 "./src/migrate.am" i64 idx = String_LastIndexOf(raw, marker); #line 1276 "./src/migrate.am" if (idx < 0LL) { #line 1277 "./src/migrate.am" resp->Error = "curl: missing status marker in output"; #line 1278 "./src/migrate.am" resp->Body = raw; #line 1279 "./src/migrate.am" return resp; } #line 1281 "./src/migrate.am" resp->Body = String_Substring(raw, 0LL, idx); #line 1282 "./src/migrate.am" code_string statStr = String_Substring(raw, idx + String_Length(marker), (String_Length(raw) - idx) - String_Length(marker)); #line 1284 "./src/migrate.am" resp->Status = String_ToInt(String_Trim(statStr)); #line 1285 "./src/migrate.am" resp->Ok = ((resp->Status >= 200LL) && (resp->Status < 300LL)); #line 1286 "./src/migrate.am" return resp; } static code_string Amalgame_Compiler_MigrateCommand_ShellEscape(code_string s) { #line 1293 "./src/migrate.am" code_string escaped = String_Replace(s, "'", "'\\''"); #line 1294 "./src/migrate.am" return code_string_concat((code_string_concat("'", escaped)), "'"); } static code_string Amalgame_Compiler_MigrateCommand_StripFences(code_string s) { #line 1300 "./src/migrate.am" code_string trimmed = String_Trim(s); #line 1301 "./src/migrate.am" if (!String_StartsWith(trimmed, "```")) { return s; } #line 1302 "./src/migrate.am" i64 nl = String_IndexOf(trimmed, "\n"); #line 1303 "./src/migrate.am" if (nl <= 0LL) { return s; } #line 1304 "./src/migrate.am" code_string afterFirst = String_Substring(trimmed, nl + 1LL, (String_Length(trimmed) - nl) - 1LL); #line 1305 "./src/migrate.am" code_string rtrimmed = String_Trim(afterFirst); #line 1306 "./src/migrate.am" if (!String_EndsWith(rtrimmed, "```")) { return s; } #line 1307 "./src/migrate.am" return String_Substring(rtrimmed, 0LL, String_Length(rtrimmed) - 3LL); } struct _Amalgame_Compiler_GenerateCommand { }; void Amalgame_Compiler_GenerateCommand_PrintUsage(); i64 Amalgame_Compiler_GenerateCommand_Run(i64 argc); static code_string Amalgame_Compiler_GenerateCommand_BuildSystemPrompt(); static code_string Amalgame_Compiler_GenerateCommand_BuildUserPrompt(code_string task); static code_string Amalgame_Compiler_GenerateCommand_StripFences(code_string s); Amalgame_Compiler_GenerateCommand* Amalgame_Compiler_GenerateCommand_new() { Amalgame_Compiler_GenerateCommand* self = (Amalgame_Compiler_GenerateCommand*) GC_MALLOC(sizeof(Amalgame_Compiler_GenerateCommand)); return self; } void Amalgame_Compiler_GenerateCommand_PrintUsage() { #line 30 "./src/generate.am" Console_WriteError("Usage: amc generate \"\" [flags]"); #line 31 "./src/generate.am" Console_WriteError(""); #line 32 "./src/generate.am" Console_WriteError("Generates an Amalgame program from a prompt via an LLM."); #line 33 "./src/generate.am" Console_WriteError("Default output is stdout; use -o to write to a file."); #line 34 "./src/generate.am" Console_WriteError(""); #line 35 "./src/generate.am" Console_WriteError("Flags:"); #line 36 "./src/generate.am" Console_WriteError(" -o, --output Write to instead of stdout."); #line 37 "./src/generate.am" Console_WriteError(" --provider LLM provider. Built-in: claude (CLI), claude-api,"); #line 38 "./src/generate.am" Console_WriteError(" chatgpt, gemini, custom. Auto-selects API by env:"); #line 39 "./src/generate.am" Console_WriteError(" ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY,"); #line 40 "./src/generate.am" Console_WriteError(" fallback claude (CLI)."); #line 41 "./src/generate.am" Console_WriteError(" --model Pass a specific model id to the provider."); #line 42 "./src/generate.am" Console_WriteError(" --no-check Skip the `amc --check` validation when -o is given."); #line 43 "./src/generate.am" Console_WriteError(" --force Overwrite an existing file at the -o path."); #line 44 "./src/generate.am" Console_WriteError(" --dry-run Print what would happen without invoking the LLM."); #line 45 "./src/generate.am" Console_WriteError(" --prompt-only Dump the assembled prompt to stdout and exit."); #line 46 "./src/generate.am" Console_WriteError(" --stream Stream the LLM response straight to stdout as it's"); #line 47 "./src/generate.am" Console_WriteError(" produced. Requires --provider claude (CLI), no -o."); #line 48 "./src/generate.am" Console_WriteError(" -h, --help Print this help and exit."); #line 49 "./src/generate.am" Console_WriteError(""); #line 50 "./src/generate.am" Console_WriteError("Examples:"); #line 51 "./src/generate.am" Console_WriteError(" amc generate \"a HTTP server with /health and /version routes\""); #line 52 "./src/generate.am" Console_WriteError(" amc generate \"sieve of Eratosthenes up to N\" -o sieve.am"); } i64 Amalgame_Compiler_GenerateCommand_Run(i64 argc) { #line 57 "./src/generate.am" code_string prompt = ""; #line 58 "./src/generate.am" code_string output = ""; #line 59 "./src/generate.am" code_string provider = ""; #line 60 "./src/generate.am" code_bool providerSet = 0; #line 61 "./src/generate.am" code_string model = ""; #line 62 "./src/generate.am" code_bool dryRun = 0; #line 63 "./src/generate.am" code_bool promptOnly = 0; #line 64 "./src/generate.am" code_bool noCheck = 0; #line 65 "./src/generate.am" code_bool force = 0; #line 66 "./src/generate.am" code_bool stream = 0; #line 69 "./src/generate.am" i64 i = 2LL; #line 70 "./src/generate.am" while (i < argc) { #line 71 "./src/generate.am" code_string a = Args_Get(i); #line 72 "./src/generate.am" if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) { #line 73 "./src/generate.am" Amalgame_Compiler_GenerateCommand_PrintUsage(); #line 74 "./src/generate.am" return 0LL; } else if ((code_string_equals(a, "-o")) || (code_string_equals(a, "--output"))) { #line 76 "./src/generate.am" i = (i + 1LL); #line 77 "./src/generate.am" if (i >= argc) { #line 78 "./src/generate.am" Console_WriteError(code_string_concat((code_string_concat("amc generate: ", a)), " requires a value")); #line 79 "./src/generate.am" return 1LL; } #line 81 "./src/generate.am" output = Args_Get(i); } else if (code_string_equals(a, "--dry-run")) { #line 83 "./src/generate.am" dryRun = 1; } else if (code_string_equals(a, "--prompt-only")) { #line 85 "./src/generate.am" promptOnly = 1; } else if (code_string_equals(a, "--no-check")) { #line 87 "./src/generate.am" noCheck = 1; } else if (code_string_equals(a, "--force")) { #line 89 "./src/generate.am" force = 1; } else if (code_string_equals(a, "--stream")) { #line 91 "./src/generate.am" stream = 1; } else if (code_string_equals(a, "--provider")) { #line 93 "./src/generate.am" i = (i + 1LL); #line 94 "./src/generate.am" if (i >= argc) { #line 95 "./src/generate.am" Console_WriteError("amc generate: --provider requires a value"); #line 96 "./src/generate.am" return 1LL; } #line 98 "./src/generate.am" provider = Args_Get(i); #line 99 "./src/generate.am" providerSet = 1; } else if (code_string_equals(a, "--model")) { #line 101 "./src/generate.am" i = (i + 1LL); #line 102 "./src/generate.am" if (i >= argc) { #line 103 "./src/generate.am" Console_WriteError("amc generate: --model requires a value"); #line 104 "./src/generate.am" return 1LL; } #line 106 "./src/generate.am" model = Args_Get(i); } else if (String_StartsWith(a, "-")) { #line 108 "./src/generate.am" Console_WriteError(code_string_concat((code_string_concat("amc generate: unknown option '", a)), "'")); #line 109 "./src/generate.am" return 1LL; } else { #line 111 "./src/generate.am" if (String_Length(prompt) > 0LL) { #line 112 "./src/generate.am" Console_WriteError("amc generate: too many positional arguments. Quote your prompt: amc generate \"...\""); #line 113 "./src/generate.am" return 1LL; } #line 115 "./src/generate.am" prompt = a; } #line 117 "./src/generate.am" i = (i + 1LL); } #line 120 "./src/generate.am" if (String_Length(prompt) == 0LL) { #line 121 "./src/generate.am" Console_WriteError("amc generate: no prompt given"); #line 122 "./src/generate.am" Console_WriteError("usage: amc generate \"\" [flags]"); #line 123 "./src/generate.am" return 1LL; } #line 127 "./src/generate.am" if (!providerSet) { #line 128 "./src/generate.am" provider = Amalgame_Compiler_MigrateCommand_AutoSelectProvider(); } #line 131 "./src/generate.am" code_string systemPrompt = Amalgame_Compiler_GenerateCommand_BuildSystemPrompt(); #line 132 "./src/generate.am" code_string userPrompt = Amalgame_Compiler_GenerateCommand_BuildUserPrompt(prompt); #line 134 "./src/generate.am" if (promptOnly) { #line 135 "./src/generate.am" Console_WriteLine(systemPrompt); #line 136 "./src/generate.am" Console_WriteLine(""); #line 137 "./src/generate.am" Console_WriteLine(userPrompt); #line 138 "./src/generate.am" return 0LL; } #line 141 "./src/generate.am" if (dryRun) { #line 142 "./src/generate.am" code_string est = Amalgame_Compiler_MigrateCommand_EstimateCost(provider, model, systemPrompt, userPrompt); #line 143 "./src/generate.am" Console_WriteLine(code_string_concat((code_string_concat("[generate] would generate from prompt (", String_FromInt(String_Length(prompt)))), " chars)")); #line 144 "./src/generate.am" if (String_Length(output) > 0LL) { #line 145 "./src/generate.am" Console_WriteLine(code_string_concat("[generate] would write: ", output)); } else { #line 147 "./src/generate.am" Console_WriteLine("[generate] would write: "); } #line 149 "./src/generate.am" Console_WriteLine(code_string_concat("[generate] provider: ", provider)); #line 150 "./src/generate.am" if (String_Length(model) > 0LL) { #line 151 "./src/generate.am" Console_WriteLine(code_string_concat("[generate] model: ", model)); } #line 153 "./src/generate.am" Console_WriteLine(code_string_concat("[generate] estimated cost: ", est)); #line 154 "./src/generate.am" return 0LL; } #line 158 "./src/generate.am" if (((String_Length(output) > 0LL) && File_Exists(output)) && !force) { #line 159 "./src/generate.am" Console_WriteError(code_string_concat("amc generate: output exists: ", output)); #line 160 "./src/generate.am" Console_WriteError("Pass --force to overwrite."); #line 161 "./src/generate.am" return 1LL; } #line 167 "./src/generate.am" if (stream) { #line 168 "./src/generate.am" if (!code_string_equals(provider, "claude")) { #line 169 "./src/generate.am" Console_WriteError("amc generate: --stream requires --provider claude (CLI). API streaming is a v3 follow-up."); #line 170 "./src/generate.am" return 1LL; } #line 172 "./src/generate.am" if (String_Length(output) > 0LL) { #line 173 "./src/generate.am" Console_WriteError("amc generate: --stream is incompatible with -o (no buffered text to write)."); #line 174 "./src/generate.am" return 1LL; } #line 176 "./src/generate.am" Console_WriteError("[generate] streaming via claude CLI..."); #line 177 "./src/generate.am" return Amalgame_Compiler_MigrateCommand_StreamClaudeCli(model, code_string_concat((code_string_concat(systemPrompt, "\n\n")), userPrompt)); } #line 180 "./src/generate.am" Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat("[generate] generating from prompt (", String_FromInt(String_Length(prompt)))), " chars, provider=")), provider)), ")...")); #line 181 "./src/generate.am" Amalgame_Compiler_MigrateResult* result = Amalgame_Compiler_MigrateCommand_CallProviderRaw(provider, model, systemPrompt, userPrompt); #line 182 "./src/generate.am" if (!result->Ok) { #line 183 "./src/generate.am" Console_WriteError(code_string_concat("amc generate: ", result->Error)); #line 184 "./src/generate.am" return 1LL; } #line 188 "./src/generate.am" code_string content = Amalgame_Compiler_GenerateCommand_StripFences(result->Content); #line 192 "./src/generate.am" if (String_Length(output) == 0LL) { #line 193 "./src/generate.am" Console_WriteLine(content); #line 194 "./src/generate.am" return 0LL; } #line 198 "./src/generate.am" code_bool writeOk = File_WriteAll(output, content); #line 199 "./src/generate.am" if (!writeOk) { #line 200 "./src/generate.am" Console_WriteError(code_string_concat("amc generate: failed to write ", output)); #line 201 "./src/generate.am" return 1LL; } #line 203 "./src/generate.am" Console_WriteLine(code_string_concat("[generate] wrote ", output)); #line 205 "./src/generate.am" if (!noCheck) { #line 206 "./src/generate.am" code_string amcPath = Args_Get(0LL); #line 207 "./src/generate.am" code_string cmd = code_string_concat((code_string_concat(amcPath, " --check ")), output); #line 208 "./src/generate.am" AmalgameProcessResult* check = Process_RunCapture(cmd); #line 209 "./src/generate.am" if (check->Exit != 0LL) { #line 210 "./src/generate.am" Console_WriteError("[generate] check failed (typechecker errors in the generated file):"); #line 211 "./src/generate.am" Console_WriteError(check->Stdout); #line 212 "./src/generate.am" Console_WriteError("The .am file was still written so you can inspect / fix manually."); #line 213 "./src/generate.am" return 1LL; } #line 215 "./src/generate.am" Console_WriteLine("[generate] check passed"); } #line 217 "./src/generate.am" return 0LL; } static code_string Amalgame_Compiler_GenerateCommand_BuildSystemPrompt() { #line 226 "./src/generate.am" code_string lb = "{"; #line 227 "./src/generate.am" code_string rb = "}"; #line 228 "./src/generate.am" code_string p = ""; #line 229 "./src/generate.am" p = (code_string_concat(p, "You are writing an Amalgame program from scratch.\n")); #line 230 "./src/generate.am" p = (code_string_concat(p, "Amalgame is a self-hosted programming language that transpiles to C.\n")); #line 231 "./src/generate.am" p = (code_string_concat(p, "It uses class-based OOP with explicit visibility modifiers, generic\n")); #line 232 "./src/generate.am" p = (code_string_concat(p, "collections (List, Map, Set), ML-style match expressions,\n")); #line 233 "./src/generate.am" p = (code_string_concat(p, "exception-based error handling, and higher-order list operations\n")); #line 234 "./src/generate.am" p = (code_string_concat(p, "(.Map / .Filter / .Reduce / .Any / .All / .CountIf).\n")); #line 235 "./src/generate.am" p = (code_string_concat(p, "\n")); #line 236 "./src/generate.am" p = (code_string_concat(p, "## Amalgame conventions\n")); #line 237 "./src/generate.am" p = (code_string_concat(p, "- Files start with `namespace ` then declarations.\n")); #line 238 "./src/generate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- Public entry point: `public class Program ")), lb)), " public static void Main(string[] args) ")), lb)), " ... ")), rb)), " ")), rb)), "`.\n")); #line 239 "./src/generate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- Classes: `public class Name ")), lb)), " public Field: int = 0 ")), rb)), "`.\n")); #line 240 "./src/generate.am" p = (code_string_concat(p, "- Data classes: `public data class User(string Name, int Age)`.\n")); #line 241 "./src/generate.am" p = (code_string_concat(p, "- Locals: `let x = 1` (immutable), `var y = 2` (mutable).\n")); #line 242 "./src/generate.am" p = (code_string_concat(p, "- Lambdas: `(x, y) => x + y` or block form.\n")); #line 243 "./src/generate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- Match: `match x ")), lb)), " 0 => \"zero\", _ => \"other\" ")), rb)), "`.\n")); #line 244 "./src/generate.am" p = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(p, "- Console output: `Console.WriteLine(\"x=")), lb)), "x")), rb)), "\")` (string interpolation).\n")); #line 245 "./src/generate.am" p = (code_string_concat(p, "\n")); #line 247 "./src/generate.am" code_string extras = Amalgame_Compiler_MigrateCommand_LoadDocsHeader(); #line 248 "./src/generate.am" if (String_Length(extras) > 0LL) { #line 249 "./src/generate.am" p = (code_string_concat(p, extras)); } #line 251 "./src/generate.am" return p; } static code_string Amalgame_Compiler_GenerateCommand_BuildUserPrompt(code_string task) { #line 256 "./src/generate.am" code_string p = ""; #line 257 "./src/generate.am" p = (code_string_concat(p, "## Task\n")); #line 258 "./src/generate.am" p = (code_string_concat((code_string_concat(p, task)), "\n")); #line 259 "./src/generate.am" p = (code_string_concat(p, "\n")); #line 260 "./src/generate.am" p = (code_string_concat(p, "## Output instructions\n")); #line 261 "./src/generate.am" p = (code_string_concat(p, "Reply with ONLY the Amalgame source code. No prose, no markdown\n")); #line 262 "./src/generate.am" p = (code_string_concat(p, "fences, no preamble like \"Here's the program:\". Just `.am` content.\n")); #line 263 "./src/generate.am" p = (code_string_concat(p, "The output should compile with `amc --check`.\n")); #line 264 "./src/generate.am" return p; } static code_string Amalgame_Compiler_GenerateCommand_StripFences(code_string s) { #line 270 "./src/generate.am" code_string trimmed = String_Trim(s); #line 271 "./src/generate.am" if (!String_StartsWith(trimmed, "```")) { return s; } #line 272 "./src/generate.am" i64 nl = String_IndexOf(trimmed, "\n"); #line 273 "./src/generate.am" if (nl <= 0LL) { return s; } #line 274 "./src/generate.am" code_string afterFirst = String_Substring(trimmed, nl + 1LL, (String_Length(trimmed) - nl) - 1LL); #line 275 "./src/generate.am" code_string rtrimmed = String_Trim(afterFirst); #line 276 "./src/generate.am" if (!String_EndsWith(rtrimmed, "```")) { return s; } #line 277 "./src/generate.am" return String_Substring(rtrimmed, 0LL, String_Length(rtrimmed) - 3LL); } struct _Amalgame_Compiler_ExplainCommand { }; void Amalgame_Compiler_ExplainCommand_PrintUsage(); i64 Amalgame_Compiler_ExplainCommand_Run(i64 argc); static code_string Amalgame_Compiler_ExplainCommand_BuildSystemPrompt(code_string outLang); static code_string Amalgame_Compiler_ExplainCommand_BuildUserPrompt(code_string path, code_string source); Amalgame_Compiler_ExplainCommand* Amalgame_Compiler_ExplainCommand_new() { Amalgame_Compiler_ExplainCommand* self = (Amalgame_Compiler_ExplainCommand*) GC_MALLOC(sizeof(Amalgame_Compiler_ExplainCommand)); return self; } void Amalgame_Compiler_ExplainCommand_PrintUsage() { #line 23 "./src/explain.am" Console_WriteError("Usage: amc explain [flags]"); #line 24 "./src/explain.am" Console_WriteError(""); #line 25 "./src/explain.am" Console_WriteError("Reads an Amalgame source file and prints a natural-language"); #line 26 "./src/explain.am" Console_WriteError("explanation of what it does. Default output is stdout."); #line 27 "./src/explain.am" Console_WriteError(""); #line 28 "./src/explain.am" Console_WriteError("Flags:"); #line 29 "./src/explain.am" Console_WriteError(" -o, --output Write to instead of stdout."); #line 30 "./src/explain.am" Console_WriteError(" --lang Output language for the explanation."); #line 31 "./src/explain.am" Console_WriteError(" Default: English. Try --lang French, etc."); #line 32 "./src/explain.am" Console_WriteError(" --provider LLM provider. Built-in: claude (CLI), claude-api,"); #line 33 "./src/explain.am" Console_WriteError(" chatgpt, gemini, custom. Auto-selects API by env:"); #line 34 "./src/explain.am" Console_WriteError(" ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY,"); #line 35 "./src/explain.am" Console_WriteError(" fallback claude (CLI)."); #line 36 "./src/explain.am" Console_WriteError(" --model Pass a specific model id to the provider."); #line 37 "./src/explain.am" Console_WriteError(" --force Overwrite an existing file at the -o path."); #line 38 "./src/explain.am" Console_WriteError(" --dry-run Print what would happen without invoking the LLM."); #line 39 "./src/explain.am" Console_WriteError(" --prompt-only Dump the assembled prompt to stdout and exit."); #line 40 "./src/explain.am" Console_WriteError(" --stream Stream the LLM response straight to stdout as it's"); #line 41 "./src/explain.am" Console_WriteError(" produced. Requires --provider claude (CLI), no -o."); #line 42 "./src/explain.am" Console_WriteError(" -h, --help Print this help and exit."); } i64 Amalgame_Compiler_ExplainCommand_Run(i64 argc) { #line 46 "./src/explain.am" code_string input = ""; #line 47 "./src/explain.am" code_string output = ""; #line 48 "./src/explain.am" code_string outLang = "English"; #line 49 "./src/explain.am" code_string provider = ""; #line 50 "./src/explain.am" code_bool providerSet = 0; #line 51 "./src/explain.am" code_string model = ""; #line 52 "./src/explain.am" code_bool dryRun = 0; #line 53 "./src/explain.am" code_bool promptOnly = 0; #line 54 "./src/explain.am" code_bool force = 0; #line 55 "./src/explain.am" code_bool stream = 0; #line 57 "./src/explain.am" i64 i = 2LL; #line 58 "./src/explain.am" while (i < argc) { #line 59 "./src/explain.am" code_string a = Args_Get(i); #line 60 "./src/explain.am" if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) { #line 61 "./src/explain.am" Amalgame_Compiler_ExplainCommand_PrintUsage(); #line 62 "./src/explain.am" return 0LL; } else if ((code_string_equals(a, "-o")) || (code_string_equals(a, "--output"))) { #line 64 "./src/explain.am" i = (i + 1LL); #line 65 "./src/explain.am" if (i >= argc) { #line 66 "./src/explain.am" Console_WriteError(code_string_concat((code_string_concat("amc explain: ", a)), " requires a value")); #line 67 "./src/explain.am" return 1LL; } #line 69 "./src/explain.am" output = Args_Get(i); } else if (code_string_equals(a, "--dry-run")) { #line 71 "./src/explain.am" dryRun = 1; } else if (code_string_equals(a, "--prompt-only")) { #line 73 "./src/explain.am" promptOnly = 1; } else if (code_string_equals(a, "--force")) { #line 75 "./src/explain.am" force = 1; } else if (code_string_equals(a, "--stream")) { #line 77 "./src/explain.am" stream = 1; } else if (code_string_equals(a, "--lang")) { #line 79 "./src/explain.am" i = (i + 1LL); #line 80 "./src/explain.am" if (i >= argc) { #line 81 "./src/explain.am" Console_WriteError("amc explain: --lang requires a value"); #line 82 "./src/explain.am" return 1LL; } #line 84 "./src/explain.am" outLang = Args_Get(i); } else if (code_string_equals(a, "--provider")) { #line 86 "./src/explain.am" i = (i + 1LL); #line 87 "./src/explain.am" if (i >= argc) { #line 88 "./src/explain.am" Console_WriteError("amc explain: --provider requires a value"); #line 89 "./src/explain.am" return 1LL; } #line 91 "./src/explain.am" provider = Args_Get(i); #line 92 "./src/explain.am" providerSet = 1; } else if (code_string_equals(a, "--model")) { #line 94 "./src/explain.am" i = (i + 1LL); #line 95 "./src/explain.am" if (i >= argc) { #line 96 "./src/explain.am" Console_WriteError("amc explain: --model requires a value"); #line 97 "./src/explain.am" return 1LL; } #line 99 "./src/explain.am" model = Args_Get(i); } else if (String_StartsWith(a, "-")) { #line 101 "./src/explain.am" Console_WriteError(code_string_concat((code_string_concat("amc explain: unknown option '", a)), "'")); #line 102 "./src/explain.am" return 1LL; } else { #line 104 "./src/explain.am" if (String_Length(input) > 0LL) { #line 105 "./src/explain.am" Console_WriteError("amc explain: too many positional arguments"); #line 106 "./src/explain.am" return 1LL; } #line 108 "./src/explain.am" input = a; } #line 110 "./src/explain.am" i = (i + 1LL); } #line 113 "./src/explain.am" if (String_Length(input) == 0LL) { #line 114 "./src/explain.am" Console_WriteError("amc explain: no input file"); #line 115 "./src/explain.am" Console_WriteError("usage: amc explain [flags]"); #line 116 "./src/explain.am" return 1LL; } #line 118 "./src/explain.am" if (!File_Exists(input)) { #line 119 "./src/explain.am" Console_WriteError(code_string_concat("amc explain: file not found: ", input)); #line 120 "./src/explain.am" return 1LL; } #line 123 "./src/explain.am" if (!providerSet) { #line 124 "./src/explain.am" provider = Amalgame_Compiler_MigrateCommand_AutoSelectProvider(); } #line 127 "./src/explain.am" code_string source = File_ReadAll(input); #line 128 "./src/explain.am" code_string systemPrompt = Amalgame_Compiler_ExplainCommand_BuildSystemPrompt(outLang); #line 129 "./src/explain.am" code_string userPrompt = Amalgame_Compiler_ExplainCommand_BuildUserPrompt(input, source); #line 131 "./src/explain.am" if (promptOnly) { #line 132 "./src/explain.am" Console_WriteLine(systemPrompt); #line 133 "./src/explain.am" Console_WriteLine(""); #line 134 "./src/explain.am" Console_WriteLine(userPrompt); #line 135 "./src/explain.am" return 0LL; } #line 137 "./src/explain.am" if (dryRun) { #line 138 "./src/explain.am" code_string est = Amalgame_Compiler_MigrateCommand_EstimateCost(provider, model, systemPrompt, userPrompt); #line 139 "./src/explain.am" Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat("[explain] would explain: ", input)), " (")), String_FromInt(String_Length(source)))), " chars)")); #line 140 "./src/explain.am" if (String_Length(output) > 0LL) { #line 141 "./src/explain.am" Console_WriteLine(code_string_concat("[explain] would write: ", output)); } else { #line 143 "./src/explain.am" Console_WriteLine("[explain] would write: "); } #line 145 "./src/explain.am" Console_WriteLine(code_string_concat("[explain] provider: ", provider)); #line 146 "./src/explain.am" Console_WriteLine(code_string_concat("[explain] output lang: ", outLang)); #line 147 "./src/explain.am" Console_WriteLine(code_string_concat("[explain] estimated cost: ", est)); #line 148 "./src/explain.am" return 0LL; } #line 151 "./src/explain.am" if (((String_Length(output) > 0LL) && File_Exists(output)) && !force) { #line 152 "./src/explain.am" Console_WriteError(code_string_concat("amc explain: output exists: ", output)); #line 153 "./src/explain.am" Console_WriteError("Pass --force to overwrite."); #line 154 "./src/explain.am" return 1LL; } #line 158 "./src/explain.am" if (stream) { #line 159 "./src/explain.am" if (!code_string_equals(provider, "claude")) { #line 160 "./src/explain.am" Console_WriteError("amc explain: --stream requires --provider claude (CLI). API streaming is a v3 follow-up."); #line 161 "./src/explain.am" return 1LL; } #line 163 "./src/explain.am" if (String_Length(output) > 0LL) { #line 164 "./src/explain.am" Console_WriteError("amc explain: --stream is incompatible with -o (no buffered text to write)."); #line 165 "./src/explain.am" return 1LL; } #line 167 "./src/explain.am" Console_WriteError("[explain] streaming via claude CLI..."); #line 168 "./src/explain.am" return Amalgame_Compiler_MigrateCommand_StreamClaudeCli(model, code_string_concat((code_string_concat(systemPrompt, "\n\n")), userPrompt)); } #line 171 "./src/explain.am" Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("[explain] explaining ", input)), " (provider=")), provider)), ", lang=")), outLang)), ")...")); #line 172 "./src/explain.am" Amalgame_Compiler_MigrateResult* result = Amalgame_Compiler_MigrateCommand_CallProviderRaw(provider, model, systemPrompt, userPrompt); #line 173 "./src/explain.am" if (!result->Ok) { #line 174 "./src/explain.am" Console_WriteError(code_string_concat("amc explain: ", result->Error)); #line 175 "./src/explain.am" return 1LL; } #line 181 "./src/explain.am" if (String_Length(output) == 0LL) { #line 182 "./src/explain.am" Console_WriteLine(result->Content); #line 183 "./src/explain.am" return 0LL; } #line 185 "./src/explain.am" code_bool writeOk = File_WriteAll(output, result->Content); #line 186 "./src/explain.am" if (!writeOk) { #line 187 "./src/explain.am" Console_WriteError(code_string_concat("amc explain: failed to write ", output)); #line 188 "./src/explain.am" return 1LL; } #line 190 "./src/explain.am" Console_WriteLine(code_string_concat("[explain] wrote ", output)); #line 191 "./src/explain.am" return 0LL; } static code_string Amalgame_Compiler_ExplainCommand_BuildSystemPrompt(code_string outLang) { #line 199 "./src/explain.am" code_string p = ""; #line 200 "./src/explain.am" p = (code_string_concat(p, "You are explaining Amalgame source code to a developer.\n")); #line 201 "./src/explain.am" p = (code_string_concat(p, "Amalgame is a self-hosted programming language that transpiles to C.\n")); #line 202 "./src/explain.am" p = (code_string_concat(p, "It uses class-based OOP, generic collections (List, Map, Set),\n")); #line 203 "./src/explain.am" p = (code_string_concat(p, "ML-style match expressions, exception-based error handling, and\n")); #line 204 "./src/explain.am" p = (code_string_concat(p, "higher-order list operations (.Map / .Filter / .Reduce / .Any / .All).\n")); #line 205 "./src/explain.am" p = (code_string_concat(p, "\n")); #line 206 "./src/explain.am" p = (code_string_concat((code_string_concat((code_string_concat(p, "Write the explanation in ")), outLang)), ".\n")); #line 207 "./src/explain.am" p = (code_string_concat(p, "\n")); #line 209 "./src/explain.am" code_string extras = Amalgame_Compiler_MigrateCommand_LoadDocsHeader(); #line 210 "./src/explain.am" if (String_Length(extras) > 0LL) { #line 211 "./src/explain.am" p = (code_string_concat(p, extras)); } #line 213 "./src/explain.am" return p; } static code_string Amalgame_Compiler_ExplainCommand_BuildUserPrompt(code_string path, code_string source) { #line 218 "./src/explain.am" code_string p = ""; #line 219 "./src/explain.am" p = (code_string_concat((code_string_concat((code_string_concat(p, "## Amalgame source: ")), path)), "\n")); #line 220 "./src/explain.am" p = (code_string_concat(p, "```amalgame\n")); #line 221 "./src/explain.am" p = (code_string_concat(p, source)); #line 222 "./src/explain.am" p = (code_string_concat(p, "\n```\n")); #line 223 "./src/explain.am" p = (code_string_concat(p, "\n")); #line 224 "./src/explain.am" p = (code_string_concat(p, "## What to cover\n")); #line 225 "./src/explain.am" p = (code_string_concat(p, "Explain this code clearly and concisely:\n")); #line 226 "./src/explain.am" p = (code_string_concat(p, " 1. The overall purpose (what problem does it solve?).\n")); #line 227 "./src/explain.am" p = (code_string_concat(p, " 2. The main types and their roles.\n")); #line 228 "./src/explain.am" p = (code_string_concat(p, " 3. The control flow of the entry point.\n")); #line 229 "./src/explain.am" p = (code_string_concat(p, " 4. Anything Amalgame-specific worth highlighting (lambdas,\n")); #line 230 "./src/explain.am" p = (code_string_concat(p, " match expressions, generics) and what they contribute.\n")); #line 231 "./src/explain.am" p = (code_string_concat(p, " 5. Edge cases or limitations the reader should know about.\n")); #line 232 "./src/explain.am" p = (code_string_concat(p, "\n")); #line 233 "./src/explain.am" p = (code_string_concat(p, "Use prose with short headings (Markdown). Quote short snippets\n")); #line 234 "./src/explain.am" p = (code_string_concat(p, "when illustrative. Don't restate the obvious — focus on the\n")); #line 235 "./src/explain.am" p = (code_string_concat(p, "non-trivial decisions in the code.\n")); #line 236 "./src/explain.am" return p; } struct _Amalgame_Compiler_NewCommand { }; void Amalgame_Compiler_NewCommand_PrintUsage(); i64 Amalgame_Compiler_NewCommand_Run(i64 argc); static i64 Amalgame_Compiler_NewCommand_ScaffoldExe(code_string path, code_string base); static i64 Amalgame_Compiler_NewCommand_ScaffoldLib(code_string path, code_string base); static i64 Amalgame_Compiler_NewCommand_ScaffoldService(code_string path, code_string base); static i64 Amalgame_Compiler_NewCommand_ScaffoldForms(code_string path, code_string base); static i64 Amalgame_Compiler_NewCommand_ScaffoldTest(code_string path, code_string base); static i64 Amalgame_Compiler_NewCommand_ScaffoldMcu(code_string path, code_string base, code_string board); static code_string Amalgame_Compiler_NewCommand_McuAppAm(code_string base, code_bool isQemu); static code_string Amalgame_Compiler_NewCommand_McuToml(code_string base, code_string board, code_string target, code_bool isQemu); static code_string Amalgame_Compiler_NewCommand_McuTasksJson(code_string target, code_bool isQemu); static code_string Amalgame_Compiler_NewCommand_McuLaunchJson(code_bool isQemu); static code_string Amalgame_Compiler_NewCommand_McuGitignore(); static code_string Amalgame_Compiler_NewCommand_McuStartupF767(); static code_string Amalgame_Compiler_NewCommand_McuLinkerF767(); static code_string Amalgame_Compiler_NewCommand_McuHeaderF767(); static code_string Amalgame_Compiler_NewCommand_McuReadme(code_string base, code_string board, code_string target, code_bool isQemu); static i64 Amalgame_Compiler_NewCommand_WriteVscodeConfig(code_string path, code_string base, code_string template); static code_string Amalgame_Compiler_NewCommand_VscodeLaunchJson(code_string base); static code_string Amalgame_Compiler_NewCommand_VscodeSettingsJson(); static code_string Amalgame_Compiler_NewCommand_VscodeTasksJson(); static code_string Amalgame_Compiler_NewCommand_MainAmExe(code_string name); static code_string Amalgame_Compiler_NewCommand_TestAmExe(code_string name); static code_string Amalgame_Compiler_NewCommand_BuildShExe(code_string name); static code_string Amalgame_Compiler_NewCommand_ReadmeExe(code_string name); static code_string Amalgame_Compiler_NewCommand_LibAm(code_string name); static code_string Amalgame_Compiler_NewCommand_BuildShLib(code_string name); static code_string Amalgame_Compiler_NewCommand_ReadmeLib(code_string name); static code_string Amalgame_Compiler_NewCommand_TestAmTest(code_string name); static code_string Amalgame_Compiler_NewCommand_ReadmeTest(code_string name); static code_string Amalgame_Compiler_NewCommand_MainAmService(code_string name); static code_string Amalgame_Compiler_NewCommand_ManifestService(code_string name); static code_string Amalgame_Compiler_NewCommand_SystemdUnit(code_string name); static code_string Amalgame_Compiler_NewCommand_InstallShService(code_string name); static code_string Amalgame_Compiler_NewCommand_PlistMacosService(code_string name); static code_string Amalgame_Compiler_NewCommand_InstallMacosShService(code_string name); static code_string Amalgame_Compiler_NewCommand_BuildShService(code_string name); static code_string Amalgame_Compiler_NewCommand_BuildPs1Service(code_string name); static code_string Amalgame_Compiler_NewCommand_InstallPs1Service(code_string name); static code_string Amalgame_Compiler_NewCommand_ReadmeService(code_string name); static code_string Amalgame_Compiler_NewCommand_GitignoreCommon(); static code_string Amalgame_Compiler_NewCommand_GitignoreService(code_string name); static code_bool Amalgame_Compiler_NewCommand_WriteFile(code_string path, code_string content); static code_string Amalgame_Compiler_NewCommand_ShellEscape(code_string s); static code_bool Amalgame_Compiler_NewCommand_IsSafeName(code_string s); static code_string Amalgame_Compiler_NewCommand_Capitalize(code_string s); static code_string Amalgame_Compiler_NewCommand_SanitizeIdent(code_string s); static code_string Amalgame_Compiler_NewCommand_Basename(code_string p); static code_string Amalgame_Compiler_NewCommand_MainAmForms(code_string name); static code_string Amalgame_Compiler_NewCommand_ManifestForms(code_string name); static code_string Amalgame_Compiler_NewCommand_BuildShForms(code_string name); static code_string Amalgame_Compiler_NewCommand_ReadmeForms(code_string name); static i64 Amalgame_Compiler_NewCommand_ScaffoldUiWebForm(code_string path, code_string base); static code_string Amalgame_Compiler_NewCommand_MainAmUiWebForm(code_string name); static code_string Amalgame_Compiler_NewCommand_ManifestUiWebForm(code_string name); static code_string Amalgame_Compiler_NewCommand_BuildShUiWebForm(code_string name); static code_string Amalgame_Compiler_NewCommand_ReadmeUiWebForm(code_string name); Amalgame_Compiler_NewCommand* Amalgame_Compiler_NewCommand_new() { Amalgame_Compiler_NewCommand* self = (Amalgame_Compiler_NewCommand*) GC_MALLOC(sizeof(Amalgame_Compiler_NewCommand)); return self; } void Amalgame_Compiler_NewCommand_PrintUsage() { #line 31 "./src/new_cmd.am" Console_WriteError("Usage: amc new [--template ] [--no-vscode] [--force]"); #line 32 "./src/new_cmd.am" Console_WriteError(""); #line 33 "./src/new_cmd.am" Console_WriteError("Scaffold a new Amalgame project named ."); #line 34 "./src/new_cmd.am" Console_WriteError(""); #line 35 "./src/new_cmd.am" Console_WriteError("Templates:"); #line 36 "./src/new_cmd.am" Console_WriteError(" exe Default. src/main.am with Program.Main + a passing test."); #line 37 "./src/new_cmd.am" Console_WriteError(" lib src/.am with a public class skeleton, no main."); #line 38 "./src/new_cmd.am" Console_WriteError(" test tests/_test.am only — bolt onto an existing project."); #line 39 "./src/new_cmd.am" Console_WriteError(" service Long-running daemon. signal-aware shutdown loop using"); #line 40 "./src/new_cmd.am" Console_WriteError(" Amalgame.Service + Amalgame.Logging, a systemd unit, and"); #line 41 "./src/new_cmd.am" Console_WriteError(" an install.sh wired for /usr/local/bin + systemctl."); #line 42 "./src/new_cmd.am" Console_WriteError(" forms GUI app on top of amalgame-ui-sdl + amalgame-ui-forms."); #line 43 "./src/new_cmd.am" Console_WriteError(" Sunset 2026-05-15 — use ui-web-form for new projects."); #line 44 "./src/new_cmd.am" Console_WriteError(" ui-web-form Webview GUI app on top of amalgame-ui-web. HTML/CSS UI"); #line 45 "./src/new_cmd.am" Console_WriteError(" rendered by the OS webview (WebView2 / WKWebView /"); #line 46 "./src/new_cmd.am" Console_WriteError(" WebKitGTK). Requires libwebkit2gtk-4.1-dev on Linux"); #line 47 "./src/new_cmd.am" Console_WriteError(" (macOS / Windows 11 ship the engine with the OS)."); #line 48 "./src/new_cmd.am" Console_WriteError(""); #line 49 "./src/new_cmd.am" Console_WriteError("Flags:"); #line 50 "./src/new_cmd.am" Console_WriteError(" --template One of: exe (default), lib, test, service, forms, ui-web-form, mcu."); #line 51 "./src/new_cmd.am" Console_WriteError(" --board For --template mcu: qemu-lm3s6965 (default) or nucleo-f767zi."); #line 52 "./src/new_cmd.am" Console_WriteError(" --no-vscode Skip the .vscode/ scaffold (launch.json + settings.json"); #line 53 "./src/new_cmd.am" Console_WriteError(" + tasks.json). On by default so F5 in VS Code launches"); #line 54 "./src/new_cmd.am" Console_WriteError(" the binary under `amc dap` with .am-level breakpoints."); #line 55 "./src/new_cmd.am" Console_WriteError(" Pass --no-vscode for projects edited in other editors"); #line 56 "./src/new_cmd.am" Console_WriteError(" (Neovim, Helix, IntelliJ)."); #line 57 "./src/new_cmd.am" Console_WriteError(" --force Overwrite if / already exists."); #line 58 "./src/new_cmd.am" Console_WriteError(" -h, --help Print this help and exit."); } i64 Amalgame_Compiler_NewCommand_Run(i64 argc) { #line 62 "./src/new_cmd.am" code_string name = ""; #line 63 "./src/new_cmd.am" code_string template = "exe"; #line 64 "./src/new_cmd.am" code_bool force = 0; #line 65 "./src/new_cmd.am" code_bool wantVscode = 1; #line 66 "./src/new_cmd.am" code_string board = ""; #line 68 "./src/new_cmd.am" i64 i = 2LL; #line 69 "./src/new_cmd.am" while (i < argc) { #line 70 "./src/new_cmd.am" code_string a = Args_Get(i); #line 71 "./src/new_cmd.am" if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) { #line 72 "./src/new_cmd.am" Amalgame_Compiler_NewCommand_PrintUsage(); #line 73 "./src/new_cmd.am" return 0LL; } #line 75 "./src/new_cmd.am" if (code_string_equals(a, "--force")) { #line 76 "./src/new_cmd.am" force = 1; } else if (code_string_equals(a, "--vscode")) { #line 79 "./src/new_cmd.am" wantVscode = 1; } else if (code_string_equals(a, "--no-vscode")) { #line 81 "./src/new_cmd.am" wantVscode = 0; } else if (code_string_equals(a, "--template")) { #line 83 "./src/new_cmd.am" if ((i + 1LL) >= argc) { #line 84 "./src/new_cmd.am" Console_WriteError("amc new: --template needs a value"); #line 85 "./src/new_cmd.am" return 1LL; } #line 87 "./src/new_cmd.am" i = (i + 1LL); #line 88 "./src/new_cmd.am" template = Args_Get(i); } else if (code_string_equals(a, "--board")) { #line 90 "./src/new_cmd.am" if ((i + 1LL) >= argc) { #line 91 "./src/new_cmd.am" Console_WriteError("amc new: --board needs a value"); #line 92 "./src/new_cmd.am" return 1LL; } #line 94 "./src/new_cmd.am" i = (i + 1LL); #line 95 "./src/new_cmd.am" board = Args_Get(i); } else if (String_StartsWith(a, "-")) { #line 97 "./src/new_cmd.am" Console_WriteError(code_string_concat((code_string_concat("amc new: unknown flag '", a)), "'")); #line 98 "./src/new_cmd.am" Amalgame_Compiler_NewCommand_PrintUsage(); #line 99 "./src/new_cmd.am" return 1LL; } else { #line 101 "./src/new_cmd.am" if (String_Length(name) == 0LL) { #line 102 "./src/new_cmd.am" name = a; } else { #line 104 "./src/new_cmd.am" Console_WriteError(code_string_concat((code_string_concat("amc new: extra positional '", a)), "'")); #line 105 "./src/new_cmd.am" return 1LL; } } #line 108 "./src/new_cmd.am" i = (i + 1LL); } #line 111 "./src/new_cmd.am" if (String_Length(name) == 0LL) { #line 112 "./src/new_cmd.am" Console_WriteError("amc new: missing "); #line 113 "./src/new_cmd.am" Amalgame_Compiler_NewCommand_PrintUsage(); #line 114 "./src/new_cmd.am" return 1LL; } #line 116 "./src/new_cmd.am" if (((((((!code_string_equals(template, "exe")) && (!code_string_equals(template, "lib"))) && (!code_string_equals(template, "test"))) && (!code_string_equals(template, "service"))) && (!code_string_equals(template, "forms"))) && (!code_string_equals(template, "ui-web-form"))) && (!code_string_equals(template, "mcu"))) { #line 117 "./src/new_cmd.am" Console_WriteError(code_string_concat((code_string_concat("amc new: unknown template '", template)), "' (try exe / lib / test / service / forms / ui-web-form / mcu)")); #line 118 "./src/new_cmd.am" return 1LL; } #line 123 "./src/new_cmd.am" if (code_string_equals(template, "mcu")) { #line 124 "./src/new_cmd.am" if (String_Length(board) == 0LL) { board = "qemu-lm3s6965"; } #line 125 "./src/new_cmd.am" if ((!code_string_equals(board, "qemu-lm3s6965")) && (!code_string_equals(board, "nucleo-f767zi"))) { #line 126 "./src/new_cmd.am" Console_WriteError(code_string_concat((code_string_concat("amc new: unknown --board '", board)), "' (try qemu-lm3s6965 / nucleo-f767zi)")); #line 127 "./src/new_cmd.am" return 1LL; } } #line 134 "./src/new_cmd.am" code_string baseName = Amalgame_Compiler_NewCommand_Basename(name); #line 135 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_IsSafeName(baseName)) { #line 136 "./src/new_cmd.am" Console_WriteError(code_string_concat((code_string_concat("amc new: '", baseName)), "' is not a safe project name (a-z, A-Z, 0-9, _ or -)")); #line 137 "./src/new_cmd.am" return 1LL; } #line 142 "./src/new_cmd.am" if (File_Exists(name) && !force) { #line 143 "./src/new_cmd.am" Console_WriteError(code_string_concat((code_string_concat("amc new: '", name)), "' already exists (pass --force to overwrite)")); #line 144 "./src/new_cmd.am" return 1LL; } #line 151 "./src/new_cmd.am" if (!File_Mkdir(name)) { #line 152 "./src/new_cmd.am" Console_WriteError(code_string_concat((code_string_concat("amc new: failed to create directory '", name)), "'")); #line 153 "./src/new_cmd.am" return 1LL; } #line 156 "./src/new_cmd.am" i64 rc = 0LL; #line 157 "./src/new_cmd.am" if (code_string_equals(template, "exe")) { #line 158 "./src/new_cmd.am" rc = Amalgame_Compiler_NewCommand_ScaffoldExe(name, baseName); } else if (code_string_equals(template, "lib")) { #line 160 "./src/new_cmd.am" rc = Amalgame_Compiler_NewCommand_ScaffoldLib(name, baseName); } else if (code_string_equals(template, "service")) { #line 162 "./src/new_cmd.am" rc = Amalgame_Compiler_NewCommand_ScaffoldService(name, baseName); } else if (code_string_equals(template, "forms")) { #line 164 "./src/new_cmd.am" rc = Amalgame_Compiler_NewCommand_ScaffoldForms(name, baseName); } else if (code_string_equals(template, "ui-web-form")) { #line 166 "./src/new_cmd.am" rc = Amalgame_Compiler_NewCommand_ScaffoldUiWebForm(name, baseName); } else if (code_string_equals(template, "mcu")) { #line 170 "./src/new_cmd.am" return Amalgame_Compiler_NewCommand_ScaffoldMcu(name, baseName, board); } else { #line 172 "./src/new_cmd.am" rc = Amalgame_Compiler_NewCommand_ScaffoldTest(name, baseName); } #line 174 "./src/new_cmd.am" if (rc != 0LL) { return rc; } #line 178 "./src/new_cmd.am" if (wantVscode) { #line 179 "./src/new_cmd.am" return Amalgame_Compiler_NewCommand_WriteVscodeConfig(name, baseName, template); } #line 181 "./src/new_cmd.am" return 0LL; } static i64 Amalgame_Compiler_NewCommand_ScaffoldExe(code_string path, code_string base) { #line 187 "./src/new_cmd.am" if (!File_Mkdir(code_string_concat(path, "/src")) || !File_Mkdir(code_string_concat(path, "/tests"))) { #line 188 "./src/new_cmd.am" Console_WriteError("amc new: failed to create subdirectories"); #line 189 "./src/new_cmd.am" return 1LL; } #line 192 "./src/new_cmd.am" code_string mainAm = Amalgame_Compiler_NewCommand_MainAmExe(base); #line 193 "./src/new_cmd.am" code_string testAm = Amalgame_Compiler_NewCommand_TestAmExe(base); #line 194 "./src/new_cmd.am" code_string buildSh = Amalgame_Compiler_NewCommand_BuildShExe(base); #line 195 "./src/new_cmd.am" code_string readme = Amalgame_Compiler_NewCommand_ReadmeExe(base); #line 196 "./src/new_cmd.am" code_string gitignore = Amalgame_Compiler_NewCommand_GitignoreCommon(); #line 198 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/src/main.am"), mainAm)) { return 1LL; } #line 199 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/tests/hello_test.am"), testAm)) { return 1LL; } #line 200 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/build.sh"), buildSh)) { return 1LL; } #line 201 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/.gitignore"), gitignore)) { return 1LL; } #line 202 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/README.md"), readme)) { return 1LL; } #line 203 "./src/new_cmd.am" Process_Run(code_string_concat("chmod +x ", Amalgame_Compiler_NewCommand_ShellEscape(code_string_concat(path, "/build.sh")))); #line 205 "./src/new_cmd.am" Console_WriteLine(code_string_concat((code_string_concat("Scaffolded '", base)), "' (exe template).")); #line 206 "./src/new_cmd.am" Console_WriteLine(code_string_concat(" cd ", path)); #line 207 "./src/new_cmd.am" Console_WriteLine(code_string_concat(" ./build.sh && ./", base)); #line 208 "./src/new_cmd.am" return 0LL; } static i64 Amalgame_Compiler_NewCommand_ScaffoldLib(code_string path, code_string base) { #line 212 "./src/new_cmd.am" if (!File_Mkdir(code_string_concat(path, "/src"))) { #line 213 "./src/new_cmd.am" Console_WriteError("amc new: failed to create src/ subdirectory"); #line 214 "./src/new_cmd.am" return 1LL; } #line 217 "./src/new_cmd.am" code_string libAm = Amalgame_Compiler_NewCommand_LibAm(base); #line 218 "./src/new_cmd.am" code_string buildSh = Amalgame_Compiler_NewCommand_BuildShLib(base); #line 219 "./src/new_cmd.am" code_string readme = Amalgame_Compiler_NewCommand_ReadmeLib(base); #line 220 "./src/new_cmd.am" code_string gitignore = Amalgame_Compiler_NewCommand_GitignoreCommon(); #line 222 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat((code_string_concat((code_string_concat(path, "/src/")), base)), ".am"), libAm)) { return 1LL; } #line 223 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/build.sh"), buildSh)) { return 1LL; } #line 224 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/.gitignore"), gitignore)) { return 1LL; } #line 225 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/README.md"), readme)) { return 1LL; } #line 226 "./src/new_cmd.am" Process_Run(code_string_concat("chmod +x ", Amalgame_Compiler_NewCommand_ShellEscape(code_string_concat(path, "/build.sh")))); #line 228 "./src/new_cmd.am" Console_WriteLine(code_string_concat((code_string_concat("Scaffolded '", base)), "' (lib template).")); #line 229 "./src/new_cmd.am" Console_WriteLine(code_string_concat(" cd ", path)); #line 230 "./src/new_cmd.am" Console_WriteLine(code_string_concat((code_string_concat(" ./build.sh # builds ", base)), ".o (library)")); #line 231 "./src/new_cmd.am" return 0LL; } static i64 Amalgame_Compiler_NewCommand_ScaffoldService(code_string path, code_string base) { #line 235 "./src/new_cmd.am" if (!File_Mkdir(code_string_concat(path, "/src"))) { #line 236 "./src/new_cmd.am" Console_WriteError("amc new: failed to create src/ subdirectory"); #line 237 "./src/new_cmd.am" return 1LL; } #line 242 "./src/new_cmd.am" code_string mainAm = Amalgame_Compiler_NewCommand_MainAmService(base); #line 243 "./src/new_cmd.am" code_string unit = Amalgame_Compiler_NewCommand_SystemdUnit(base); #line 244 "./src/new_cmd.am" code_string installSh = Amalgame_Compiler_NewCommand_InstallShService(base); #line 245 "./src/new_cmd.am" code_string buildSh = Amalgame_Compiler_NewCommand_BuildShService(base); #line 246 "./src/new_cmd.am" code_string plistMacos = Amalgame_Compiler_NewCommand_PlistMacosService(base); #line 247 "./src/new_cmd.am" code_string installMacOs = Amalgame_Compiler_NewCommand_InstallMacosShService(base); #line 254 "./src/new_cmd.am" code_string buildPs1 = Amalgame_Compiler_NewCommand_BuildPs1Service(base); #line 255 "./src/new_cmd.am" code_string installPs1 = Amalgame_Compiler_NewCommand_InstallPs1Service(base); #line 256 "./src/new_cmd.am" code_string readme = Amalgame_Compiler_NewCommand_ReadmeService(base); #line 257 "./src/new_cmd.am" code_string gitignore = Amalgame_Compiler_NewCommand_GitignoreService(base); #line 262 "./src/new_cmd.am" code_string manifest = Amalgame_Compiler_NewCommand_ManifestService(base); #line 264 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/src/main.am"), mainAm)) { return 1LL; } #line 265 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/amalgame.toml"), manifest)) { return 1LL; } #line 266 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat((code_string_concat((code_string_concat(path, "/")), base)), ".service"), unit)) { return 1LL; } #line 267 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/install.sh"), installSh)) { return 1LL; } #line 268 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/build.sh"), buildSh)) { return 1LL; } #line 269 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat((code_string_concat((code_string_concat(path, "/com.amalgame.")), base)), ".plist"), plistMacos)) { return 1LL; } #line 270 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/install-macos.sh"), installMacOs)) { return 1LL; } #line 271 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/install.ps1"), installPs1)) { return 1LL; } #line 272 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/build.ps1"), buildPs1)) { return 1LL; } #line 273 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/.gitignore"), gitignore)) { return 1LL; } #line 274 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/README.md"), readme)) { return 1LL; } #line 275 "./src/new_cmd.am" Process_Run(code_string_concat("chmod +x ", Amalgame_Compiler_NewCommand_ShellEscape(code_string_concat(path, "/build.sh")))); #line 276 "./src/new_cmd.am" Process_Run(code_string_concat("chmod +x ", Amalgame_Compiler_NewCommand_ShellEscape(code_string_concat(path, "/install.sh")))); #line 277 "./src/new_cmd.am" Process_Run(code_string_concat("chmod +x ", Amalgame_Compiler_NewCommand_ShellEscape(code_string_concat(path, "/install-macos.sh")))); #line 279 "./src/new_cmd.am" Console_WriteLine(code_string_concat((code_string_concat("Scaffolded '", base)), "' (service template).")); #line 280 "./src/new_cmd.am" Console_WriteLine(code_string_concat(" cd ", path)); #line 281 "./src/new_cmd.am" Console_WriteLine(" amc package add logging service # fetch external deps (one-off)"); #line 282 "./src/new_cmd.am" Console_WriteLine(" Linux: ./build.sh && sudo ./install.sh"); #line 283 "./src/new_cmd.am" Console_WriteLine(code_string_concat(" sudo journalctl -fu ", base)); #line 284 "./src/new_cmd.am" Console_WriteLine(" macOS: ./build.sh && sudo ./install-macos.sh"); #line 285 "./src/new_cmd.am" Console_WriteLine(code_string_concat((code_string_concat(" tail -f /usr/local/var/log/", base)), ".err.log")); #line 286 "./src/new_cmd.am" Console_WriteLine(" Windows: .\\build.ps1 ; Start-Process powershell -Verb runAs install.ps1"); #line 287 "./src/new_cmd.am" Console_WriteLine(" (registers as a native Windows service via sc.exe)"); #line 288 "./src/new_cmd.am" return 0LL; } static i64 Amalgame_Compiler_NewCommand_ScaffoldForms(code_string path, code_string base) { #line 292 "./src/new_cmd.am" if (!File_Mkdir(code_string_concat(path, "/src"))) { #line 293 "./src/new_cmd.am" Console_WriteError("amc new: failed to create src/ subdirectory"); #line 294 "./src/new_cmd.am" return 1LL; } #line 297 "./src/new_cmd.am" code_string mainAm = Amalgame_Compiler_NewCommand_MainAmForms(base); #line 298 "./src/new_cmd.am" code_string manifest = Amalgame_Compiler_NewCommand_ManifestForms(base); #line 299 "./src/new_cmd.am" code_string buildSh = Amalgame_Compiler_NewCommand_BuildShForms(base); #line 300 "./src/new_cmd.am" code_string readme = Amalgame_Compiler_NewCommand_ReadmeForms(base); #line 301 "./src/new_cmd.am" code_string gitignore = Amalgame_Compiler_NewCommand_GitignoreCommon(); #line 303 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/src/main.am"), mainAm)) { return 1LL; } #line 304 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/amalgame.toml"), manifest)) { return 1LL; } #line 305 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/build.sh"), buildSh)) { return 1LL; } #line 306 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/.gitignore"), gitignore)) { return 1LL; } #line 307 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/README.md"), readme)) { return 1LL; } #line 308 "./src/new_cmd.am" Process_Run(code_string_concat("chmod +x ", Amalgame_Compiler_NewCommand_ShellEscape(code_string_concat(path, "/build.sh")))); #line 310 "./src/new_cmd.am" Console_WriteLine(code_string_concat((code_string_concat("Scaffolded '", base)), "' (forms template).")); #line 311 "./src/new_cmd.am" Console_WriteLine(code_string_concat(" cd ", path)); #line 312 "./src/new_cmd.am" Console_WriteLine(" amc package add ui-sdl ui-forms # fetch external deps (one-off)"); #line 313 "./src/new_cmd.am" Console_WriteLine(" sudo apt install libsdl2-dev libsdl2-ttf-dev # Linux build deps"); #line 314 "./src/new_cmd.am" Console_WriteLine(code_string_concat(" ./build.sh && ./", base)); #line 315 "./src/new_cmd.am" return 0LL; } static i64 Amalgame_Compiler_NewCommand_ScaffoldTest(code_string path, code_string base) { #line 319 "./src/new_cmd.am" if (!File_Mkdir(code_string_concat(path, "/tests"))) { #line 320 "./src/new_cmd.am" Console_WriteError("amc new: failed to create tests/ subdirectory"); #line 321 "./src/new_cmd.am" return 1LL; } #line 324 "./src/new_cmd.am" code_string testAm = Amalgame_Compiler_NewCommand_TestAmTest(base); #line 325 "./src/new_cmd.am" code_string readme = Amalgame_Compiler_NewCommand_ReadmeTest(base); #line 326 "./src/new_cmd.am" code_string gitignore = Amalgame_Compiler_NewCommand_GitignoreCommon(); #line 328 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat((code_string_concat((code_string_concat(path, "/tests/")), base)), "_test.am"), testAm)) { return 1LL; } #line 329 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/.gitignore"), gitignore)) { return 1LL; } #line 330 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/README.md"), readme)) { return 1LL; } #line 332 "./src/new_cmd.am" Console_WriteLine(code_string_concat((code_string_concat("Scaffolded '", base)), "' (test template).")); #line 333 "./src/new_cmd.am" Console_WriteLine(code_string_concat(" cd ", path)); #line 334 "./src/new_cmd.am" Console_WriteLine(" amc test tests/"); #line 335 "./src/new_cmd.am" return 0LL; } static i64 Amalgame_Compiler_NewCommand_ScaffoldMcu(code_string path, code_string base, code_string board) { #line 344 "./src/new_cmd.am" code_bool isQemu = code_string_equals(board, "qemu-lm3s6965"); #line 345 "./src/new_cmd.am" code_string target = "cortex-m7"; #line 346 "./src/new_cmd.am" if (isQemu) { target = "cortex-m3"; } #line 348 "./src/new_cmd.am" if (!File_Mkdir(code_string_concat(path, "/.vscode"))) { #line 349 "./src/new_cmd.am" Console_WriteError("amc new: failed to create .vscode/"); #line 350 "./src/new_cmd.am" return 1LL; } #line 352 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/app.am"), Amalgame_Compiler_NewCommand_McuAppAm(base, isQemu))) { return 1LL; } #line 353 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/README.md"), Amalgame_Compiler_NewCommand_McuReadme(base, board, target, isQemu))) { return 1LL; } #line 354 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/.gitignore"), Amalgame_Compiler_NewCommand_McuGitignore())) { return 1LL; } #line 355 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/amalgame.toml"), Amalgame_Compiler_NewCommand_McuToml(base, board, target, isQemu))) { return 1LL; } #line 356 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/.vscode/tasks.json"), Amalgame_Compiler_NewCommand_McuTasksJson(target, isQemu))) { return 1LL; } #line 357 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/.vscode/launch.json"), Amalgame_Compiler_NewCommand_McuLaunchJson(isQemu))) { return 1LL; } #line 359 "./src/new_cmd.am" if (!isQemu) { #line 361 "./src/new_cmd.am" if (!File_Mkdir(code_string_concat(path, "/boards")) || !File_Mkdir(code_string_concat(path, "/runtime"))) { #line 362 "./src/new_cmd.am" Console_WriteError("amc new: failed to create boards/ or runtime/"); #line 363 "./src/new_cmd.am" return 1LL; } #line 365 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/boards/startup.c"), Amalgame_Compiler_NewCommand_McuStartupF767())) { return 1LL; } #line 366 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/boards/stm32f767zi.ld"), Amalgame_Compiler_NewCommand_McuLinkerF767())) { return 1LL; } #line 367 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/runtime/Amalgame_Mcu_Board.h"), Amalgame_Compiler_NewCommand_McuHeaderF767())) { return 1LL; } } #line 370 "./src/new_cmd.am" Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat("Scaffolded '", base)), "' (mcu template, board=")), board)), ").")); #line 371 "./src/new_cmd.am" Console_WriteLine(code_string_concat(" cd ", path)); #line 372 "./src/new_cmd.am" if (isQemu) { #line 373 "./src/new_cmd.am" Console_WriteLine(" amc build --target=cortex-m3 app.am -o firmware"); #line 374 "./src/new_cmd.am" Console_WriteLine(" qemu-system-arm -M lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel firmware"); #line 375 "./src/new_cmd.am" Console_WriteLine(" (or just press F5 in VS Code — runs in QEMU)"); } else { #line 377 "./src/new_cmd.am" Console_WriteLine(" amc mcu setup # one-time: toolchain + libopencm3 (auto-detected)"); #line 378 "./src/new_cmd.am" Console_WriteLine(" amc build --target=cortex-m7 --board=. --flash app.am -o firmware"); #line 379 "./src/new_cmd.am" Console_WriteLine(" (or in VS Code: Ctrl-Shift-B = flash, F5 = debug on chip)"); } #line 384 "./src/new_cmd.am" if (Amalgame_Compiler_McuCommand_IsInteractive() && !Amalgame_Compiler_McuCommand_Has("arm-none-eabi-gcc")) { #line 385 "./src/new_cmd.am" Console_WriteLine(""); #line 386 "./src/new_cmd.am" Console_WriteLine("MCU toolchain not detected."); #line 387 "./src/new_cmd.am" i64 _sr = Amalgame_Compiler_McuCommand_Setup(0); } #line 389 "./src/new_cmd.am" return 0LL; } static code_string Amalgame_Compiler_NewCommand_McuAppAm(code_string base, code_bool isQemu) { #line 393 "./src/new_cmd.am" code_string led = "16"; #line 394 "./src/new_cmd.am" if (isQemu) { led = "13"; } #line 395 "./src/new_cmd.am" code_string s = ""; #line 396 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "namespace ")), base)), "\n\n")); #line 397 "./src/new_cmd.am" s = (code_string_concat(s, "// Bare-metal blink via the Amalgame.Mcu HAL + the embedded\n")); #line 398 "./src/new_cmd.am" s = (code_string_concat(s, "// execution model (setup / loop / region). See README.md.\n")); #line 399 "./src/new_cmd.am" s = (code_string_concat(s, "public class Program {\n")); #line 400 "./src/new_cmd.am" s = (code_string_concat(s, " public static void Main() {\n")); #line 401 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " let led = ")), led)), "\n")); #line 402 "./src/new_cmd.am" s = (code_string_concat(s, " Mcu.PinMode(led, Mcu.Output())\n")); #line 403 "./src/new_cmd.am" s = (code_string_concat(s, " var i = 0\n")); #line 404 "./src/new_cmd.am" s = (code_string_concat(s, " loop {\n")); #line 405 "./src/new_cmd.am" s = (code_string_concat(s, " i = i + 1\n")); #line 406 "./src/new_cmd.am" s = (code_string_concat(s, " Mcu.Toggle(led)\n")); #line 407 "./src/new_cmd.am" s = (code_string_concat(s, " Mcu.DelayMs(500)\n")); #line 408 "./src/new_cmd.am" if (isQemu) { #line 409 "./src/new_cmd.am" s = (code_string_concat(s, " if (i >= 6) { break } // bounded so QEMU returns\n")); } #line 411 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 412 "./src/new_cmd.am" if (isQemu) { s = (code_string_concat(s, " Console.WriteLine(\"blink done\")\n")); } #line 413 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 414 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 415 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_McuToml(code_string base, code_string board, code_string target, code_bool isQemu) { #line 419 "./src/new_cmd.am" code_string s = ""; #line 420 "./src/new_cmd.am" s = (code_string_concat(s, "[package]\n")); #line 421 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "name = \"")), base)), "\"\n")); #line 422 "./src/new_cmd.am" s = (code_string_concat(s, "version = \"0.1.0\"\n")); #line 423 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "description = \"Amalgame MCU project (")), board)), ")\"\n\n")); #line 424 "./src/new_cmd.am" s = (code_string_concat(s, "[target]\n")); #line 425 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "mcu = \"")), target)), "\"\n")); #line 426 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "board = \"")), board)), "\"\n")); #line 427 "./src/new_cmd.am" if (!isQemu) { #line 428 "./src/new_cmd.am" s = (code_string_concat(s, "cpu_flags = \"-mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16\"\n")); #line 429 "./src/new_cmd.am" s = (code_string_concat(s, "defines = [\"STM32F7\"]\n")); #line 430 "./src/new_cmd.am" s = (code_string_concat(s, "linker = \"boards/stm32f767zi.ld\"\n")); #line 431 "./src/new_cmd.am" s = (code_string_concat(s, "flash_tool = \"openocd\"\n")); #line 432 "./src/new_cmd.am" s = (code_string_concat(s, "openocd_cfg = \"board/st_nucleo_f7.cfg\"\n")); #line 433 "./src/new_cmd.am" s = (code_string_concat(s, "flash_addr = \"0x08000000\"\n\n")); #line 434 "./src/new_cmd.am" s = (code_string_concat(s, "[stdlib]\n")); #line 435 "./src/new_cmd.am" s = (code_string_concat(s, "classes = [\"Mcu\"]\n")); #line 436 "./src/new_cmd.am" s = (code_string_concat(s, "namespace = \"Amalgame.Mcu\"\n")); #line 437 "./src/new_cmd.am" s = (code_string_concat(s, "header = \"runtime/Amalgame_Mcu_Board.h\"\n")); #line 438 "./src/new_cmd.am" s = (code_string_concat(s, "libs = [\"opencm3_stm32f7\"]\n")); } #line 440 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_McuTasksJson(code_string target, code_bool isQemu) { #line 444 "./src/new_cmd.am" code_string lb = "{"; #line 445 "./src/new_cmd.am" code_string rb = "}"; #line 446 "./src/new_cmd.am" code_string wsf = code_string_concat((code_string_concat((code_string_concat("$", lb)), "workspaceFolder")), rb); #line 447 "./src/new_cmd.am" code_string home = code_string_concat((code_string_concat((code_string_concat("$", lb)), "env:HOME")), rb); #line 448 "./src/new_cmd.am" code_string s = ""; #line 449 "./src/new_cmd.am" s = (code_string_concat(s, "{\n \"version\": \"2.0.0\",\n \"tasks\": [\n")); #line 450 "./src/new_cmd.am" if (isQemu) { #line 451 "./src/new_cmd.am" s = (code_string_concat(s, " {\n")); #line 452 "./src/new_cmd.am" s = (code_string_concat(s, " \"label\": \"amc: build (mcu, debug)\",\n")); #line 453 "./src/new_cmd.am" s = (code_string_concat(s, " \"type\": \"shell\", \"command\": \"amc\",\n")); #line 454 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " \"args\": [\"build\", \"--debug\", \"--target=")), target)), "\", \"app.am\", \"-o\", \"firmware\"],\n")); #line 455 "./src/new_cmd.am" s = (code_string_concat(s, " \"group\": \"build\", \"problemMatcher\": [\"$gcc\"]\n")); #line 456 "./src/new_cmd.am" s = (code_string_concat(s, " },\n")); #line 457 "./src/new_cmd.am" s = (code_string_concat(s, " {\n")); #line 458 "./src/new_cmd.am" s = (code_string_concat(s, " \"label\": \"amc: run (qemu)\",\n")); #line 459 "./src/new_cmd.am" s = (code_string_concat(s, " \"type\": \"shell\",\n")); #line 460 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " \"command\": \"amc build --target=")), target)), " app.am -o firmware && qemu-system-arm -M lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel firmware\",\n")); #line 461 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, " \"group\": ")), lb)), " \"kind\": \"build\", \"isDefault\": true ")), rb)), ",\n")); #line 462 "./src/new_cmd.am" s = (code_string_concat(s, " \"problemMatcher\": [\"$gcc\"]\n")); #line 463 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); } else { #line 465 "./src/new_cmd.am" s = (code_string_concat(s, " {\n")); #line 466 "./src/new_cmd.am" s = (code_string_concat(s, " \"label\": \"amc: build (mcu, debug)\",\n")); #line 467 "./src/new_cmd.am" s = (code_string_concat(s, " \"type\": \"shell\", \"command\": \"amc\",\n")); #line 468 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, " \"args\": [\"build\", \"--debug\", \"--target=")), target)), "\", \"--board=")), wsf)), "\", \"app.am\", \"-o\", \"firmware\"],\n")); #line 469 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, " \"options\": ")), lb)), " \"env\": ")), lb)), " \"AMC_EMBED_INC\": \"")), home)), "/libopencm3/include\", \"AMC_EMBED_LIB\": \"")), home)), "/libopencm3/lib\" ")), rb)), " ")), rb)), ",\n")); #line 470 "./src/new_cmd.am" s = (code_string_concat(s, " \"group\": \"build\", \"problemMatcher\": [\"$gcc\"]\n")); #line 471 "./src/new_cmd.am" s = (code_string_concat(s, " },\n")); #line 472 "./src/new_cmd.am" s = (code_string_concat(s, " {\n")); #line 473 "./src/new_cmd.am" s = (code_string_concat(s, " \"label\": \"amc: flash (mcu)\",\n")); #line 474 "./src/new_cmd.am" s = (code_string_concat(s, " \"type\": \"shell\", \"command\": \"amc\",\n")); #line 475 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, " \"args\": [\"build\", \"--target=")), target)), "\", \"--board=")), wsf)), "\", \"--flash\", \"app.am\", \"-o\", \"firmware\"],\n")); #line 476 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, " \"options\": ")), lb)), " \"env\": ")), lb)), " \"AMC_EMBED_INC\": \"")), home)), "/libopencm3/include\", \"AMC_EMBED_LIB\": \"")), home)), "/libopencm3/lib\" ")), rb)), " ")), rb)), ",\n")); #line 477 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, " \"group\": ")), lb)), " \"kind\": \"build\", \"isDefault\": true ")), rb)), ",\n")); #line 478 "./src/new_cmd.am" s = (code_string_concat(s, " \"problemMatcher\": [\"$gcc\"]\n")); #line 479 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); } #line 481 "./src/new_cmd.am" s = (code_string_concat(s, " ]\n}\n")); #line 482 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_McuLaunchJson(code_bool isQemu) { #line 486 "./src/new_cmd.am" code_string lb = "{"; #line 487 "./src/new_cmd.am" code_string rb = "}"; #line 488 "./src/new_cmd.am" code_string wsf = code_string_concat((code_string_concat((code_string_concat("$", lb)), "workspaceFolder")), rb); #line 489 "./src/new_cmd.am" code_string s = ""; #line 490 "./src/new_cmd.am" s = (code_string_concat(s, "{\n \"version\": \"0.2.0\",\n \"configurations\": [\n")); #line 491 "./src/new_cmd.am" if (isQemu) { #line 495 "./src/new_cmd.am" s = (code_string_concat(s, " {\n")); #line 496 "./src/new_cmd.am" s = (code_string_concat(s, " \"type\": \"amc\", \"request\": \"launch\",\n")); #line 497 "./src/new_cmd.am" s = (code_string_concat(s, " \"name\": \"Run in QEMU\",\n")); #line 498 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " \"program\": \"")), wsf)), "/firmware\",\n")); #line 499 "./src/new_cmd.am" s = (code_string_concat(s, " \"preLaunchTask\": \"amc: run (qemu)\",\n")); #line 500 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " \"cwd\": \"")), wsf)), "\"\n")); #line 501 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); } else { #line 503 "./src/new_cmd.am" s = (code_string_concat(s, " {\n")); #line 504 "./src/new_cmd.am" s = (code_string_concat(s, " \"type\": \"amc\", \"request\": \"launch\",\n")); #line 505 "./src/new_cmd.am" s = (code_string_concat(s, " \"name\": \"Debug on MCU\",\n")); #line 506 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " \"program\": \"")), wsf)), "/firmware\",\n")); #line 507 "./src/new_cmd.am" s = (code_string_concat(s, " \"target\": \"cortex-m7\",\n")); #line 508 "./src/new_cmd.am" s = (code_string_concat(s, " \"openocd\": \"board/st_nucleo_f7.cfg\",\n")); #line 509 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " \"cwd\": \"")), wsf)), "\",\n")); #line 510 "./src/new_cmd.am" s = (code_string_concat(s, " \"stopOnEntry\": false,\n")); #line 511 "./src/new_cmd.am" s = (code_string_concat(s, " \"preLaunchTask\": \"amc: build (mcu, debug)\"\n")); #line 512 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); } #line 514 "./src/new_cmd.am" s = (code_string_concat(s, " ]\n}\n")); #line 515 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_McuGitignore() { #line 519 "./src/new_cmd.am" return "firmware\nfirmware.c\n*.elf\n*.bin\n*.hex\n*.o\n"; } static code_string Amalgame_Compiler_NewCommand_McuStartupF767() { #line 525 "./src/new_cmd.am" code_string s = ""; #line 526 "./src/new_cmd.am" s = (code_string_concat(s, "/* Cortex-M7 startup for STM32F767ZI. Owns reset; calls amc_main(). */\n")); #line 527 "./src/new_cmd.am" s = (code_string_concat(s, "#include \n")); #line 528 "./src/new_cmd.am" s = (code_string_concat(s, "extern uint32_t _sidata, _sdata, _edata, _sbss, _ebss, _estack;\n")); #line 529 "./src/new_cmd.am" s = (code_string_concat(s, "extern int amc_main(void);\n")); #line 530 "./src/new_cmd.am" s = (code_string_concat(s, "void Reset_Handler(void);\n")); #line 531 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "void Default_Handler(void) { for (;;) ")), "{")), "} }\n")); #line 532 "./src/new_cmd.am" s = (code_string_concat(s, "__attribute__((section(\".isr_vector\"), used))\n")); #line 533 "./src/new_cmd.am" s = (code_string_concat(s, "uint32_t *const vector_table[] = {\n")); #line 534 "./src/new_cmd.am" s = (code_string_concat(s, " (uint32_t *)&_estack,\n")); #line 535 "./src/new_cmd.am" s = (code_string_concat(s, " (uint32_t *)Reset_Handler,\n")); #line 536 "./src/new_cmd.am" s = (code_string_concat(s, " (uint32_t *)Default_Handler,\n")); #line 537 "./src/new_cmd.am" s = (code_string_concat(s, " (uint32_t *)Default_Handler,\n")); #line 538 "./src/new_cmd.am" s = (code_string_concat(s, " (uint32_t *)Default_Handler,\n")); #line 539 "./src/new_cmd.am" s = (code_string_concat(s, " (uint32_t *)Default_Handler,\n")); #line 540 "./src/new_cmd.am" s = (code_string_concat(s, " (uint32_t *)Default_Handler,\n")); #line 541 "./src/new_cmd.am" s = (code_string_concat(s, "};\n")); #line 542 "./src/new_cmd.am" s = (code_string_concat(s, "void Reset_Handler(void) {\n")); #line 543 "./src/new_cmd.am" s = (code_string_concat(s, " uint32_t *src = &_sidata, *dst = &_sdata;\n")); #line 544 "./src/new_cmd.am" s = (code_string_concat(s, " while (dst < &_edata) *dst++ = *src++;\n")); #line 545 "./src/new_cmd.am" s = (code_string_concat(s, " for (dst = &_sbss; dst < &_ebss; ) *dst++ = 0;\n")); #line 546 "./src/new_cmd.am" s = (code_string_concat(s, " amc_main();\n")); #line 547 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " for (;;) ")), "{")), "}\n")); #line 548 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 549 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_McuLinkerF767() { #line 553 "./src/new_cmd.am" code_string s = ""; #line 554 "./src/new_cmd.am" s = (code_string_concat(s, "/* STM32F767ZI: 2 MB flash @ 0x08000000, 512 KB SRAM @ 0x20000000. */\n")); #line 555 "./src/new_cmd.am" s = (code_string_concat(s, "MEMORY\n{\n")); #line 556 "./src/new_cmd.am" s = (code_string_concat(s, " FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K\n")); #line 557 "./src/new_cmd.am" s = (code_string_concat(s, " RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 512K\n")); #line 558 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 559 "./src/new_cmd.am" s = (code_string_concat(s, "_estack = ORIGIN(RAM) + LENGTH(RAM);\n")); #line 560 "./src/new_cmd.am" s = (code_string_concat(s, "SECTIONS\n{\n")); #line 561 "./src/new_cmd.am" s = (code_string_concat(s, " .isr_vector : { KEEP(*(.isr_vector)) } > FLASH\n")); #line 562 "./src/new_cmd.am" s = (code_string_concat(s, " .text : { *(.text*) *(.rodata*) } > FLASH\n")); #line 563 "./src/new_cmd.am" s = (code_string_concat(s, " _sidata = LOADADDR(.data);\n")); #line 564 "./src/new_cmd.am" s = (code_string_concat(s, " .data : { _sdata = .; *(.data*) _edata = .; } > RAM AT > FLASH\n")); #line 565 "./src/new_cmd.am" s = (code_string_concat(s, " .bss : { _sbss = .; *(.bss*) *(COMMON) _ebss = .; } > RAM\n")); #line 566 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 567 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_McuHeaderF767() { #line 571 "./src/new_cmd.am" code_string s = ""; #line 572 "./src/new_cmd.am" s = (code_string_concat(s, "/* Amalgame.Mcu HAL for Nucleo-F767ZI via libopencm3. */\n")); #line 573 "./src/new_cmd.am" s = (code_string_concat(s, "#ifndef AMALGAME_MCU_BOARD_F767ZI_H\n#define AMALGAME_MCU_BOARD_F767ZI_H\n")); #line 574 "./src/new_cmd.am" s = (code_string_concat(s, "#define AMC_HAVE_MCU_BOARD 1\n")); #line 575 "./src/new_cmd.am" s = (code_string_concat(s, "#include \n")); #line 576 "./src/new_cmd.am" s = (code_string_concat(s, "#include \n")); #line 577 "./src/new_cmd.am" s = (code_string_concat(s, "#include \n")); #line 578 "./src/new_cmd.am" s = (code_string_concat(s, "#include \n")); #line 579 "./src/new_cmd.am" s = (code_string_concat(s, "/* pin = port*16 + bit; port 0=A,1=B,... PB0 (green LD1) = 16 */\n")); #line 580 "./src/new_cmd.am" s = (code_string_concat(s, "#define Board_LedGreen ((i64)(1*16 + 0))\n")); #line 581 "./src/new_cmd.am" s = (code_string_concat(s, "#define Board_LedBlue ((i64)(1*16 + 7))\n")); #line 582 "./src/new_cmd.am" s = (code_string_concat(s, "#define Board_LedRed ((i64)(1*16 + 14))\n")); #line 583 "./src/new_cmd.am" s = (code_string_concat(s, "#define Board_LedBuiltin Board_LedGreen\n")); #line 584 "./src/new_cmd.am" s = (code_string_concat(s, "static const uint32_t amc_gpio_ports[11] = {\n")); #line 585 "./src/new_cmd.am" s = (code_string_concat(s, " GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH, GPIOI, GPIOJ, GPIOK };\n")); #line 586 "./src/new_cmd.am" s = (code_string_concat(s, "static const enum rcc_periph_clken amc_gpio_clk[11] = {\n")); #line 587 "./src/new_cmd.am" s = (code_string_concat(s, " RCC_GPIOA, RCC_GPIOB, RCC_GPIOC, RCC_GPIOD, RCC_GPIOE, RCC_GPIOF,\n")); #line 588 "./src/new_cmd.am" s = (code_string_concat(s, " RCC_GPIOG, RCC_GPIOH, RCC_GPIOI, RCC_GPIOJ, RCC_GPIOK };\n")); #line 589 "./src/new_cmd.am" s = (code_string_concat(s, "static inline uint32_t amc_port_of(i64 pin) { return amc_gpio_ports[(pin >> 4) & 0xF]; }\n")); #line 590 "./src/new_cmd.am" s = (code_string_concat(s, "static inline uint16_t amc_bit_of(i64 pin) { return (uint16_t)(1u << (pin & 0xF)); }\n")); #line 591 "./src/new_cmd.am" s = (code_string_concat(s, "static inline int Mcu_High(void) { return 1; }\n")); #line 592 "./src/new_cmd.am" s = (code_string_concat(s, "static inline int Mcu_Low(void) { return 0; }\n")); #line 593 "./src/new_cmd.am" s = (code_string_concat(s, "static inline int Mcu_Output(void) { return 1; }\n")); #line 594 "./src/new_cmd.am" s = (code_string_concat(s, "static inline int Mcu_Input(void) { return 0; }\n")); #line 595 "./src/new_cmd.am" s = (code_string_concat(s, "static inline void Mcu_PinMode(i64 pin, i64 mode) {\n")); #line 596 "./src/new_cmd.am" s = (code_string_concat(s, " rcc_periph_clock_enable(amc_gpio_clk[(pin >> 4) & 0xF]);\n")); #line 597 "./src/new_cmd.am" s = (code_string_concat(s, " gpio_mode_setup(amc_port_of(pin), mode ? GPIO_MODE_OUTPUT : GPIO_MODE_INPUT, GPIO_PUPD_NONE, amc_bit_of(pin)); }\n")); #line 598 "./src/new_cmd.am" s = (code_string_concat(s, "static inline void Mcu_DigitalWrite(i64 pin, i64 level) {\n")); #line 599 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " if (level) ")), "{")), " gpio_set(amc_port_of(pin), amc_bit_of(pin)); } else { gpio_clear(amc_port_of(pin), amc_bit_of(pin)); } }\n")); #line 600 "./src/new_cmd.am" s = (code_string_concat(s, "static inline i64 Mcu_DigitalRead(i64 pin) { return gpio_get(amc_port_of(pin), amc_bit_of(pin)) ? 1 : 0; }\n")); #line 601 "./src/new_cmd.am" s = (code_string_concat(s, "static inline void Mcu_Toggle(i64 pin) { gpio_toggle(amc_port_of(pin), amc_bit_of(pin)); }\n")); #line 602 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "static inline void Mcu_DelayMs(i64 ms) { for (volatile i64 i = 0; i < ms * 4000; i++) ")), "{")), " __asm__ volatile(\"nop\"); } }\n")); #line 603 "./src/new_cmd.am" s = (code_string_concat(s, "static inline i64 Mcu_Millis(void) { return 0; }\n")); #line 604 "./src/new_cmd.am" s = (code_string_concat(s, "/* Console over USART3 (PD8/PD9) = ST-LINK VCP /dev/ttyACM0 @115200. */\n")); #line 605 "./src/new_cmd.am" s = (code_string_concat(s, "#define AMC_HAVE_CONSOLE 1\n")); #line 606 "./src/new_cmd.am" s = (code_string_concat(s, "static int amc_uart_inited = 0;\n")); #line 607 "./src/new_cmd.am" s = (code_string_concat(s, "static void amc_uart_init(void) {\n")); #line 608 "./src/new_cmd.am" s = (code_string_concat(s, " rcc_periph_clock_enable(RCC_GPIOD);\n")); #line 609 "./src/new_cmd.am" s = (code_string_concat(s, " rcc_periph_clock_enable(RCC_USART3);\n")); #line 610 "./src/new_cmd.am" s = (code_string_concat(s, " gpio_mode_setup(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8 | GPIO9);\n")); #line 611 "./src/new_cmd.am" s = (code_string_concat(s, " gpio_set_af(GPIOD, GPIO_AF7, GPIO8 | GPIO9);\n")); #line 612 "./src/new_cmd.am" s = (code_string_concat(s, " rcc_apb1_frequency = 16000000;\n")); #line 613 "./src/new_cmd.am" s = (code_string_concat(s, " usart_set_baudrate(USART3, 115200);\n")); #line 614 "./src/new_cmd.am" s = (code_string_concat(s, " usart_set_databits(USART3, 8);\n")); #line 615 "./src/new_cmd.am" s = (code_string_concat(s, " usart_set_stopbits(USART3, USART_STOPBITS_1);\n")); #line 616 "./src/new_cmd.am" s = (code_string_concat(s, " usart_set_mode(USART3, USART_MODE_TX);\n")); #line 617 "./src/new_cmd.am" s = (code_string_concat(s, " usart_set_parity(USART3, USART_PARITY_NONE);\n")); #line 618 "./src/new_cmd.am" s = (code_string_concat(s, " usart_set_flow_control(USART3, USART_FLOWCONTROL_NONE);\n")); #line 619 "./src/new_cmd.am" s = (code_string_concat(s, " usart_enable(USART3);\n")); #line 620 "./src/new_cmd.am" s = (code_string_concat(s, " amc_uart_inited = 1;\n")); #line 621 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 622 "./src/new_cmd.am" s = (code_string_concat(s, "static inline void code_putc(char c) {\n")); #line 623 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " if (!amc_uart_inited) ")), "{")), " amc_uart_init(); }\n")); #line 624 "./src/new_cmd.am" s = (code_string_concat(s, " usart_send_blocking(USART3, (uint8_t)c);\n")); #line 625 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 626 "./src/new_cmd.am" s = (code_string_concat(s, "static inline void Console_Write(code_string s) {\n")); #line 627 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " if (!s) ")), "{")), " return; }\n")); #line 628 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " if (!amc_uart_inited) ")), "{")), " amc_uart_init(); }\n")); #line 629 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " for (const char* p = s; *p; p++) ")), "{")), " usart_send_blocking(USART3, (uint8_t)*p); }\n")); #line 630 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 631 "./src/new_cmd.am" s = (code_string_concat(s, "static inline void Console_WriteLine(code_string s) {\n")); #line 632 "./src/new_cmd.am" s = (code_string_concat(s, " Console_Write(s);\n")); #line 633 "./src/new_cmd.am" s = (code_string_concat(s, " usart_send_blocking(USART3, (uint8_t)13);\n")); #line 634 "./src/new_cmd.am" s = (code_string_concat(s, " usart_send_blocking(USART3, (uint8_t)10);\n")); #line 635 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 636 "./src/new_cmd.am" s = (code_string_concat(s, "#endif\n")); #line 637 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_McuReadme(code_string base, code_string board, code_string target, code_bool isQemu) { #line 641 "./src/new_cmd.am" code_string s = ""; #line 642 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "# ")), base)), " — Amalgame on bare metal (")), board)), ")\n\n")); #line 643 "./src/new_cmd.am" if (isQemu) { #line 644 "./src/new_cmd.am" s = (code_string_concat(s, "A blink for the QEMU `lm3s6965evb` (Cortex-M3). No hardware needed.\n\n")); #line 645 "./src/new_cmd.am" s = (code_string_concat(s, "```\namc build --target=cortex-m3 app.am -o firmware\n")); #line 646 "./src/new_cmd.am" s = (code_string_concat(s, "qemu-system-arm -M lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel firmware\n```\n\n")); #line 647 "./src/new_cmd.am" s = (code_string_concat(s, "VS Code: press **F5** (or Ctrl-Shift-B) to build + run in QEMU.\n\n")); #line 648 "./src/new_cmd.am" s = (code_string_concat(s, "The `Amalgame.Mcu` HAL here is the bundled QEMU virtual board (pin ops\n")); #line 649 "./src/new_cmd.am" s = (code_string_concat(s, "logged over semihosting). Re-scaffold with `--board nucleo-f767zi` to\n")); #line 650 "./src/new_cmd.am" s = (code_string_concat(s, "target real STM32 silicon.\n")); } else { #line 652 "./src/new_cmd.am" s = (code_string_concat(s, "A blink for the ST **Nucleo-F767ZI** (Cortex-M7), via libopencm3.\n\n")); #line 653 "./src/new_cmd.am" s = (code_string_concat(s, "## Setup (one-time)\n```\n")); #line 654 "./src/new_cmd.am" s = (code_string_concat(s, "amc mcu setup # installs arm gcc, openocd, gdb-multiarch + builds libopencm3\n")); #line 655 "./src/new_cmd.am" s = (code_string_concat(s, "amc mcu doctor # check what's installed\n```\n")); #line 656 "./src/new_cmd.am" s = (code_string_concat(s, "(amc auto-detects libopencm3 at ~/libopencm3 — no env vars needed.)\n\n")); #line 657 "./src/new_cmd.am" s = (code_string_concat(s, "## Build + flash\n```\n")); #line 658 "./src/new_cmd.am" s = (code_string_concat(s, "amc build --target=cortex-m7 --board=. --flash app.am -o firmware\n```\n\n")); #line 659 "./src/new_cmd.am" s = (code_string_concat(s, "## VS Code (real MCU IDE)\n")); #line 660 "./src/new_cmd.am" s = (code_string_concat(s, "- **Ctrl-Shift-B** = flash to the board (on-board ST-LINK).\n")); #line 661 "./src/new_cmd.am" s = (code_string_concat(s, "- **F5** = build (debug) + flash + breakpoints in your `.am`, on the chip.\n\n")); #line 662 "./src/new_cmd.am" s = (code_string_concat(s, "`amc` preflight-checks each tool and prints what to install if missing.\n")); } #line 664 "./src/new_cmd.am" return s; } static i64 Amalgame_Compiler_NewCommand_WriteVscodeConfig(code_string path, code_string base, code_string template) { #line 679 "./src/new_cmd.am" if (!File_Mkdir(code_string_concat(path, "/.vscode"))) { #line 680 "./src/new_cmd.am" Console_WriteError("amc new: failed to create .vscode/ subdirectory"); #line 681 "./src/new_cmd.am" return 1LL; } #line 683 "./src/new_cmd.am" code_string launchJson = Amalgame_Compiler_NewCommand_VscodeLaunchJson(base); #line 684 "./src/new_cmd.am" code_string settingsJson = Amalgame_Compiler_NewCommand_VscodeSettingsJson(); #line 685 "./src/new_cmd.am" code_string tasksJson = Amalgame_Compiler_NewCommand_VscodeTasksJson(); #line 686 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/.vscode/launch.json"), launchJson)) { return 1LL; } #line 687 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/.vscode/settings.json"), settingsJson)) { return 1LL; } #line 688 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/.vscode/tasks.json"), tasksJson)) { return 1LL; } #line 689 "./src/new_cmd.am" Console_WriteLine(" + .vscode/launch.json + settings.json + tasks.json (F5 rebuilds with -g)"); #line 690 "./src/new_cmd.am" if ((code_string_equals(template, "lib")) || (code_string_equals(template, "test"))) { #line 691 "./src/new_cmd.am" Console_WriteLine(code_string_concat((code_string_concat(" note: '", template)), "' templates have no default runnable binary;")); #line 692 "./src/new_cmd.am" Console_WriteLine(" edit .vscode/launch.json `program` before F5."); } #line 694 "./src/new_cmd.am" return 0LL; } static code_string Amalgame_Compiler_NewCommand_VscodeLaunchJson(code_string base) { #line 710 "./src/new_cmd.am" code_string lb = "{"; #line 711 "./src/new_cmd.am" code_string rb = "}"; #line 712 "./src/new_cmd.am" code_string wsf = code_string_concat((code_string_concat((code_string_concat("$", lb)), "workspaceFolder")), rb); #line 713 "./src/new_cmd.am" code_string s = ""; #line 714 "./src/new_cmd.am" s = (code_string_concat(s, "{\n")); #line 715 "./src/new_cmd.am" s = (code_string_concat(s, " \"version\": \"0.2.0\",\n")); #line 716 "./src/new_cmd.am" s = (code_string_concat(s, " \"configurations\": [\n")); #line 717 "./src/new_cmd.am" s = (code_string_concat(s, " {\n")); #line 718 "./src/new_cmd.am" s = (code_string_concat(s, " \"type\": \"amc\",\n")); #line 719 "./src/new_cmd.am" s = (code_string_concat(s, " \"request\": \"launch\",\n")); #line 720 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " \"name\": \"Debug ")), base)), " (Linux/macOS)\",\n")); #line 721 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, " \"program\": \"")), wsf)), "/")), base)), "\",\n")); #line 722 "./src/new_cmd.am" s = (code_string_concat(s, " \"args\": [],\n")); #line 723 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " \"cwd\": \"")), wsf)), "\",\n")); #line 724 "./src/new_cmd.am" s = (code_string_concat(s, " \"stopOnEntry\": false,\n")); #line 725 "./src/new_cmd.am" s = (code_string_concat(s, " \"preLaunchTask\": \"amc: build (debug)\"\n")); #line 726 "./src/new_cmd.am" s = (code_string_concat(s, " },\n")); #line 727 "./src/new_cmd.am" s = (code_string_concat(s, " {\n")); #line 728 "./src/new_cmd.am" s = (code_string_concat(s, " \"type\": \"amc\",\n")); #line 729 "./src/new_cmd.am" s = (code_string_concat(s, " \"request\": \"launch\",\n")); #line 730 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " \"name\": \"Debug ")), base)), " (Windows)\",\n")); #line 731 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, " \"program\": \"")), wsf)), "/")), base)), ".exe\",\n")); #line 732 "./src/new_cmd.am" s = (code_string_concat(s, " \"args\": [],\n")); #line 733 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " \"cwd\": \"")), wsf)), "\",\n")); #line 734 "./src/new_cmd.am" s = (code_string_concat(s, " \"stopOnEntry\": false,\n")); #line 735 "./src/new_cmd.am" s = (code_string_concat(s, " \"preLaunchTask\": \"amc: build (debug)\"\n")); #line 736 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 737 "./src/new_cmd.am" s = (code_string_concat(s, " ]\n")); #line 738 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 739 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_VscodeSettingsJson() { #line 743 "./src/new_cmd.am" code_string s = ""; #line 744 "./src/new_cmd.am" s = (code_string_concat(s, "{\n")); #line 745 "./src/new_cmd.am" s = (code_string_concat(s, " \"amalgame.enableLsp\": true\n")); #line 746 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 747 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_VscodeTasksJson() { #line 759 "./src/new_cmd.am" code_string s = ""; #line 760 "./src/new_cmd.am" s = (code_string_concat(s, "{\n")); #line 761 "./src/new_cmd.am" s = (code_string_concat(s, " \"version\": \"2.0.0\",\n")); #line 762 "./src/new_cmd.am" s = (code_string_concat(s, " \"tasks\": [\n")); #line 763 "./src/new_cmd.am" s = (code_string_concat(s, " {\n")); #line 764 "./src/new_cmd.am" s = (code_string_concat(s, " \"label\": \"amc: build (debug)\",\n")); #line 765 "./src/new_cmd.am" s = (code_string_concat(s, " \"type\": \"shell\",\n")); #line 766 "./src/new_cmd.am" s = (code_string_concat(s, " \"command\": \"./build.sh\",\n")); #line 767 "./src/new_cmd.am" s = (code_string_concat(s, " \"args\": [\"-g\"],\n")); #line 768 "./src/new_cmd.am" s = (code_string_concat(s, " \"group\": { \"kind\": \"build\", \"isDefault\": true },\n")); #line 769 "./src/new_cmd.am" s = (code_string_concat(s, " \"presentation\": { \"reveal\": \"silent\", \"clear\": true },\n")); #line 770 "./src/new_cmd.am" s = (code_string_concat(s, " \"problemMatcher\": []\n")); #line 771 "./src/new_cmd.am" s = (code_string_concat(s, " },\n")); #line 772 "./src/new_cmd.am" s = (code_string_concat(s, " {\n")); #line 773 "./src/new_cmd.am" s = (code_string_concat(s, " \"label\": \"amc: build (release)\",\n")); #line 774 "./src/new_cmd.am" s = (code_string_concat(s, " \"type\": \"shell\",\n")); #line 775 "./src/new_cmd.am" s = (code_string_concat(s, " \"command\": \"./build.sh\",\n")); #line 776 "./src/new_cmd.am" s = (code_string_concat(s, " \"presentation\": { \"reveal\": \"silent\", \"clear\": true },\n")); #line 777 "./src/new_cmd.am" s = (code_string_concat(s, " \"problemMatcher\": []\n")); #line 778 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 779 "./src/new_cmd.am" s = (code_string_concat(s, " ]\n")); #line 780 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 781 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_MainAmExe(code_string name) { #line 787 "./src/new_cmd.am" code_string s = ""; #line 788 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "namespace ")), Amalgame_Compiler_NewCommand_SanitizeIdent(name))), "\n")); #line 789 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 790 "./src/new_cmd.am" s = (code_string_concat(s, "import Amalgame.Collections\n")); #line 791 "./src/new_cmd.am" s = (code_string_concat(s, "import Amalgame.IO\n")); #line 792 "./src/new_cmd.am" s = (code_string_concat(s, "import Amalgame.String\n")); #line 793 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 794 "./src/new_cmd.am" s = (code_string_concat(s, "public class Program {\n")); #line 795 "./src/new_cmd.am" s = (code_string_concat(s, " public static int Main(List args) {\n")); #line 796 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " Console.WriteLine(\"Hello from ")), name)), "!\")\n")); #line 797 "./src/new_cmd.am" s = (code_string_concat(s, " return 0\n")); #line 798 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 799 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 800 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_TestAmExe(code_string name) { #line 804 "./src/new_cmd.am" code_string s = ""; #line 805 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "// Smoke test for ")), name)), ". `amc test tests/` runs this file\n")); #line 806 "./src/new_cmd.am" s = (code_string_concat(s, "// and counts the [PASS]/[FAIL] tags it prints.\n")); #line 807 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 808 "./src/new_cmd.am" s = (code_string_concat(s, "import Amalgame.IO\n")); #line 809 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 810 "./src/new_cmd.am" s = (code_string_concat(s, "class Program {\n")); #line 811 "./src/new_cmd.am" s = (code_string_concat(s, " public static void Main() {\n")); #line 812 "./src/new_cmd.am" s = (code_string_concat(s, " let n: int = 1 + 1\n")); #line 813 "./src/new_cmd.am" s = (code_string_concat(s, " if (n == 2) {\n")); #line 814 "./src/new_cmd.am" s = (code_string_concat(s, " Console.WriteLine(\"[PASS] sanity\")\n")); #line 815 "./src/new_cmd.am" s = (code_string_concat(s, " } else {\n")); #line 816 "./src/new_cmd.am" s = (code_string_concat(s, " Console.WriteLine(\"[FAIL] sanity\")\n")); #line 817 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 818 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 819 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 820 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_BuildShExe(code_string name) { #line 829 "./src/new_cmd.am" code_string s = ""; #line 830 "./src/new_cmd.am" s = (code_string_concat(s, "#!/bin/bash\n")); #line 831 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# Build script for ")), name)), ". Wraps `amc build`.\n")); #line 832 "./src/new_cmd.am" s = (code_string_concat(s, "#\n")); #line 833 "./src/new_cmd.am" s = (code_string_concat(s, "# Usage:\n")); #line 834 "./src/new_cmd.am" s = (code_string_concat(s, "# ./build.sh # release build (-O2)\n")); #line 835 "./src/new_cmd.am" s = (code_string_concat(s, "# ./build.sh -g # debug build (-O0 -g, for `amc dap`)\n")); #line 836 "./src/new_cmd.am" s = (code_string_concat(s, "# ./build.sh --verbose # show the underlying gcc command\n")); #line 837 "./src/new_cmd.am" s = (code_string_concat(s, "set -e\n")); #line 838 "./src/new_cmd.am" s = (code_string_concat(s, "cd \"$(dirname \"$0\")\"\n")); #line 839 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "amc build src/main.am -o ./")), name)), " \"$@\"\n")); #line 840 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_ReadmeExe(code_string name) { #line 844 "./src/new_cmd.am" code_string s = ""; #line 845 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# ")), name)), "\n")); #line 846 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 847 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "Amalgame project scaffolded by `amc new ")), name)), "`.\n")); #line 848 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 849 "./src/new_cmd.am" s = (code_string_concat(s, "## Build & run\n")); #line 850 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 851 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 852 "./src/new_cmd.am" s = (code_string_concat(s, "./build.sh # release build (-O2)\n")); #line 853 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "./")), name)), "\n")); #line 854 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 855 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 856 "./src/new_cmd.am" s = (code_string_concat(s, "## Debug\n")); #line 857 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 858 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 859 "./src/new_cmd.am" s = (code_string_concat(s, "./build.sh -g # debug build (-O0 -g, DWARF for `amc dap`)\n")); #line 860 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "lldb-18 ./")), name)), " # then `breakpoint set --file src/main.am --line 5` etc.\n")); #line 861 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 862 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 863 "./src/new_cmd.am" s = (code_string_concat(s, "F5 in VS Code rebuilds with `-g` automatically (via the\n")); #line 864 "./src/new_cmd.am" s = (code_string_concat(s, "`preLaunchTask` in `.vscode/launch.json`) and stops on\n")); #line 865 "./src/new_cmd.am" s = (code_string_concat(s, "breakpoints set in `src/main.am` directly. Pass\n")); #line 866 "./src/new_cmd.am" s = (code_string_concat(s, "`--no-vscode` to `amc new` to skip that scaffold.\n")); #line 867 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 868 "./src/new_cmd.am" s = (code_string_concat(s, "## Test\n")); #line 869 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 870 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 871 "./src/new_cmd.am" s = (code_string_concat(s, "amc test tests/\n")); #line 872 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 873 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_LibAm(code_string name) { #line 877 "./src/new_cmd.am" code_string s = ""; #line 878 "./src/new_cmd.am" code_string ident = Amalgame_Compiler_NewCommand_SanitizeIdent(name); #line 879 "./src/new_cmd.am" code_string cls = Amalgame_Compiler_NewCommand_Capitalize(ident); #line 880 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "namespace ")), ident)), "\n")); #line 881 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 882 "./src/new_cmd.am" s = (code_string_concat(s, "import Amalgame.String\n")); #line 883 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 884 "./src/new_cmd.am" s = (code_string_concat(s, "// [Library]\n")); #line 885 "./src/new_cmd.am" s = (code_string_concat(s, "// Marker comment is read by `amc --lib` to skip the missing-Main check.\n")); #line 886 "./src/new_cmd.am" s = (code_string_concat(s, "// See https://github.com/amalgame-lang/Amalgame for the reference.\n")); #line 887 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 888 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "public class ")), cls)), " {\n")); #line 889 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " public ")), cls)), "() {}\n")); #line 890 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 891 "./src/new_cmd.am" s = (code_string_concat(s, " public string Greet(string who) {\n")); #line 892 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " return \"Hello, \" + who + \", from ")), name)), "!\"\n")); #line 893 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 894 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 895 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_BuildShLib(code_string name) { #line 899 "./src/new_cmd.am" code_string s = ""; #line 900 "./src/new_cmd.am" s = (code_string_concat(s, "#!/bin/bash\n")); #line 901 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "# Build script for the ")), name)), " library. Emits ")), name)), ".c\n")); #line 902 "./src/new_cmd.am" s = (code_string_concat(s, "# (a self-contained Amalgame translation) that callers compile\n")); #line 903 "./src/new_cmd.am" s = (code_string_concat(s, "# alongside their own sources via gcc.\n")); #line 904 "./src/new_cmd.am" s = (code_string_concat(s, "set -e\n")); #line 905 "./src/new_cmd.am" s = (code_string_concat(s, "cd \"$(dirname \"$0\")\"\n")); #line 906 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "amc --lib src/")), name)), ".am -o ")), name)), "\n")); #line 907 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "echo \"built ./")), name)), ".c\"\n")); #line 908 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_ReadmeLib(code_string name) { #line 912 "./src/new_cmd.am" code_string s = ""; #line 913 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# ")), name)), "\n")); #line 914 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 915 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "Amalgame library scaffolded by `amc new ")), name)), " --template lib`.\n")); #line 916 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 917 "./src/new_cmd.am" s = (code_string_concat(s, "## Build\n")); #line 918 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 919 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 920 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "./build.sh # produces ./")), name)), ".o\n")); #line 921 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 922 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 923 "./src/new_cmd.am" s = (code_string_concat(s, "## Use from a host binary\n")); #line 924 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 925 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "Compile your host with `amc src/main.am src/")), name)), ".am -o app`,\n")); #line 926 "./src/new_cmd.am" s = (code_string_concat(s, "or pre-build the .o and link it manually with `gcc`.\n")); #line 927 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_TestAmTest(code_string name) { #line 931 "./src/new_cmd.am" code_string s = ""; #line 932 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "// Test bundle for ")), name)), ". Run with `amc test tests/`.\n")); #line 933 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 934 "./src/new_cmd.am" s = (code_string_concat(s, "import Amalgame.IO\n")); #line 935 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 936 "./src/new_cmd.am" s = (code_string_concat(s, "class Program {\n")); #line 937 "./src/new_cmd.am" s = (code_string_concat(s, " public static void Main() {\n")); #line 938 "./src/new_cmd.am" s = (code_string_concat(s, " let n: int = 2 + 3\n")); #line 939 "./src/new_cmd.am" s = (code_string_concat(s, " if (n == 5) {\n")); #line 940 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " Console.WriteLine(\"[PASS] ")), name)), ": baseline\")\n")); #line 941 "./src/new_cmd.am" s = (code_string_concat(s, " } else {\n")); #line 942 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " Console.WriteLine(\"[FAIL] ")), name)), ": baseline\")\n")); #line 943 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 944 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 945 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 946 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_ReadmeTest(code_string name) { #line 950 "./src/new_cmd.am" code_string s = ""; #line 951 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# ")), name)), " — tests\n")); #line 952 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 953 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "Test bundle scaffolded by `amc new ")), name)), " --template test`.\n")); #line 954 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 955 "./src/new_cmd.am" s = (code_string_concat(s, "## Run\n")); #line 956 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 957 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 958 "./src/new_cmd.am" s = (code_string_concat(s, "amc test tests/\n")); #line 959 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 960 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_MainAmService(code_string name) { #line 966 "./src/new_cmd.am" code_string s = ""; #line 967 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "namespace ")), Amalgame_Compiler_NewCommand_SanitizeIdent(name))), "\n")); #line 968 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 969 "./src/new_cmd.am" s = (code_string_concat(s, "import Amalgame.Collections\n")); #line 970 "./src/new_cmd.am" s = (code_string_concat(s, "import Amalgame.IO\n")); #line 971 "./src/new_cmd.am" s = (code_string_concat(s, "import Amalgame.Logging\n")); #line 972 "./src/new_cmd.am" s = (code_string_concat(s, "import Amalgame.Service\n")); #line 973 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 974 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "// ── ")), name)), " — long-running daemon ─────────────────────\n")); #line 975 "./src/new_cmd.am" s = (code_string_concat(s, "//\n")); #line 976 "./src/new_cmd.am" s = (code_string_concat(s, "// Built with `amc new --template service`. The skeleton\n")); #line 977 "./src/new_cmd.am" s = (code_string_concat(s, "// covers the three things every service needs: catch the\n")); #line 978 "./src/new_cmd.am" s = (code_string_concat(s, "// shutdown signal, sleep between iterations without burning\n")); #line 979 "./src/new_cmd.am" s = (code_string_concat(s, "// CPU, and log to a place that survives the process exit.\n")); #line 980 "./src/new_cmd.am" s = (code_string_concat(s, "//\n")); #line 981 "./src/new_cmd.am" s = (code_string_concat(s, "// Replace `OnTick()` with your actual work. The systemd unit\n")); #line 982 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "// (`")), name)), ".service`) runs this with stdout/stderr routed\n")); #line 983 "./src/new_cmd.am" s = (code_string_concat(s, "// to journald; on macOS launchd does the same; on Windows the\n")); #line 984 "./src/new_cmd.am" s = (code_string_concat(s, "// binary is a native service (SCM dispatcher wired in via\n")); #line 985 "./src/new_cmd.am" s = (code_string_concat(s, "// `Service.RunAsService`) registered via `sc.exe create`.\n")); #line 986 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 987 "./src/new_cmd.am" s = (code_string_concat(s, "public class Program {\n")); #line 988 "./src/new_cmd.am" s = (code_string_concat(s, " public static int Main(List args) {\n")); #line 989 "./src/new_cmd.am" s = (code_string_concat(s, " Log.SetMinLevel(\"info\")\n")); #line 990 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " Log.Info(\"")), name)), " starting\")\n")); #line 991 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 992 "./src/new_cmd.am" s = (code_string_concat(s, " // `RunAsService` installs the POSIX signal / Windows\n")); #line 993 "./src/new_cmd.am" s = (code_string_concat(s, " // Ctrl handler AND (on Windows) bootstraps the Service\n")); #line 994 "./src/new_cmd.am" s = (code_string_concat(s, " // Control Manager dispatcher so the same binary runs\n")); #line 995 "./src/new_cmd.am" s = (code_string_concat(s, " // unchanged as a console process and as a registered\n")); #line 996 "./src/new_cmd.am" s = (code_string_concat(s, " // Windows service. The name must match `sc create `.\n")); #line 997 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " Service.RunAsService(\"")), name)), "\")\n")); #line 998 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 999 "./src/new_cmd.am" s = (code_string_concat(s, " var ticks: int = 0\n")); #line 1000 "./src/new_cmd.am" s = (code_string_concat(s, " while (!Service.ShouldStop()) {\n")); #line 1001 "./src/new_cmd.am" s = (code_string_concat(s, " Program.OnTick(ticks)\n")); #line 1002 "./src/new_cmd.am" s = (code_string_concat(s, " ticks = ticks + 1\n")); #line 1003 "./src/new_cmd.am" s = (code_string_concat(s, " Service.Sleep(5000)\n")); #line 1004 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 1005 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1006 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " Log.Info(\"")), name)), " shutting down cleanly\")\n")); #line 1007 "./src/new_cmd.am" s = (code_string_concat(s, " return 0\n")); #line 1008 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 1009 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1010 "./src/new_cmd.am" s = (code_string_concat(s, " // Single iteration of work. Called every 5s by default; tune\n")); #line 1011 "./src/new_cmd.am" s = (code_string_concat(s, " // the Service.Sleep above or drive off events instead.\n")); #line 1012 "./src/new_cmd.am" s = (code_string_concat(s, " private static void OnTick(int n) {\n")); #line 1013 "./src/new_cmd.am" s = (code_string_concat(s, " Log.Info(\"tick \" + String_FromInt(n))\n")); #line 1014 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 1015 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 1016 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_ManifestService(code_string name) { #line 1020 "./src/new_cmd.am" code_string s = ""; #line 1021 "./src/new_cmd.am" s = (code_string_concat(s, "# Project manifest — declares external package deps.\n")); #line 1022 "./src/new_cmd.am" s = (code_string_concat(s, "# `amc package add logging service` populates amalgame.lock\n")); #line 1023 "./src/new_cmd.am" s = (code_string_concat(s, "# and caches the package facades.\n")); #line 1024 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1025 "./src/new_cmd.am" s = (code_string_concat(s, "[package]\n")); #line 1026 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "name = \"")), name)), "\"\n")); #line 1027 "./src/new_cmd.am" s = (code_string_concat(s, "version = \"0.1.0\"\n")); #line 1028 "./src/new_cmd.am" s = (code_string_concat(s, "description = \"Long-running Amalgame service scaffolded by `amc new --template service`.\"\n")); #line 1029 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1030 "./src/new_cmd.am" s = (code_string_concat(s, "[dependencies]\n")); #line 1031 "./src/new_cmd.am" s = (code_string_concat(s, "logging = { git = \"github.com/amalgame-lang/amalgame-logging\", tag = \"v0.1.0\" }\n")); #line 1032 "./src/new_cmd.am" s = (code_string_concat(s, "service = { git = \"github.com/amalgame-lang/amalgame-service\", tag = \"v0.2.0\" }\n")); #line 1033 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_SystemdUnit(code_string name) { #line 1037 "./src/new_cmd.am" code_string s = ""; #line 1038 "./src/new_cmd.am" s = (code_string_concat(s, "[Unit]\n")); #line 1039 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "Description=")), name)), " (Amalgame service)\n")); #line 1040 "./src/new_cmd.am" s = (code_string_concat(s, "After=network.target\n")); #line 1041 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1042 "./src/new_cmd.am" s = (code_string_concat(s, "[Service]\n")); #line 1043 "./src/new_cmd.am" s = (code_string_concat(s, "Type=simple\n")); #line 1044 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "ExecStart=/usr/local/bin/")), name)), "\n")); #line 1045 "./src/new_cmd.am" s = (code_string_concat(s, "Restart=on-failure\n")); #line 1046 "./src/new_cmd.am" s = (code_string_concat(s, "RestartSec=5s\n")); #line 1047 "./src/new_cmd.am" s = (code_string_concat(s, "StandardOutput=journal\n")); #line 1048 "./src/new_cmd.am" s = (code_string_concat(s, "StandardError=journal\n")); #line 1049 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1050 "./src/new_cmd.am" s = (code_string_concat(s, "# Run as a dedicated unprivileged user. Create with:\n")); #line 1051 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# sudo useradd --system --no-create-home --shell /usr/sbin/nologin ")), name)), "\n")); #line 1052 "./src/new_cmd.am" s = (code_string_concat(s, "# Then uncomment the User= line below.\n")); #line 1053 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# User=")), name)), "\n")); #line 1054 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# Group=")), name)), "\n")); #line 1055 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1056 "./src/new_cmd.am" s = (code_string_concat(s, "[Install]\n")); #line 1057 "./src/new_cmd.am" s = (code_string_concat(s, "WantedBy=multi-user.target\n")); #line 1058 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_InstallShService(code_string name) { #line 1062 "./src/new_cmd.am" code_string s = ""; #line 1063 "./src/new_cmd.am" s = (code_string_concat(s, "#!/usr/bin/env bash\n")); #line 1064 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# install.sh — build + install the ")), name)), " daemon under systemd.\n")); #line 1065 "./src/new_cmd.am" s = (code_string_concat(s, "# Re-run after a code change to deploy the new binary; systemctl\n")); #line 1066 "./src/new_cmd.am" s = (code_string_concat(s, "# picks it up on the next restart triggered by the install step.\n")); #line 1067 "./src/new_cmd.am" s = (code_string_concat(s, "set -euo pipefail\n")); #line 1068 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1069 "./src/new_cmd.am" s = (code_string_concat(s, "if [ \"$(id -u)\" -ne 0 ]; then\n")); #line 1070 "./src/new_cmd.am" s = (code_string_concat(s, " echo \"install.sh: must run as root (try: sudo ./install.sh)\" >&2\n")); #line 1071 "./src/new_cmd.am" s = (code_string_concat(s, " exit 1\n")); #line 1072 "./src/new_cmd.am" s = (code_string_concat(s, "fi\n")); #line 1073 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1074 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "echo \"==> Building ")), name)), "\"\n")); #line 1075 "./src/new_cmd.am" s = (code_string_concat(s, "./build.sh\n")); #line 1076 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1077 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "echo \"==> Installing binary to /usr/local/bin/")), name)), "\"\n")); #line 1078 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "install -m 0755 ./")), name)), " /usr/local/bin/")), name)), "\n")); #line 1079 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1080 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "echo \"==> Installing systemd unit to /etc/systemd/system/")), name)), ".service\"\n")); #line 1081 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, "install -m 0644 ./")), name)), ".service /etc/systemd/system/")), name)), ".service\n")); #line 1082 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1083 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"==> Reloading systemd, enabling + (re)starting\"\n")); #line 1084 "./src/new_cmd.am" s = (code_string_concat(s, "systemctl daemon-reload\n")); #line 1085 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "systemctl enable ")), name)), ".service\n")); #line 1086 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "systemctl restart ")), name)), ".service\n")); #line 1087 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1088 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"==> Status\"\n")); #line 1089 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "systemctl --no-pager --full status ")), name)), ".service || true\n")); #line 1090 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1091 "./src/new_cmd.am" s = (code_string_concat(s, "echo\n")); #line 1092 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"Done. Tail the logs with:\"\n")); #line 1093 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "echo \" journalctl -fu ")), name)), "\"\n")); #line 1094 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_PlistMacosService(code_string name) { #line 1109 "./src/new_cmd.am" code_string s = ""; #line 1110 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1111 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1112 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1113 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1114 "./src/new_cmd.am" s = (code_string_concat(s, " Label\n")); #line 1115 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " com.amalgame.")), name)), "\n")); #line 1116 "./src/new_cmd.am" s = (code_string_concat(s, " ProgramArguments\n")); #line 1117 "./src/new_cmd.am" s = (code_string_concat(s, " \n")); #line 1118 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " /usr/local/bin/")), name)), "\n")); #line 1119 "./src/new_cmd.am" s = (code_string_concat(s, " \n")); #line 1120 "./src/new_cmd.am" s = (code_string_concat(s, " RunAtLoad\n")); #line 1121 "./src/new_cmd.am" s = (code_string_concat(s, " \n")); #line 1122 "./src/new_cmd.am" s = (code_string_concat(s, " KeepAlive\n")); #line 1123 "./src/new_cmd.am" s = (code_string_concat(s, " \n")); #line 1124 "./src/new_cmd.am" s = (code_string_concat(s, " ThrottleInterval\n")); #line 1125 "./src/new_cmd.am" s = (code_string_concat(s, " 5\n")); #line 1126 "./src/new_cmd.am" s = (code_string_concat(s, " StandardOutPath\n")); #line 1127 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " /usr/local/var/log/")), name)), ".out.log\n")); #line 1128 "./src/new_cmd.am" s = (code_string_concat(s, " StandardErrorPath\n")); #line 1129 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " /usr/local/var/log/")), name)), ".err.log\n")); #line 1130 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1131 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1132 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_InstallMacosShService(code_string name) { #line 1136 "./src/new_cmd.am" code_string s = ""; #line 1137 "./src/new_cmd.am" s = (code_string_concat(s, "#!/usr/bin/env bash\n")); #line 1138 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# install-macos.sh — build + install the ")), name)), " daemon under launchd.\n")); #line 1139 "./src/new_cmd.am" s = (code_string_concat(s, "# Re-run after a code change to deploy the new binary; launchd\n")); #line 1140 "./src/new_cmd.am" s = (code_string_concat(s, "# picks it up on the next bootstrap triggered by the install step.\n")); #line 1141 "./src/new_cmd.am" s = (code_string_concat(s, "set -euo pipefail\n")); #line 1142 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1143 "./src/new_cmd.am" s = (code_string_concat(s, "if [ \"$(id -u)\" -ne 0 ]; then\n")); #line 1144 "./src/new_cmd.am" s = (code_string_concat(s, " echo \"install-macos.sh: must run as root (try: sudo ./install-macos.sh)\" >&2\n")); #line 1145 "./src/new_cmd.am" s = (code_string_concat(s, " exit 1\n")); #line 1146 "./src/new_cmd.am" s = (code_string_concat(s, "fi\n")); #line 1147 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1153 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "NAME=\"")), name)), "\"\n")); #line 1154 "./src/new_cmd.am" s = (code_string_concat(s, "LABEL=\"com.amalgame.$NAME\"\n")); #line 1155 "./src/new_cmd.am" s = (code_string_concat(s, "PLIST=\"/Library/LaunchDaemons/$LABEL.plist\"\n")); #line 1156 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1157 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"==> Building $NAME\"\n")); #line 1158 "./src/new_cmd.am" s = (code_string_concat(s, "./build.sh\n")); #line 1159 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1160 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"==> Installing binary to /usr/local/bin/$NAME\"\n")); #line 1161 "./src/new_cmd.am" s = (code_string_concat(s, "install -m 0755 ./\"$NAME\" /usr/local/bin/\"$NAME\"\n")); #line 1162 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1163 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"==> Ensuring /usr/local/var/log exists\"\n")); #line 1164 "./src/new_cmd.am" s = (code_string_concat(s, "install -d -m 0755 /usr/local/var/log\n")); #line 1165 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1166 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"==> Installing launchd plist to $PLIST\"\n")); #line 1167 "./src/new_cmd.am" s = (code_string_concat(s, "install -m 0644 ./\"$LABEL.plist\" \"$PLIST\"\n")); #line 1168 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1169 "./src/new_cmd.am" s = (code_string_concat(s, "# Unload any prior registration so we cleanly replace it.\n")); #line 1170 "./src/new_cmd.am" s = (code_string_concat(s, "# `bootout` exits non-zero when the service is absent — ignore.\n")); #line 1171 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"==> Unloading previous registration (if any)\"\n")); #line 1172 "./src/new_cmd.am" s = (code_string_concat(s, "launchctl bootout system/\"$LABEL\" 2>/dev/null || true\n")); #line 1173 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1174 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"==> Bootstrapping $LABEL into launchd (system domain)\"\n")); #line 1175 "./src/new_cmd.am" s = (code_string_concat(s, "launchctl bootstrap system \"$PLIST\"\n")); #line 1176 "./src/new_cmd.am" s = (code_string_concat(s, "launchctl enable system/\"$LABEL\"\n")); #line 1177 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1178 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"==> Status\"\n")); #line 1179 "./src/new_cmd.am" s = (code_string_concat(s, "launchctl print system/\"$LABEL\" 2>/dev/null | grep -E 'state|pid' || true\n")); #line 1180 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1181 "./src/new_cmd.am" s = (code_string_concat(s, "echo\n")); #line 1182 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"Done. Tail the logs with:\"\n")); #line 1183 "./src/new_cmd.am" s = (code_string_concat(s, "echo \" tail -f /usr/local/var/log/$NAME.err.log\"\n")); #line 1184 "./src/new_cmd.am" s = (code_string_concat(s, "echo \" tail -f /usr/local/var/log/$NAME.out.log\"\n")); #line 1185 "./src/new_cmd.am" s = (code_string_concat(s, "echo\n")); #line 1186 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"Operate the service via standard launchctl tooling:\"\n")); #line 1187 "./src/new_cmd.am" s = (code_string_concat(s, "echo \" sudo launchctl kickstart -k system/$LABEL # restart\"\n")); #line 1188 "./src/new_cmd.am" s = (code_string_concat(s, "echo \" sudo launchctl bootout system/$LABEL # unload (uninstall)\"\n")); #line 1189 "./src/new_cmd.am" s = (code_string_concat(s, "echo \" launchctl print system/$LABEL # detailed state\"\n")); #line 1190 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_BuildShService(code_string name) { #line 1198 "./src/new_cmd.am" code_string s = ""; #line 1199 "./src/new_cmd.am" s = (code_string_concat(s, "#!/usr/bin/env bash\n")); #line 1200 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# build.sh — compile ")), name)), " via `amc build`.\n")); #line 1201 "./src/new_cmd.am" s = (code_string_concat(s, "#\n")); #line 1202 "./src/new_cmd.am" s = (code_string_concat(s, "# Usage:\n")); #line 1203 "./src/new_cmd.am" s = (code_string_concat(s, "# ./build.sh # release build (-O2)\n")); #line 1204 "./src/new_cmd.am" s = (code_string_concat(s, "# ./build.sh -g # debug build (-O0 -g, for `amc dap`)\n")); #line 1205 "./src/new_cmd.am" s = (code_string_concat(s, "set -euo pipefail\n")); #line 1206 "./src/new_cmd.am" s = (code_string_concat(s, "cd \"$(dirname \"$0\")\"\n")); #line 1207 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "amc build src/main.am -o ./")), name)), " \"$@\"\n")); #line 1208 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_BuildPs1Service(code_string name) { #line 1218 "./src/new_cmd.am" code_string s = ""; #line 1219 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# build.ps1 — compile ")), name)), " on Windows via `amc build`.\n")); #line 1220 "./src/new_cmd.am" s = (code_string_concat(s, "#\n")); #line 1221 "./src/new_cmd.am" s = (code_string_concat(s, "# Run from a PowerShell where `amc.exe` and a MinGW `gcc.exe`\n")); #line 1222 "./src/new_cmd.am" s = (code_string_concat(s, "# are on PATH. MSYS2 mingw64 installs both with:\n")); #line 1223 "./src/new_cmd.am" s = (code_string_concat(s, "# pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-gc mingw-w64-x86_64-curl\n")); #line 1224 "./src/new_cmd.am" s = (code_string_concat(s, "#\n")); #line 1225 "./src/new_cmd.am" s = (code_string_concat(s, "# Pass -g (or any flag) and it forwards to `amc build` for a\n")); #line 1226 "./src/new_cmd.am" s = (code_string_concat(s, "# debug DWARF build that pairs with `amc dap` under VS Code.\n")); #line 1227 "./src/new_cmd.am" s = (code_string_concat(s, "$ErrorActionPreference = 'Stop'\n")); #line 1228 "./src/new_cmd.am" s = (code_string_concat(s, "Set-Location $PSScriptRoot\n")); #line 1229 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "& amc build src/main.am -o ./")), name)), ".exe @args\n")); #line 1230 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_InstallPs1Service(code_string name) { #line 1247 "./src/new_cmd.am" code_string s = ""; #line 1248 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# install.ps1 — register ")), name)), " as a native Windows service.\n")); #line 1249 "./src/new_cmd.am" s = (code_string_concat(s, "#\n")); #line 1250 "./src/new_cmd.am" s = (code_string_concat(s, "# Uses the built-in `sc.exe` (no NSSM, no external download).\n")); #line 1251 "./src/new_cmd.am" s = (code_string_concat(s, "# The binary is a native service: its `Service.RunAsService`\n")); #line 1252 "./src/new_cmd.am" s = (code_string_concat(s, "# call (from amalgame-service v0.2.0+) bootstraps the Windows\n")); #line 1253 "./src/new_cmd.am" s = (code_string_concat(s, "# SCM dispatcher on a worker thread at startup.\n")); #line 1254 "./src/new_cmd.am" s = (code_string_concat(s, "#\n")); #line 1255 "./src/new_cmd.am" s = (code_string_concat(s, "# Run from an elevated PowerShell:\n")); #line 1256 "./src/new_cmd.am" s = (code_string_concat(s, "# Start-Process powershell -Verb runAs -ArgumentList '-File','install.ps1'\n")); #line 1257 "./src/new_cmd.am" s = (code_string_concat(s, "$ErrorActionPreference = 'Stop'\n")); #line 1258 "./src/new_cmd.am" s = (code_string_concat(s, "Set-Location $PSScriptRoot\n")); #line 1259 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1260 "./src/new_cmd.am" s = (code_string_concat(s, "# Elevation check — `sc create` needs admin.\n")); #line 1261 "./src/new_cmd.am" s = (code_string_concat(s, "$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()\n")); #line 1262 "./src/new_cmd.am" s = (code_string_concat(s, "$principal = New-Object System.Security.Principal.WindowsPrincipal($identity)\n")); #line 1263 "./src/new_cmd.am" s = (code_string_concat(s, "if (-not $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) {\n")); #line 1264 "./src/new_cmd.am" s = (code_string_concat(s, " Write-Error 'install.ps1 must run as Administrator.'\n")); #line 1265 "./src/new_cmd.am" s = (code_string_concat(s, " exit 1\n")); #line 1266 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 1267 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1268 "./src/new_cmd.am" s = (code_string_concat(s, "# Build the binary if missing.\n")); #line 1269 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "$exe = Join-Path $PSScriptRoot '")), name)), ".exe'\n")); #line 1270 "./src/new_cmd.am" s = (code_string_concat(s, "if (-not (Test-Path $exe)) { & .\\build.ps1 }\n")); #line 1271 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1272 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "$svc = '")), name)), "'\n")); #line 1273 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "$display = '")), name)), " (Amalgame service)'\n")); #line 1274 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1275 "./src/new_cmd.am" s = (code_string_concat(s, "# Stop + delete any prior registration so we cleanly replace it.\n")); #line 1276 "./src/new_cmd.am" s = (code_string_concat(s, "# `sc query` exit code 1060 means \"service does not exist\".\n")); #line 1277 "./src/new_cmd.am" s = (code_string_concat(s, "& sc.exe query $svc *> $null\n")); #line 1278 "./src/new_cmd.am" s = (code_string_concat(s, "if ($LASTEXITCODE -eq 0) {\n")); #line 1279 "./src/new_cmd.am" s = (code_string_concat(s, " Write-Host \"==> Stopping existing service '$svc'\"\n")); #line 1280 "./src/new_cmd.am" s = (code_string_concat(s, " & sc.exe stop $svc *> $null\n")); #line 1281 "./src/new_cmd.am" s = (code_string_concat(s, " Start-Sleep -Seconds 1\n")); #line 1282 "./src/new_cmd.am" s = (code_string_concat(s, " Write-Host \"==> Deleting existing service '$svc'\"\n")); #line 1283 "./src/new_cmd.am" s = (code_string_concat(s, " & sc.exe delete $svc *> $null\n")); #line 1284 "./src/new_cmd.am" s = (code_string_concat(s, " Start-Sleep -Seconds 1\n")); #line 1285 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 1286 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1287 "./src/new_cmd.am" s = (code_string_concat(s, "# Register the binary as an auto-start service. `binPath=` MUST\n")); #line 1288 "./src/new_cmd.am" s = (code_string_concat(s, "# have a space after the equals sign (sc.exe quirk).\n")); #line 1289 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host \"==> Registering '$svc' (binPath=$exe)\"\n")); #line 1290 "./src/new_cmd.am" s = (code_string_concat(s, "& sc.exe create $svc binPath= \"`\"$exe`\"\" start= auto DisplayName= $display\n")); #line 1291 "./src/new_cmd.am" s = (code_string_concat(s, "if ($LASTEXITCODE -ne 0) { throw \"sc create failed (exit=$LASTEXITCODE)\" }\n")); #line 1292 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1293 "./src/new_cmd.am" s = (code_string_concat(s, "# Optional: restart on failure (1st/2nd/3rd retry @ 5s, reset counter @ 1h).\n")); #line 1294 "./src/new_cmd.am" s = (code_string_concat(s, "& sc.exe failure $svc reset= 3600 actions= restart/5000/restart/5000/restart/5000 *> $null\n")); #line 1295 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1296 "./src/new_cmd.am" s = (code_string_concat(s, "# Start.\n")); #line 1297 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host \"==> Starting '$svc'\"\n")); #line 1298 "./src/new_cmd.am" s = (code_string_concat(s, "& sc.exe start $svc\n")); #line 1299 "./src/new_cmd.am" s = (code_string_concat(s, "if ($LASTEXITCODE -ne 0) { throw \"sc start failed (exit=$LASTEXITCODE)\" }\n")); #line 1300 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1301 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host ''\n")); #line 1302 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host \"Done. Service '$svc' registered + started.\"\n")); #line 1303 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host ' Status (sc query):'\n")); #line 1304 "./src/new_cmd.am" s = (code_string_concat(s, "& sc.exe query $svc\n")); #line 1305 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host ''\n")); #line 1306 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host 'Operate the service via standard tooling:'\n")); #line 1307 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host \" sc.exe query $svc\"\n")); #line 1308 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host \" sc.exe stop $svc\"\n")); #line 1309 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host \" sc.exe start $svc\"\n")); #line 1310 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host \" sc.exe delete $svc # remove (after stop)\"\n")); #line 1311 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host \" Get-Service $svc # PowerShell view\"\n")); #line 1312 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host ''\n")); #line 1313 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host 'Logs: this template writes to stderr only. To capture them,'\n")); #line 1314 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host 'either redirect inside Main() (Amalgame.Logging.SetFile)'\n")); #line 1315 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host 'or wrap stdout/stderr via a shim. Native Windows event-log'\n")); #line 1316 "./src/new_cmd.am" s = (code_string_concat(s, "Write-Host 'integration is on the amalgame-service roadmap.'\n")); #line 1317 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_ReadmeService(code_string name) { #line 1322 "./src/new_cmd.am" code_string s = ""; #line 1323 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# ")), name)), "\n")); #line 1324 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1325 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "A long-running Amalgame daemon scaffolded by `amc new ")), name)), " --template service`.\n")); #line 1326 "./src/new_cmd.am" s = (code_string_concat(s, "Uses `Amalgame.Service` for signal-aware shutdown and `Amalgame.Logging` for stderr / journal output.\n")); #line 1327 "./src/new_cmd.am" s = (code_string_concat(s, "Both are external packages — install them once with:\n")); #line 1328 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1329 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1330 "./src/new_cmd.am" s = (code_string_concat(s, "amc package add logging service\n")); #line 1331 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1332 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1333 "./src/new_cmd.am" s = (code_string_concat(s, "(They're already declared in `amalgame.toml`; `add` fetches + locks them.)\n")); #line 1334 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1335 "./src/new_cmd.am" s = (code_string_concat(s, "## Run in the foreground (any OS)\n")); #line 1336 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1337 "./src/new_cmd.am" s = (code_string_concat(s, "Build, then run the binary directly. Logs go to stderr in human-readable form.\n")); #line 1338 "./src/new_cmd.am" s = (code_string_concat(s, "Hit `Ctrl-C` for clean shutdown.\n")); #line 1339 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1340 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "- **Linux / macOS:** `./build.sh && ./")), name)), "`\n")); #line 1341 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "- **Windows:** `.\\build.ps1 ; .\\")), name)), ".exe`\n")); #line 1342 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1343 "./src/new_cmd.am" s = (code_string_concat(s, "## Debug (any OS)\n")); #line 1344 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1345 "./src/new_cmd.am" s = (code_string_concat(s, "Add `-g` (or any flag) to forward `-O0 -g` to `amc build`. The\n")); #line 1346 "./src/new_cmd.am" s = (code_string_concat(s, "cgen emits `#line` directives so debuggers stop on `.am` source\n")); #line 1347 "./src/new_cmd.am" s = (code_string_concat(s, "lines directly — no source maps needed.\n")); #line 1348 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1349 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "- **Linux / macOS:** `./build.sh -g` then `lldb-18 ./")), name)), "`\n")); #line 1350 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "- **Windows:** `.\\build.ps1 -g` then `gdb ./")), name)), ".exe`\n")); #line 1351 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1352 "./src/new_cmd.am" s = (code_string_concat(s, "F5 in VS Code rebuilds with `-g` automatically (via the\n")); #line 1353 "./src/new_cmd.am" s = (code_string_concat(s, "`preLaunchTask`) and stops on breakpoints set in `src/main.am`.\n")); #line 1354 "./src/new_cmd.am" s = (code_string_concat(s, "Pass `--no-vscode` to `amc new` to skip that scaffold.\n")); #line 1355 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1356 "./src/new_cmd.am" s = (code_string_concat(s, "## Linux — install under systemd\n")); #line 1357 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1358 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1359 "./src/new_cmd.am" s = (code_string_concat(s, "sudo ./install.sh\n")); #line 1360 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1361 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1362 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "Installs the binary to `/usr/local/bin/")), name)), "`, drops the unit at\n")); #line 1363 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "`/etc/systemd/system/")), name)), ".service`, reloads systemd, and enables\n")); #line 1364 "./src/new_cmd.am" s = (code_string_concat(s, "+ starts the service. Re-run after each code change to deploy.\n")); #line 1365 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1366 "./src/new_cmd.am" s = (code_string_concat(s, "Inspect status / tail logs:\n")); #line 1367 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1368 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1369 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "systemctl status ")), name)), "\n")); #line 1370 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "journalctl -fu ")), name)), "\n")); #line 1371 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1372 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1373 "./src/new_cmd.am" s = (code_string_concat(s, "## Windows — install as a native service (via sc.exe)\n")); #line 1374 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1375 "./src/new_cmd.am" s = (code_string_concat(s, "```powershell\n")); #line 1376 "./src/new_cmd.am" s = (code_string_concat(s, "# elevated PowerShell\n")); #line 1377 "./src/new_cmd.am" s = (code_string_concat(s, "Start-Process powershell -Verb runAs -ArgumentList '-File','install.ps1'\n")); #line 1378 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1379 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1380 "./src/new_cmd.am" s = (code_string_concat(s, "`install.ps1` builds the binary if needed, then registers it as\n")); #line 1381 "./src/new_cmd.am" s = (code_string_concat(s, "a native auto-start Windows service via the built-in `sc.exe`.\n")); #line 1382 "./src/new_cmd.am" s = (code_string_concat(s, "**No NSSM** or other external wrapper is involved — the binary\n")); #line 1383 "./src/new_cmd.am" s = (code_string_concat(s, "wires up the Windows Service Control Manager dispatcher itself\n")); #line 1384 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "through `Service.RunAsService(\"")), name)), "\")` (from\n")); #line 1385 "./src/new_cmd.am" s = (code_string_concat(s, "`amalgame-service` v0.2.0+).\n")); #line 1386 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1387 "./src/new_cmd.am" s = (code_string_concat(s, "Operate the service via standard Windows tooling:\n")); #line 1388 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1389 "./src/new_cmd.am" s = (code_string_concat(s, "```powershell\n")); #line 1390 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "sc.exe query ")), name)), "\n")); #line 1391 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "sc.exe stop ")), name)), "\n")); #line 1392 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "sc.exe start ")), name)), "\n")); #line 1393 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "sc.exe delete ")), name)), "\n")); #line 1394 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "Get-Service ")), name)), "\n")); #line 1395 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1396 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1397 "./src/new_cmd.am" s = (code_string_concat(s, "The exact same binary keeps working when launched directly from a\n")); #line 1398 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "console (`.\\")), name)), ".exe`) — `StartServiceCtrlDispatcher` returns\n")); #line 1399 "./src/new_cmd.am" s = (code_string_concat(s, "immediately with `ERROR_FAILED_SERVICE_CONTROLLER_CONNECT` and the\n")); #line 1400 "./src/new_cmd.am" s = (code_string_concat(s, "binary falls through to the same `while (!ShouldStop)` loop, with\n")); #line 1401 "./src/new_cmd.am" s = (code_string_concat(s, "`Ctrl+C` triggering clean shutdown via the console Ctrl handler.\n")); #line 1402 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1403 "./src/new_cmd.am" s = (code_string_concat(s, "## macOS — install under launchd\n")); #line 1404 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1405 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1406 "./src/new_cmd.am" s = (code_string_concat(s, "sudo ./install-macos.sh\n")); #line 1407 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1408 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1409 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "Installs the binary to `/usr/local/bin/")), name)), "`, drops the plist at\n")); #line 1410 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "`/Library/LaunchDaemons/com.amalgame.")), name)), ".plist`, ensures\n")); #line 1411 "./src/new_cmd.am" s = (code_string_concat(s, "`/usr/local/var/log` exists, then `launchctl bootstrap`s the\n")); #line 1412 "./src/new_cmd.am" s = (code_string_concat(s, "LaunchDaemon into the system domain so it survives logout and starts\n")); #line 1413 "./src/new_cmd.am" s = (code_string_concat(s, "at boot. Re-run after each code change to deploy.\n")); #line 1414 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1415 "./src/new_cmd.am" s = (code_string_concat(s, "Inspect status / tail logs:\n")); #line 1416 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1417 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1418 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "launchctl print system/com.amalgame.")), name)), "\n")); #line 1419 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "tail -f /usr/local/var/log/")), name)), ".err.log\n")); #line 1420 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "tail -f /usr/local/var/log/")), name)), ".out.log\n")); #line 1421 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1422 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1423 "./src/new_cmd.am" s = (code_string_concat(s, "Operate the service:\n")); #line 1424 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1425 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1426 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "sudo launchctl kickstart -k system/com.amalgame.")), name)), " # restart\n")); #line 1427 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "sudo launchctl bootout system/com.amalgame.")), name)), " # uninstall\n")); #line 1428 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1429 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1430 "./src/new_cmd.am" s = (code_string_concat(s, "## Project layout\n")); #line 1431 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1432 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1433 "./src/new_cmd.am" s = (code_string_concat((code_string_concat(s, name)), "/\n")); #line 1434 "./src/new_cmd.am" s = (code_string_concat(s, "├── amalgame.toml # project manifest — declares logging + service deps\n")); #line 1435 "./src/new_cmd.am" s = (code_string_concat(s, "├── src/main.am # daemon entry point — edit OnTick() here\n")); #line 1436 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "├── ")), name)), ".service # systemd unit (Linux)\n")); #line 1437 "./src/new_cmd.am" s = (code_string_concat(s, "├── install.sh # build + deploy under systemd (Linux)\n")); #line 1438 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "├── com.amalgame.")), name)), ".plist # launchd LaunchDaemon (macOS)\n")); #line 1439 "./src/new_cmd.am" s = (code_string_concat(s, "├── install-macos.sh # build + deploy under launchd (macOS)\n")); #line 1440 "./src/new_cmd.am" s = (code_string_concat(s, "├── install.ps1 # native Windows service install (sc.exe)\n")); #line 1441 "./src/new_cmd.am" s = (code_string_concat(s, "├── build.sh # POSIX compile: amc + gcc\n")); #line 1442 "./src/new_cmd.am" s = (code_string_concat(s, "├── build.ps1 # Windows compile: amc + MinGW gcc\n")); #line 1443 "./src/new_cmd.am" s = (code_string_concat(s, "├── .gitignore\n")); #line 1444 "./src/new_cmd.am" s = (code_string_concat(s, "└── README.md\n")); #line 1445 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1446 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_GitignoreCommon() { #line 1450 "./src/new_cmd.am" code_string s = ""; #line 1451 "./src/new_cmd.am" s = (code_string_concat(s, "# Build artifacts\n")); #line 1452 "./src/new_cmd.am" s = (code_string_concat(s, "*.o\n")); #line 1453 "./src/new_cmd.am" s = (code_string_concat(s, "*.c.bundle\n")); #line 1454 "./src/new_cmd.am" s = (code_string_concat(s, "a.out\n")); #line 1455 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1456 "./src/new_cmd.am" s = (code_string_concat(s, "# Editor state\n")); #line 1457 "./src/new_cmd.am" s = (code_string_concat(s, "# .vscode/ is scaffolded by `amc new` and meant to be committed\n")); #line 1458 "./src/new_cmd.am" s = (code_string_concat(s, "# (project-shared launch.json / tasks.json). Add it here if you\n")); #line 1459 "./src/new_cmd.am" s = (code_string_concat(s, "# prefer to keep it local-only.\n")); #line 1460 "./src/new_cmd.am" s = (code_string_concat(s, ".idea/\n")); #line 1461 "./src/new_cmd.am" s = (code_string_concat(s, "*.swp\n")); #line 1462 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_GitignoreService(code_string name) { #line 1469 "./src/new_cmd.am" code_string s = Amalgame_Compiler_NewCommand_GitignoreCommon(); #line 1470 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1471 "./src/new_cmd.am" s = (code_string_concat(s, "# Service template artifacts\n")); #line 1472 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "/")), name)), "\n")); #line 1473 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "/")), name)), ".exe\n")); #line 1474 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "/")), name)), ".c\n")); #line 1475 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "/")), name)), ".out.log\n")); #line 1476 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "/")), name)), ".err.log\n")); #line 1477 "./src/new_cmd.am" s = (code_string_concat(s, "/nssm.exe\n")); #line 1478 "./src/new_cmd.am" return s; } static code_bool Amalgame_Compiler_NewCommand_WriteFile(code_string path, code_string content) { #line 1484 "./src/new_cmd.am" code_bool ok = File_WriteAll(path, content); #line 1485 "./src/new_cmd.am" if (!ok) { #line 1486 "./src/new_cmd.am" Console_WriteError(code_string_concat((code_string_concat("amc new: failed to write '", path)), "'")); #line 1487 "./src/new_cmd.am" return 0; } #line 1489 "./src/new_cmd.am" return 1; } static code_string Amalgame_Compiler_NewCommand_ShellEscape(code_string s) { #line 1497 "./src/new_cmd.am" i64 n = String_Length(s); #line 1498 "./src/new_cmd.am" code_string out = "'"; #line 1499 "./src/new_cmd.am" for (i64 i = 0LL; i < n; i++) { #line 1500 "./src/new_cmd.am" code_string c = String_CharAt1(s, i); #line 1501 "./src/new_cmd.am" if (code_string_equals(c, "'")) { #line 1502 "./src/new_cmd.am" out = (code_string_concat(out, "'\\''")); } else { #line 1504 "./src/new_cmd.am" out = (code_string_concat(out, c)); } } #line 1507 "./src/new_cmd.am" out = (code_string_concat(out, "'")); #line 1508 "./src/new_cmd.am" return out; } static code_bool Amalgame_Compiler_NewCommand_IsSafeName(code_string s) { #line 1512 "./src/new_cmd.am" i64 n = String_Length(s); #line 1513 "./src/new_cmd.am" if (n == 0LL) { return 0; } #line 1514 "./src/new_cmd.am" code_string allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"; #line 1515 "./src/new_cmd.am" for (i64 i = 0LL; i < n; i++) { #line 1516 "./src/new_cmd.am" code_string c = String_CharAt1(s, i); #line 1517 "./src/new_cmd.am" if (String_IndexOf(allowed, c) < 0LL) { return 0; } } #line 1522 "./src/new_cmd.am" if (String_StartsWith(s, "-")) { return 0; } #line 1523 "./src/new_cmd.am" return 1; } static code_string Amalgame_Compiler_NewCommand_Capitalize(code_string s) { #line 1527 "./src/new_cmd.am" if (String_Length(s) == 0LL) { return s; } #line 1528 "./src/new_cmd.am" code_string head = String_Substring(s, 0LL, 1LL); #line 1529 "./src/new_cmd.am" code_string tail = String_Substring(s, 1LL, String_Length(s) - 1LL); #line 1530 "./src/new_cmd.am" return code_string_concat(String_ToUpper(head), tail); } static code_string Amalgame_Compiler_NewCommand_SanitizeIdent(code_string s) { #line 1544 "./src/new_cmd.am" code_string out = ""; #line 1545 "./src/new_cmd.am" i64 n = String_Length(s); #line 1546 "./src/new_cmd.am" code_string alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; #line 1547 "./src/new_cmd.am" code_string digit = "0123456789"; #line 1548 "./src/new_cmd.am" for (i64 i = 0LL; i < n; i++) { #line 1549 "./src/new_cmd.am" code_string c = String_Substring(s, i, 1LL); #line 1550 "./src/new_cmd.am" code_bool isAlpha = String_IndexOf(alpha, c) >= 0LL; #line 1551 "./src/new_cmd.am" code_bool isDigit = String_IndexOf(digit, c) >= 0LL; #line 1552 "./src/new_cmd.am" if ((isAlpha || isDigit) || (code_string_equals(c, "_"))) { out = (code_string_concat(out, c)); } else { #line 1553 "./src/new_cmd.am" out = (code_string_concat(out, "_")); } } #line 1555 "./src/new_cmd.am" if (String_Length(out) == 0LL) { return "Project"; } #line 1556 "./src/new_cmd.am" code_string first = String_Substring(out, 0LL, 1LL); #line 1557 "./src/new_cmd.am" if (String_IndexOf(digit, first) >= 0LL) { #line 1558 "./src/new_cmd.am" return code_string_concat("_", out); } #line 1560 "./src/new_cmd.am" return out; } static code_string Amalgame_Compiler_NewCommand_Basename(code_string p) { #line 1568 "./src/new_cmd.am" i64 n = String_Length(p); #line 1569 "./src/new_cmd.am" if (n == 0LL) { return p; } #line 1570 "./src/new_cmd.am" i64 i = n - 1LL; #line 1571 "./src/new_cmd.am" while (i >= 0LL) { #line 1572 "./src/new_cmd.am" code_string c = String_Substring(p, i, 1LL); #line 1573 "./src/new_cmd.am" if (code_string_equals(c, "/")) { #line 1574 "./src/new_cmd.am" return String_Substring(p, i + 1LL, (n - i) - 1LL); } #line 1576 "./src/new_cmd.am" i = (i - 1LL); } #line 1578 "./src/new_cmd.am" return p; } static code_string Amalgame_Compiler_NewCommand_MainAmForms(code_string name) { #line 1584 "./src/new_cmd.am" code_string s = ""; #line 1585 "./src/new_cmd.am" s = (code_string_concat(s, "import Amalgame.UI.Forms\n")); #line 1586 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1587 "./src/new_cmd.am" s = (code_string_concat(s, "// Scaffolded by `amc new --template forms`.\n")); #line 1588 "./src/new_cmd.am" s = (code_string_concat(s, "// A 320x240 window with a Label + Button arranged via\n")); #line 1589 "./src/new_cmd.am" s = (code_string_concat(s, "// StackVertical. Application.Run handles the SDL event\n")); #line 1590 "./src/new_cmd.am" s = (code_string_concat(s, "// loop, renders each frame, returns when the window's\n")); #line 1591 "./src/new_cmd.am" s = (code_string_concat(s, "// close button is hit.\n")); #line 1592 "./src/new_cmd.am" s = (code_string_concat(s, "//\n")); #line 1593 "./src/new_cmd.am" s = (code_string_concat(s, "// Theme.FromOS picks Light or Dark automatically based\n")); #line 1594 "./src/new_cmd.am" s = (code_string_concat(s, "// on the host appearance setting (macOS / Windows /\n")); #line 1595 "./src/new_cmd.am" s = (code_string_concat(s, "// gsettings on Linux).\n")); #line 1596 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1597 "./src/new_cmd.am" s = (code_string_concat(s, "class Program {\n")); #line 1598 "./src/new_cmd.am" s = (code_string_concat(s, " public static void Main() {\n")); #line 1599 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, " let form: Form = new Form(\"")), name)), "\", 320, 240)\n")); #line 1600 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1601 "./src/new_cmd.am" s = (code_string_concat(s, " let title: Widget = Widget.Label(\"Hello from Amalgame!\", 0, 0, 0, 0)\n")); #line 1602 "./src/new_cmd.am" s = (code_string_concat(s, " let confirm: Widget = Widget.Button(\"OK\", 0, 0, 0, 0)\n")); #line 1603 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1604 "./src/new_cmd.am" s = (code_string_concat(s, " form.Add(title)\n")); #line 1605 "./src/new_cmd.am" s = (code_string_concat(s, " form.Add(confirm)\n")); #line 1606 "./src/new_cmd.am" s = (code_string_concat(s, " form.SetLayout(Layout.StackVertical(10, 10))\n")); #line 1607 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1608 "./src/new_cmd.am" s = (code_string_concat(s, " Application.Run(form)\n")); #line 1609 "./src/new_cmd.am" s = (code_string_concat(s, " }\n")); #line 1610 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 1611 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_ManifestForms(code_string name) { #line 1615 "./src/new_cmd.am" code_string s = ""; #line 1616 "./src/new_cmd.am" s = (code_string_concat(s, "# Project manifest — declares external package deps.\n")); #line 1617 "./src/new_cmd.am" s = (code_string_concat(s, "# Run `amc package add ui-sdl ui-forms` once to populate\n")); #line 1618 "./src/new_cmd.am" s = (code_string_concat(s, "# amalgame.lock and cache the package facades, then\n")); #line 1619 "./src/new_cmd.am" s = (code_string_concat(s, "# `./build.sh` to compile + link against SDL2.\n")); #line 1620 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1621 "./src/new_cmd.am" s = (code_string_concat(s, "[package]\n")); #line 1622 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "name = \"")), name)), "\"\n")); #line 1623 "./src/new_cmd.am" s = (code_string_concat(s, "version = \"0.1.0\"\n")); #line 1624 "./src/new_cmd.am" s = (code_string_concat(s, "description = \"Amalgame GUI app scaffolded by `amc new --template forms`.\"\n")); #line 1625 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1626 "./src/new_cmd.am" s = (code_string_concat(s, "[dependencies]\n")); #line 1627 "./src/new_cmd.am" s = (code_string_concat(s, "ui-sdl = { git = \"github.com/amalgame-lang/amalgame-ui-sdl\", tag = \"v0.1.0\" }\n")); #line 1628 "./src/new_cmd.am" s = (code_string_concat(s, "ui-forms = { git = \"github.com/amalgame-lang/amalgame-ui-forms\", tag = \"v0.1.1\" }\n")); #line 1629 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_BuildShForms(code_string name) { #line 1636 "./src/new_cmd.am" code_string lb = "{"; #line 1637 "./src/new_cmd.am" code_string rb = "}"; #line 1638 "./src/new_cmd.am" code_string amcVar = code_string_concat((code_string_concat((code_string_concat("$", lb)), "AMC:-$(command -v amc)")), rb); #line 1639 "./src/new_cmd.am" code_string amcLibVar = code_string_concat((code_string_concat((code_string_concat("$", lb)), "AMC_LIB:-$AMC_DIR/../share/amalgame/lib/libamalgame.a")), rb); #line 1640 "./src/new_cmd.am" code_string pkgVar = code_string_concat((code_string_concat((code_string_concat("$", lb)), "AMALGAME_PACKAGES_DIR:-$HOME/.amalgame/packages")), rb); #line 1641 "./src/new_cmd.am" code_string s = ""; #line 1642 "./src/new_cmd.am" s = (code_string_concat(s, "#!/bin/sh\n")); #line 1643 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# Build script for the `")), name)), "` GUI app.\n")); #line 1644 "./src/new_cmd.am" s = (code_string_concat(s, "#\n")); #line 1645 "./src/new_cmd.am" s = (code_string_concat(s, "# Step 1: amc compiles src/main.am to build/.c\n")); #line 1646 "./src/new_cmd.am" s = (code_string_concat(s, "# (resolves the ui-sdl / ui-forms imports via\n")); #line 1647 "./src/new_cmd.am" s = (code_string_concat(s, "# amalgame.lock + your local package cache).\n")); #line 1648 "./src/new_cmd.am" s = (code_string_concat(s, "# Step 2: gcc links the generated .c against the per-\n")); #line 1649 "./src/new_cmd.am" s = (code_string_concat(s, "# package facade archives (built by\n")); #line 1650 "./src/new_cmd.am" s = (code_string_concat(s, "# `amc package add ui-sdl ui-forms`) plus\n")); #line 1651 "./src/new_cmd.am" s = (code_string_concat(s, "# SDL2 + SDL2_ttf via pkg-config.\n")); #line 1652 "./src/new_cmd.am" s = (code_string_concat(s, "#\n")); #line 1653 "./src/new_cmd.am" s = (code_string_concat(s, "# Requires: amc 0.8.7+ + libsdl2-dev + libsdl2-ttf-dev.\n")); #line 1654 "./src/new_cmd.am" s = (code_string_concat(s, "set -eu\n")); #line 1655 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1656 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "NAME=")), name)), "\n")); #line 1657 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "AMC=")), amcVar)), "\n")); #line 1658 "./src/new_cmd.am" s = (code_string_concat(s, "AMC_DIR=$(cd \"$(dirname \"$AMC\")\" && pwd)\n")); #line 1659 "./src/new_cmd.am" s = (code_string_concat(s, "if [ -d \"$AMC_DIR/runtime\" ]; then\n")); #line 1660 "./src/new_cmd.am" s = (code_string_concat(s, " AMC_RUNTIME=\"$AMC_DIR/runtime\"\n")); #line 1661 "./src/new_cmd.am" s = (code_string_concat(s, "else\n")); #line 1662 "./src/new_cmd.am" s = (code_string_concat(s, " AMC_RUNTIME=\"$AMC_DIR/../share/amalgame/runtime\"\n")); #line 1663 "./src/new_cmd.am" s = (code_string_concat(s, "fi\n")); #line 1664 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "AMC_LIB=")), amcLibVar)), "\n")); #line 1665 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "PKG_CACHE=")), pkgVar)), "\n")); #line 1666 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1667 "./src/new_cmd.am" s = (code_string_concat(s, "# Find the precompiled per-package facade archives.\n")); #line 1668 "./src/new_cmd.am" s = (code_string_concat(s, "PLAT=$(uname -s | tr 'A-Z' 'a-z')-$(uname -m)\n")); #line 1669 "./src/new_cmd.am" s = (code_string_concat(s, "find_archive() {\n")); #line 1670 "./src/new_cmd.am" s = (code_string_concat(s, " find \"$PKG_CACHE/github.com/amalgame-lang/$1\" \\\n")); #line 1671 "./src/new_cmd.am" s = (code_string_concat(s, " -path \"*/build/$PLAT/libamalgame-pkg-*.a\" 2>/dev/null | head -1\n")); #line 1672 "./src/new_cmd.am" s = (code_string_concat(s, "}\n")); #line 1673 "./src/new_cmd.am" s = (code_string_concat(s, "FORMS_AR=$(find_archive amalgame-ui-forms)\n")); #line 1674 "./src/new_cmd.am" s = (code_string_concat(s, "SDL_AR=$(find_archive amalgame-ui-sdl)\n")); #line 1675 "./src/new_cmd.am" s = (code_string_concat(s, "if [ -z \"$FORMS_AR\" ] || [ -z \"$SDL_AR\" ]; then\n")); #line 1676 "./src/new_cmd.am" s = (code_string_concat(s, " echo \"ERROR: missing facade archive. Did you run 'amc package add ui-sdl ui-forms'?\"\n")); #line 1677 "./src/new_cmd.am" s = (code_string_concat(s, " exit 1\n")); #line 1678 "./src/new_cmd.am" s = (code_string_concat(s, "fi\n")); #line 1679 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1680 "./src/new_cmd.am" s = (code_string_concat(s, "SDL_CFLAGS=$(pkg-config --cflags sdl2 SDL2_ttf)\n")); #line 1681 "./src/new_cmd.am" s = (code_string_concat(s, "SDL_LIBS=$(pkg-config --libs sdl2 SDL2_ttf)\n")); #line 1682 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1683 "./src/new_cmd.am" s = (code_string_concat(s, "mkdir -p build\n")); #line 1684 "./src/new_cmd.am" s = (code_string_concat(s, "\"$AMC\" -o build/$NAME src/main.am --quiet\n")); #line 1685 "./src/new_cmd.am" s = (code_string_concat(s, "gcc -O2 -I\"$AMC_RUNTIME\" $SDL_CFLAGS build/$NAME.c \\\n")); #line 1686 "./src/new_cmd.am" s = (code_string_concat(s, " \"$FORMS_AR\" \"$SDL_AR\" \"$AMC_LIB\" \\\n")); #line 1687 "./src/new_cmd.am" s = (code_string_concat(s, " -lgc -lm -lz -ldl -lpthread $SDL_LIBS -o $NAME\n")); #line 1688 "./src/new_cmd.am" s = (code_string_concat(s, "echo \"Built ./$NAME — run it now.\"\n")); #line 1689 "./src/new_cmd.am" return s; } static code_string Amalgame_Compiler_NewCommand_ReadmeForms(code_string name) { #line 1693 "./src/new_cmd.am" code_string s = ""; #line 1694 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "# ")), name)), "\n")); #line 1695 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1696 "./src/new_cmd.am" s = (code_string_concat(s, "GUI app built with the [Amalgame](https://amalgame.me)\n")); #line 1697 "./src/new_cmd.am" s = (code_string_concat(s, "language and the `amalgame-ui-forms` toolkit.\n")); #line 1698 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1699 "./src/new_cmd.am" s = (code_string_concat(s, "## First run\n")); #line 1700 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1701 "./src/new_cmd.am" s = (code_string_concat(s, "Install the SDL2 development headers (one-off, per machine):\n")); #line 1702 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1703 "./src/new_cmd.am" s = (code_string_concat(s, "```sh\n")); #line 1704 "./src/new_cmd.am" s = (code_string_concat(s, "# Debian / Ubuntu\n")); #line 1705 "./src/new_cmd.am" s = (code_string_concat(s, "sudo apt install libsdl2-dev libsdl2-ttf-dev libgc-dev\n")); #line 1706 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1707 "./src/new_cmd.am" s = (code_string_concat(s, "# macOS (Homebrew)\n")); #line 1708 "./src/new_cmd.am" s = (code_string_concat(s, "brew install sdl2 sdl2_ttf bdw-gc\n")); #line 1709 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1710 "./src/new_cmd.am" s = (code_string_concat(s, "# Arch / Manjaro\n")); #line 1711 "./src/new_cmd.am" s = (code_string_concat(s, "sudo pacman -S sdl2 sdl2_ttf gc\n")); #line 1712 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1713 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1714 "./src/new_cmd.am" s = (code_string_concat(s, "Fetch the package deps and build:\n")); #line 1715 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1716 "./src/new_cmd.am" s = (code_string_concat(s, "```sh\n")); #line 1717 "./src/new_cmd.am" s = (code_string_concat(s, "amc package add ui-sdl ui-forms\n")); #line 1718 "./src/new_cmd.am" s = (code_string_concat(s, "./build.sh\n")); #line 1719 "./src/new_cmd.am" s = (code_string_concat((code_string_concat((code_string_concat(s, "./")), name)), "\n")); #line 1720 "./src/new_cmd.am" s = (code_string_concat(s, "```\n")); #line 1721 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1722 "./src/new_cmd.am" s = (code_string_concat(s, "A 320x240 window with a Label and a Button will open.\n")); #line 1723 "./src/new_cmd.am" s = (code_string_concat(s, "Click the close button (or the OK button — it flips\n")); #line 1724 "./src/new_cmd.am" s = (code_string_concat(s, "to the accent color) to exit.\n")); #line 1725 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1726 "./src/new_cmd.am" s = (code_string_concat(s, "## Next steps\n")); #line 1727 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1728 "./src/new_cmd.am" s = (code_string_concat(s, "- Add more widgets with `Widget.CheckBox / RadioButton /\n")); #line 1729 "./src/new_cmd.am" s = (code_string_concat(s, " TextBox / Panel`.\n")); #line 1730 "./src/new_cmd.am" s = (code_string_concat(s, "- Try other layouts: `Layout.StackHorizontal`,\n")); #line 1731 "./src/new_cmd.am" s = (code_string_concat(s, " `Layout.Grid(rows, cols, spacing, padding)`,\n")); #line 1732 "./src/new_cmd.am" s = (code_string_concat(s, " `Layout.Absolute()`.\n")); #line 1733 "./src/new_cmd.am" s = (code_string_concat(s, "- Detect the host theme: `Theme.FromOS()` picks Light or\n")); #line 1734 "./src/new_cmd.am" s = (code_string_concat(s, " Dark automatically.\n")); #line 1735 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1736 "./src/new_cmd.am" s = (code_string_concat(s, "Full surface in the `amalgame-ui-forms` README\n")); #line 1737 "./src/new_cmd.am" s = (code_string_concat(s, "(github.com/amalgame-lang/amalgame-ui-forms).\n")); #line 1738 "./src/new_cmd.am" return s; } static i64 Amalgame_Compiler_NewCommand_ScaffoldUiWebForm(code_string path, code_string base) { #line 1752 "./src/new_cmd.am" if (!File_Mkdir(code_string_concat(path, "/src"))) { #line 1753 "./src/new_cmd.am" Console_WriteError("amc new: failed to create src/ subdirectory"); #line 1754 "./src/new_cmd.am" return 1LL; } #line 1757 "./src/new_cmd.am" code_string mainAm = Amalgame_Compiler_NewCommand_MainAmUiWebForm(base); #line 1758 "./src/new_cmd.am" code_string manifest = Amalgame_Compiler_NewCommand_ManifestUiWebForm(base); #line 1759 "./src/new_cmd.am" code_string buildSh = Amalgame_Compiler_NewCommand_BuildShUiWebForm(base); #line 1760 "./src/new_cmd.am" code_string readme = Amalgame_Compiler_NewCommand_ReadmeUiWebForm(base); #line 1761 "./src/new_cmd.am" code_string gitignore = Amalgame_Compiler_NewCommand_GitignoreCommon(); #line 1763 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/src/main.am"), mainAm)) { return 1LL; } #line 1764 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/amalgame.toml"), manifest)) { return 1LL; } #line 1765 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/build.sh"), buildSh)) { return 1LL; } #line 1766 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/.gitignore"), gitignore)) { return 1LL; } #line 1767 "./src/new_cmd.am" if (!Amalgame_Compiler_NewCommand_WriteFile(code_string_concat(path, "/README.md"), readme)) { return 1LL; } #line 1768 "./src/new_cmd.am" Process_Run(code_string_concat("chmod +x ", Amalgame_Compiler_NewCommand_ShellEscape(code_string_concat(path, "/build.sh")))); #line 1770 "./src/new_cmd.am" Console_WriteLine(code_string_concat((code_string_concat("Scaffolded '", base)), "' (ui-web-form template).")); #line 1771 "./src/new_cmd.am" Console_WriteLine(code_string_concat(" cd ", path)); #line 1772 "./src/new_cmd.am" Console_WriteLine(" amc package add ui-web # fetch the package (one-off)"); #line 1773 "./src/new_cmd.am" Console_WriteLine(" sudo apt install libwebkit2gtk-4.1-dev # Linux build deps"); #line 1774 "./src/new_cmd.am" Console_WriteLine(code_string_concat(" ./build.sh && ./", base)); #line 1775 "./src/new_cmd.am" return 0LL; } static code_string Amalgame_Compiler_NewCommand_MainAmUiWebForm(code_string name) { #line 1779 "./src/new_cmd.am" code_string s = ""; #line 1780 "./src/new_cmd.am" s = (code_string_concat(s, "import Amalgame.UI.Web\n")); #line 1781 "./src/new_cmd.am" s = (code_string_concat(s, "\n")); #line 1782 "./src/new_cmd.am" s = (code_string_concat(s, "// Scaffolded by `amc new --template ui-web-form`.\n")); #line 1783 "./src/new_cmd.am" s = (code_string_concat(s, "//\n")); #line 1784 "./src/new_cmd.am" s = (code_string_concat(s, "// A 720x480 webview window with a small form built via the\n")); #line 1785 "./src/new_cmd.am" s = (code_string_concat(s, "// AM-side Element / Page builder. Submit invokes the AM\n")); #line 1786 "./src/new_cmd.am" s = (code_string_concat(s, "// handler with the form payload as a JSON object string\n")); #line 1787 "./src/new_cmd.am" s = (code_string_concat(s, "// (auto-collected by ui-web's __amc_collect bridge). The\n")); #line 1788 "./src/new_cmd.am" s = (code_string_concat(s, "// returned value is routed declaratively into the\n")); #line 1789 "./src/new_cmd.am" s = (code_string_concat(s, "//
 panel via `Element.OnResult(\"out\")`.\n"));
    #line 1790 "./src/new_cmd.am"
    s = (code_string_concat(s, "//\n"));
    #line 1791 "./src/new_cmd.am"
    s = (code_string_concat(s, "// The baseline stylesheet handles light/dark theming from\n"));
    #line 1792 "./src/new_cmd.am"
    s = (code_string_concat(s, "// the OS. Override individual CSS variables (`--amc-bg`,\n"));
    #line 1793 "./src/new_cmd.am"
    s = (code_string_concat(s, "// `--amc-fg`, `--amc-accent`, …) from your own stylesheet\n"));
    #line 1794 "./src/new_cmd.am"
    s = (code_string_concat(s, "// or call `Page.SetStylesheet(url)` / `.AddCss(url)`.\n"));
    #line 1795 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1796 "./src/new_cmd.am"
    s = (code_string_concat(s, "class Program {\n"));
    #line 1797 "./src/new_cmd.am"
    s = (code_string_concat(s, "    public static void Main() {\n"));
    #line 1798 "./src/new_cmd.am"
    s = (code_string_concat((code_string_concat((code_string_concat(s, "        let win: Window = new Window(\"")), name)), "\", 720, 480, false)\n"));
    #line 1799 "./src/new_cmd.am"
    s = (code_string_concat(s, "        if (!win.IsValid()) {\n"));
    #line 1800 "./src/new_cmd.am"
    s = (code_string_concat(s, "            return\n"));
    #line 1801 "./src/new_cmd.am"
    s = (code_string_concat(s, "        }\n"));
    #line 1802 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1803 "./src/new_cmd.am"
    s = (code_string_concat(s, "        let page: Page = Page.New()\n"));
    #line 1804 "./src/new_cmd.am"
    s = (code_string_concat((code_string_concat((code_string_concat(s, "            .SetTitle(\"")), name)), "\")\n"));
    #line 1805 "./src/new_cmd.am"
    s = (code_string_concat(s, "            .SetBody(\n"));
    #line 1806 "./src/new_cmd.am"
    s = (code_string_concat(s, "                Element.Stack()\n"));
    #line 1807 "./src/new_cmd.am"
    s = (code_string_concat((code_string_concat((code_string_concat(s, "                    .AddChild(Element.Heading(\"Welcome to ")), name)), "\"))\n"));
    #line 1808 "./src/new_cmd.am"
    s = (code_string_concat(s, "                    .AddChild(Element.Label(\"Edit the form, then click Submit.\"))\n"));
    #line 1809 "./src/new_cmd.am"
    s = (code_string_concat(s, "                    .AddChild(Element.Input(\"user\").Attr(\"placeholder\", \"Your name\"))\n"));
    #line 1810 "./src/new_cmd.am"
    s = (code_string_concat(s, "                    .AddChild(Element.Textarea(\"message\").Attr(\"placeholder\", \"A message\").Size(0, 80))\n"));
    #line 1811 "./src/new_cmd.am"
    s = (code_string_concat(s, "                    .AddChild(Element.Button(\"Submit\")\n"));
    #line 1812 "./src/new_cmd.am"
    s = (code_string_concat(s, "                        .OnClick((req: string) => req)\n"));
    #line 1813 "./src/new_cmd.am"
    s = (code_string_concat(s, "                        .OnResult(\"out\"))\n"));
    #line 1814 "./src/new_cmd.am"
    s = (code_string_concat(s, "                    .AddChild(Element.Pre(\"(submit to see the form payload)\").Id(\"out\"))\n"));
    #line 1815 "./src/new_cmd.am"
    s = (code_string_concat(s, "            )\n"));
    #line 1816 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1817 "./src/new_cmd.am"
    s = (code_string_concat(s, "        page.ApplyTo(win)\n"));
    #line 1818 "./src/new_cmd.am"
    s = (code_string_concat(s, "        win.Run()\n"));
    #line 1819 "./src/new_cmd.am"
    s = (code_string_concat(s, "        win.Destroy()\n"));
    #line 1820 "./src/new_cmd.am"
    s = (code_string_concat(s, "    }\n"));
    #line 1821 "./src/new_cmd.am"
    s = (code_string_concat(s, "}\n"));
    #line 1822 "./src/new_cmd.am"
    return s;
}

static code_string Amalgame_Compiler_NewCommand_ManifestUiWebForm(code_string name) {
    #line 1826 "./src/new_cmd.am"
    code_string s = "";
    #line 1827 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Project manifest — declares external package deps.\n"));
    #line 1828 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Run `amc package add ui-web` once to populate amalgame.lock\n"));
    #line 1829 "./src/new_cmd.am"
    s = (code_string_concat(s, "# and clone the package into ~/.amalgame/packages/, then\n"));
    #line 1830 "./src/new_cmd.am"
    s = (code_string_concat(s, "# `./build.sh` to compile + link against the OS webview.\n"));
    #line 1831 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1832 "./src/new_cmd.am"
    s = (code_string_concat(s, "[package]\n"));
    #line 1833 "./src/new_cmd.am"
    s = (code_string_concat((code_string_concat((code_string_concat(s, "name        = \"")), name)), "\"\n"));
    #line 1834 "./src/new_cmd.am"
    s = (code_string_concat(s, "version     = \"0.1.0\"\n"));
    #line 1835 "./src/new_cmd.am"
    s = (code_string_concat(s, "description = \"Amalgame webview GUI app scaffolded by `amc new --template ui-web-form`.\"\n"));
    #line 1836 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1837 "./src/new_cmd.am"
    s = (code_string_concat(s, "[dependencies]\n"));
    #line 1838 "./src/new_cmd.am"
    s = (code_string_concat(s, "ui-web = { git = \"github.com/amalgame-lang/amalgame-ui-web\", tag = \"v0.0.5\" }\n"));
    #line 1839 "./src/new_cmd.am"
    return s;
}

static code_string Amalgame_Compiler_NewCommand_BuildShUiWebForm(code_string name) {
    #line 1846 "./src/new_cmd.am"
    code_string lb = "{";
    #line 1847 "./src/new_cmd.am"
    code_string rb = "}";
    #line 1848 "./src/new_cmd.am"
    code_string amcVar = code_string_concat((code_string_concat((code_string_concat("$", lb)), "AMC:-$(command -v amc)")), rb);
    #line 1849 "./src/new_cmd.am"
    code_string pkgVar = code_string_concat((code_string_concat((code_string_concat("$", lb)), "AMALGAME_PACKAGES_DIR:-$HOME/.amalgame/packages")), rb);
    #line 1850 "./src/new_cmd.am"
    code_string s = "";
    #line 1851 "./src/new_cmd.am"
    s = (code_string_concat(s, "#!/bin/sh\n"));
    #line 1852 "./src/new_cmd.am"
    s = (code_string_concat((code_string_concat((code_string_concat(s, "# Build script for the `")), name)), "` webview GUI app.\n"));
    #line 1853 "./src/new_cmd.am"
    s = (code_string_concat(s, "#\n"));
    #line 1854 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Pipeline:\n"));
    #line 1855 "./src/new_cmd.am"
    s = (code_string_concat(s, "#   1. Locate the amalgame-ui-web clone in your package cache.\n"));
    #line 1856 "./src/new_cmd.am"
    s = (code_string_concat(s, "#   2. Compile the vendored webview C++ implementation (once).\n"));
    #line 1857 "./src/new_cmd.am"
    s = (code_string_concat(s, "#   3. Compile the C glue and the AM-side facade.\n"));
    #line 1858 "./src/new_cmd.am"
    s = (code_string_concat(s, "#   4. Compile src/main.am via amc --external.\n"));
    #line 1859 "./src/new_cmd.am"
    s = (code_string_concat(s, "#   5. Link everything against libwebkit2gtk (Linux), Cocoa+WebKit\n"));
    #line 1860 "./src/new_cmd.am"
    s = (code_string_concat(s, "#      (macOS), or WebView2Loader (Windows MinGW).\n"));
    #line 1861 "./src/new_cmd.am"
    s = (code_string_concat(s, "#\n"));
    #line 1862 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Requires: amc 0.8.12+. On Linux you also need\n"));
    #line 1863 "./src/new_cmd.am"
    s = (code_string_concat(s, "# libwebkit2gtk-4.1-dev (Debian/Ubuntu) or equivalent.\n"));
    #line 1864 "./src/new_cmd.am"
    s = (code_string_concat(s, "set -eu\n"));
    #line 1865 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1866 "./src/new_cmd.am"
    s = (code_string_concat((code_string_concat((code_string_concat(s, "NAME=")), name)), "\n"));
    #line 1867 "./src/new_cmd.am"
    s = (code_string_concat((code_string_concat((code_string_concat(s, "AMC=")), amcVar)), "\n"));
    #line 1868 "./src/new_cmd.am"
    s = (code_string_concat(s, "AMC_DIR=$(cd \"$(dirname \"$AMC\")\" && pwd)\n"));
    #line 1869 "./src/new_cmd.am"
    s = (code_string_concat(s, "if [ -d \"$AMC_DIR/runtime\" ]; then\n"));
    #line 1870 "./src/new_cmd.am"
    s = (code_string_concat(s, "  AMC_RUNTIME=\"$AMC_DIR/runtime\"\n"));
    #line 1871 "./src/new_cmd.am"
    s = (code_string_concat(s, "else\n"));
    #line 1872 "./src/new_cmd.am"
    s = (code_string_concat(s, "  AMC_RUNTIME=\"$AMC_DIR/../share/amalgame/runtime\"\n"));
    #line 1873 "./src/new_cmd.am"
    s = (code_string_concat(s, "fi\n"));
    #line 1874 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Resolve libamalgame.a: prefer the XDG install layout\n"));
    #line 1875 "./src/new_cmd.am"
    s = (code_string_concat(s, "# (share/amalgame/lib/), fall back to a dev checkout layout\n"));
    #line 1876 "./src/new_cmd.am"
    s = (code_string_concat(s, "# ($AMC_DIR/lib/) so this script works against both an\n"));
    #line 1877 "./src/new_cmd.am"
    s = (code_string_concat(s, "# installed amc and a freshly-bootstrapped one.\n"));
    #line 1878 "./src/new_cmd.am"
    s = (code_string_concat(s, "if [ -z \"${AMC_LIB:-}\" ]; then\n"));
    #line 1879 "./src/new_cmd.am"
    s = (code_string_concat(s, "  if [ -f \"$AMC_DIR/../share/amalgame/lib/libamalgame.a\" ]; then\n"));
    #line 1880 "./src/new_cmd.am"
    s = (code_string_concat(s, "    AMC_LIB=\"$AMC_DIR/../share/amalgame/lib/libamalgame.a\"\n"));
    #line 1881 "./src/new_cmd.am"
    s = (code_string_concat(s, "  elif [ -f \"$AMC_DIR/lib/libamalgame.a\" ]; then\n"));
    #line 1882 "./src/new_cmd.am"
    s = (code_string_concat(s, "    AMC_LIB=\"$AMC_DIR/lib/libamalgame.a\"\n"));
    #line 1883 "./src/new_cmd.am"
    s = (code_string_concat(s, "  else\n"));
    #line 1884 "./src/new_cmd.am"
    s = (code_string_concat(s, "    echo \"ERROR: libamalgame.a not found. Set \\$AMC_LIB or reinstall amc.\"\n"));
    #line 1885 "./src/new_cmd.am"
    s = (code_string_concat(s, "    exit 1\n"));
    #line 1886 "./src/new_cmd.am"
    s = (code_string_concat(s, "  fi\n"));
    #line 1887 "./src/new_cmd.am"
    s = (code_string_concat(s, "fi\n"));
    #line 1888 "./src/new_cmd.am"
    s = (code_string_concat((code_string_concat((code_string_concat(s, "PKG_CACHE=")), pkgVar)), "\n"));
    #line 1889 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1890 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Newest installed ui-web tag in the cache.\n"));
    #line 1891 "./src/new_cmd.am"
    s = (code_string_concat(s, "UIWEB_DIR=$(ls -dt \"$PKG_CACHE/github.com/amalgame-lang/amalgame-ui-web/\"v* 2>/dev/null | head -1)\n"));
    #line 1892 "./src/new_cmd.am"
    s = (code_string_concat(s, "if [ -z \"$UIWEB_DIR\" ] || [ ! -d \"$UIWEB_DIR/runtime/vendor/webview\" ]; then\n"));
    #line 1893 "./src/new_cmd.am"
    s = (code_string_concat(s, "  echo \"ERROR: amalgame-ui-web not installed. Run 'amc package add ui-web' first.\"\n"));
    #line 1894 "./src/new_cmd.am"
    s = (code_string_concat(s, "  exit 1\n"));
    #line 1895 "./src/new_cmd.am"
    s = (code_string_concat(s, "fi\n"));
    #line 1896 "./src/new_cmd.am"
    s = (code_string_concat(s, "echo \"Using ui-web from $UIWEB_DIR\"\n"));
    #line 1897 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1898 "./src/new_cmd.am"
    s = (code_string_concat(s, "# WebKitGTK detection (Linux only — macOS/Windows ship the engine).\n"));
    #line 1899 "./src/new_cmd.am"
    s = (code_string_concat(s, "WEBKIT_CFLAGS=\"\"\n"));
    #line 1900 "./src/new_cmd.am"
    s = (code_string_concat(s, "WEBKIT_LIBS=\"\"\n"));
    #line 1901 "./src/new_cmd.am"
    s = (code_string_concat(s, "case \"$(uname -s)\" in\n"));
    #line 1902 "./src/new_cmd.am"
    s = (code_string_concat(s, "  Linux*|FreeBSD*|OpenBSD*|NetBSD*)\n"));
    #line 1903 "./src/new_cmd.am"
    s = (code_string_concat(s, "    if pkg-config --exists webkit2gtk-4.1; then\n"));
    #line 1904 "./src/new_cmd.am"
    s = (code_string_concat(s, "      WEBKIT_PC=webkit2gtk-4.1\n"));
    #line 1905 "./src/new_cmd.am"
    s = (code_string_concat(s, "    elif pkg-config --exists webkit2gtk-4.0; then\n"));
    #line 1906 "./src/new_cmd.am"
    s = (code_string_concat(s, "      WEBKIT_PC=webkit2gtk-4.0\n"));
    #line 1907 "./src/new_cmd.am"
    s = (code_string_concat(s, "    else\n"));
    #line 1908 "./src/new_cmd.am"
    s = (code_string_concat(s, "      echo \"ERROR: install libwebkit2gtk-4.1-dev (Debian/Ubuntu) or equivalent.\"\n"));
    #line 1909 "./src/new_cmd.am"
    s = (code_string_concat(s, "      exit 1\n"));
    #line 1910 "./src/new_cmd.am"
    s = (code_string_concat(s, "    fi\n"));
    #line 1911 "./src/new_cmd.am"
    s = (code_string_concat(s, "    WEBKIT_CFLAGS=$(pkg-config --cflags \"$WEBKIT_PC\")\n"));
    #line 1912 "./src/new_cmd.am"
    s = (code_string_concat(s, "    WEBKIT_LIBS=$(pkg-config --libs \"$WEBKIT_PC\")\n"));
    #line 1913 "./src/new_cmd.am"
    s = (code_string_concat(s, "    ;;\n"));
    #line 1914 "./src/new_cmd.am"
    s = (code_string_concat(s, "  Darwin*)\n"));
    #line 1915 "./src/new_cmd.am"
    s = (code_string_concat(s, "    WEBKIT_LIBS=\"-framework Cocoa -framework WebKit\"\n"));
    #line 1916 "./src/new_cmd.am"
    s = (code_string_concat(s, "    ;;\n"));
    #line 1917 "./src/new_cmd.am"
    s = (code_string_concat(s, "  MINGW*|MSYS*|CYGWIN*)\n"));
    #line 1918 "./src/new_cmd.am"
    s = (code_string_concat(s, "    WEBKIT_LIBS=\"-lWebView2Loader.dll.lib -lOle32 -lShlwapi\"\n"));
    #line 1919 "./src/new_cmd.am"
    s = (code_string_concat(s, "    ;;\n"));
    #line 1920 "./src/new_cmd.am"
    s = (code_string_concat(s, "esac\n"));
    #line 1921 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1922 "./src/new_cmd.am"
    s = (code_string_concat(s, "mkdir -p build\n"));
    #line 1923 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1924 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Step 1: vendored webview C++ TU (one-shot, ~5 s).\n"));
    #line 1925 "./src/new_cmd.am"
    s = (code_string_concat(s, "if [ ! -f build/webview.o ] || \\\n"));
    #line 1926 "./src/new_cmd.am"
    s = (code_string_concat(s, "   [ \"$UIWEB_DIR/runtime/vendor/webview/webview.cc\" -nt build/webview.o ]; then\n"));
    #line 1927 "./src/new_cmd.am"
    s = (code_string_concat(s, "  echo \"Building webview.cc (one-time C++ TU)...\"\n"));
    #line 1928 "./src/new_cmd.am"
    s = (code_string_concat(s, "  g++ -c -O2 -std=c++17 -DNDEBUG -Wno-unused-parameter \\\n"));
    #line 1929 "./src/new_cmd.am"
    s = (code_string_concat(s, "      -DWEBVIEW_STATIC \\\n"));
    #line 1930 "./src/new_cmd.am"
    s = (code_string_concat(s, "      -I \"$UIWEB_DIR/runtime/vendor/webview\" \\\n"));
    #line 1931 "./src/new_cmd.am"
    s = (code_string_concat(s, "      $WEBKIT_CFLAGS \\\n"));
    #line 1932 "./src/new_cmd.am"
    s = (code_string_concat(s, "      \"$UIWEB_DIR/runtime/vendor/webview/webview.cc\" \\\n"));
    #line 1933 "./src/new_cmd.am"
    s = (code_string_concat(s, "      -o build/webview.o\n"));
    #line 1934 "./src/new_cmd.am"
    s = (code_string_concat(s, "fi\n"));
    #line 1935 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1936 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Step 2: C glue (thin slot-table over webview_*).\n"));
    #line 1937 "./src/new_cmd.am"
    s = (code_string_concat(s, "if [ ! -f build/Amalgame_UI_Web.o ] || \\\n"));
    #line 1938 "./src/new_cmd.am"
    s = (code_string_concat(s, "   [ \"$UIWEB_DIR/runtime/Amalgame_UI_Web.c\" -nt build/Amalgame_UI_Web.o ]; then\n"));
    #line 1939 "./src/new_cmd.am"
    s = (code_string_concat(s, "  echo \"Building C glue...\"\n"));
    #line 1940 "./src/new_cmd.am"
    s = (code_string_concat(s, "  gcc -c -O2 -DWEBVIEW_STATIC \\\n"));
    #line 1941 "./src/new_cmd.am"
    s = (code_string_concat(s, "      -I \"$AMC_RUNTIME\" \\\n"));
    #line 1942 "./src/new_cmd.am"
    s = (code_string_concat(s, "      -I \"$UIWEB_DIR/runtime\" \\\n"));
    #line 1943 "./src/new_cmd.am"
    s = (code_string_concat(s, "      -I \"$UIWEB_DIR/runtime/vendor/webview\" \\\n"));
    #line 1944 "./src/new_cmd.am"
    s = (code_string_concat(s, "      $WEBKIT_CFLAGS \\\n"));
    #line 1945 "./src/new_cmd.am"
    s = (code_string_concat(s, "      \"$UIWEB_DIR/runtime/Amalgame_UI_Web.c\" \\\n"));
    #line 1946 "./src/new_cmd.am"
    s = (code_string_concat(s, "      -o build/Amalgame_UI_Web.o\n"));
    #line 1947 "./src/new_cmd.am"
    s = (code_string_concat(s, "fi\n"));
    #line 1948 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1949 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Step 3: ui-web AM facade.\n"));
    #line 1950 "./src/new_cmd.am"
    s = (code_string_concat(s, "if [ ! -f build/facade.o ] || [ \"$UIWEB_DIR/facade.am\" -nt build/facade.o ]; then\n"));
    #line 1951 "./src/new_cmd.am"
    s = (code_string_concat(s, "  echo \"Building ui-web facade...\"\n"));
    #line 1952 "./src/new_cmd.am"
    s = (code_string_concat(s, "  (cd \"$UIWEB_DIR\" && \"$AMC\" --lib facade.am --quiet)\n"));
    #line 1953 "./src/new_cmd.am"
    s = (code_string_concat(s, "  gcc -c -O2 \\\n"));
    #line 1954 "./src/new_cmd.am"
    s = (code_string_concat(s, "      -I \"$AMC_RUNTIME\" \\\n"));
    #line 1955 "./src/new_cmd.am"
    s = (code_string_concat(s, "      -I \"$UIWEB_DIR/runtime\" \\\n"));
    #line 1956 "./src/new_cmd.am"
    s = (code_string_concat(s, "      \"$UIWEB_DIR/a.out.c\" \\\n"));
    #line 1957 "./src/new_cmd.am"
    s = (code_string_concat(s, "      -o build/facade.o\n"));
    #line 1958 "./src/new_cmd.am"
    s = (code_string_concat(s, "fi\n"));
    #line 1959 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1960 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Step 4: user app.\n"));
    #line 1961 "./src/new_cmd.am"
    s = (code_string_concat(s, "echo \"Compiling src/main.am...\"\n"));
    #line 1962 "./src/new_cmd.am"
    s = (code_string_concat(s, "\"$AMC\" -o \"build/$NAME\" src/main.am --external \"$UIWEB_DIR/facade.am\" --quiet\n"));
    #line 1963 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1964 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Step 5: link. Use gcc (not g++) — Amalgame_Net.h passes string\n"));
    #line 1965 "./src/new_cmd.am"
    s = (code_string_concat(s, "# literals as code_string (non-const char*) which g++ rejects.\n"));
    #line 1966 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Pull libstdc++ in explicitly so the C++ symbols resolve.\n"));
    #line 1967 "./src/new_cmd.am"
    s = (code_string_concat(s, "echo \"Linking $NAME...\"\n"));
    #line 1968 "./src/new_cmd.am"
    s = (code_string_concat(s, "gcc -O2 \\\n"));
    #line 1969 "./src/new_cmd.am"
    s = (code_string_concat(s, "    -I \"$AMC_RUNTIME\" \\\n"));
    #line 1970 "./src/new_cmd.am"
    s = (code_string_concat(s, "    -I \"$UIWEB_DIR/runtime\" \\\n"));
    #line 1971 "./src/new_cmd.am"
    s = (code_string_concat(s, "    \"build/$NAME.c\" \\\n"));
    #line 1972 "./src/new_cmd.am"
    s = (code_string_concat(s, "    build/facade.o build/Amalgame_UI_Web.o build/webview.o \\\n"));
    #line 1973 "./src/new_cmd.am"
    s = (code_string_concat(s, "    \"$AMC_LIB\" \\\n"));
    #line 1974 "./src/new_cmd.am"
    s = (code_string_concat(s, "    $WEBKIT_LIBS \\\n"));
    #line 1975 "./src/new_cmd.am"
    s = (code_string_concat(s, "    -lstdc++ -lm -lgc -lz -ldl -lpthread \\\n"));
    #line 1976 "./src/new_cmd.am"
    s = (code_string_concat(s, "    -o \"$NAME\"\n"));
    #line 1977 "./src/new_cmd.am"
    s = (code_string_concat(s, "echo \"Built ./$NAME — run it now.\"\n"));
    #line 1978 "./src/new_cmd.am"
    return s;
}

static code_string Amalgame_Compiler_NewCommand_ReadmeUiWebForm(code_string name) {
    #line 1982 "./src/new_cmd.am"
    code_string s = "";
    #line 1983 "./src/new_cmd.am"
    s = (code_string_concat((code_string_concat((code_string_concat(s, "# ")), name)), "\n"));
    #line 1984 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1985 "./src/new_cmd.am"
    s = (code_string_concat(s, "Webview GUI app built with the [Amalgame](https://amalgame.me)\n"));
    #line 1986 "./src/new_cmd.am"
    s = (code_string_concat(s, "language and the [`amalgame-ui-web`](https://github.com/amalgame-lang/amalgame-ui-web)\n"));
    #line 1987 "./src/new_cmd.am"
    s = (code_string_concat(s, "package.\n"));
    #line 1988 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1989 "./src/new_cmd.am"
    s = (code_string_concat(s, "Renders an HTML/CSS UI through the OS-native webview engine\n"));
    #line 1990 "./src/new_cmd.am"
    s = (code_string_concat(s, "(WebView2 on Windows, WKWebView on macOS, WebKitGTK on Linux).\n"));
    #line 1991 "./src/new_cmd.am"
    s = (code_string_concat(s, "Backend logic stays in Amalgame, with JS ↔ Amalgame IPC via\n"));
    #line 1992 "./src/new_cmd.am"
    s = (code_string_concat(s, "`Window.Bind` and a declarative form-collect bridge.\n"));
    #line 1993 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1994 "./src/new_cmd.am"
    s = (code_string_concat(s, "## First run\n"));
    #line 1995 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1996 "./src/new_cmd.am"
    s = (code_string_concat(s, "Install build dependencies (one-off, per machine):\n"));
    #line 1997 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 1998 "./src/new_cmd.am"
    s = (code_string_concat(s, "```sh\n"));
    #line 1999 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Debian / Ubuntu\n"));
    #line 2000 "./src/new_cmd.am"
    s = (code_string_concat(s, "sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev pkg-config\n"));
    #line 2001 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 2002 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Fedora\n"));
    #line 2003 "./src/new_cmd.am"
    s = (code_string_concat(s, "sudo dnf install webkit2gtk4.1-devel gtk3-devel pkgconf-pkg-config\n"));
    #line 2004 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 2005 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Arch / Manjaro\n"));
    #line 2006 "./src/new_cmd.am"
    s = (code_string_concat(s, "sudo pacman -S webkit2gtk-4.1 gtk3 pkgconf\n"));
    #line 2007 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 2008 "./src/new_cmd.am"
    s = (code_string_concat(s, "# macOS — nothing, WKWebView ships with the OS since 10.10.\n"));
    #line 2009 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Windows 11 — nothing, WebView2 runtime ships with the OS.\n"));
    #line 2010 "./src/new_cmd.am"
    s = (code_string_concat(s, "# Older Windows 10 — install the WebView2 evergreen bootstrapper:\n"));
    #line 2011 "./src/new_cmd.am"
    s = (code_string_concat(s, "#   https://developer.microsoft.com/microsoft-edge/webview2/\n"));
    #line 2012 "./src/new_cmd.am"
    s = (code_string_concat(s, "```\n"));
    #line 2013 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 2014 "./src/new_cmd.am"
    s = (code_string_concat(s, "Fetch the package and build:\n"));
    #line 2015 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 2016 "./src/new_cmd.am"
    s = (code_string_concat(s, "```sh\n"));
    #line 2017 "./src/new_cmd.am"
    s = (code_string_concat(s, "amc package add ui-web\n"));
    #line 2018 "./src/new_cmd.am"
    s = (code_string_concat(s, "./build.sh\n"));
    #line 2019 "./src/new_cmd.am"
    s = (code_string_concat((code_string_concat((code_string_concat(s, "./")), name)), "\n"));
    #line 2020 "./src/new_cmd.am"
    s = (code_string_concat(s, "```\n"));
    #line 2021 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 2022 "./src/new_cmd.am"
    s = (code_string_concat(s, "A 720x480 window opens with a small form (Input + Textarea +\n"));
    #line 2023 "./src/new_cmd.am"
    s = (code_string_concat(s, "Submit). Clicking Submit echoes the form payload back into a\n"));
    #line 2024 "./src/new_cmd.am"
    s = (code_string_concat(s, "`
` panel as pretty-printed JSON.\n"));
    #line 2025 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 2026 "./src/new_cmd.am"
    s = (code_string_concat(s, "## Next steps\n"));
    #line 2027 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 2028 "./src/new_cmd.am"
    s = (code_string_concat(s, "- More form fields: `Element.Select / Option / CheckBox /\n"));
    #line 2029 "./src/new_cmd.am"
    s = (code_string_concat(s, "  Radio`. Names auto-collected into the handler's `req` JSON.\n"));
    #line 2030 "./src/new_cmd.am"
    s = (code_string_concat(s, "- Custom theme: override CSS variables in your own stylesheet:\n"));
    #line 2031 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 2032 "./src/new_cmd.am"
    s = (code_string_concat(s, "  ```css\n"));
    #line 2033 "./src/new_cmd.am"
    s = (code_string_concat(s, "  :root { --amc-accent: #ff6b00 }\n"));
    #line 2034 "./src/new_cmd.am"
    s = (code_string_concat(s, "  ```\n"));
    #line 2035 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 2036 "./src/new_cmd.am"
    s = (code_string_concat(s, "  Apply via `Page.New().AddCss(\"file:///abs/path/style.css\")`.\n"));
    #line 2037 "./src/new_cmd.am"
    s = (code_string_concat(s, "- Force theme: `Page.SetTheme(\"light\" | \"dark\" | \"auto\")`.\n"));
    #line 2038 "./src/new_cmd.am"
    s = (code_string_concat(s, "- Multi-page apps: layer extra stylesheets / replace the\n"));
    #line 2039 "./src/new_cmd.am"
    s = (code_string_concat(s, "  baseline / load remote URLs — see the ui-web README.\n"));
    #line 2040 "./src/new_cmd.am"
    s = (code_string_concat(s, "\n"));
    #line 2041 "./src/new_cmd.am"
    s = (code_string_concat(s, "Full surface in the `amalgame-ui-web` README\n"));
    #line 2042 "./src/new_cmd.am"
    s = (code_string_concat(s, "(github.com/amalgame-lang/amalgame-ui-web).\n"));
    #line 2043 "./src/new_cmd.am"
    return s;
}

struct _Amalgame_Compiler_McuCommand {
};

i64 Amalgame_Compiler_McuCommand_Run(i64 argc);
code_bool Amalgame_Compiler_McuCommand_IsWin();
code_bool Amalgame_Compiler_McuCommand_IsInteractive();
code_string Amalgame_Compiler_McuCommand_DetectOs();
code_bool Amalgame_Compiler_McuCommand_Has(code_string tool);
static void Amalgame_Compiler_McuCommand_Report(code_string tool, code_string role);
i64 Amalgame_Compiler_McuCommand_Doctor();
code_string Amalgame_Compiler_McuCommand_Libopencm3Dir();
i64 Amalgame_Compiler_McuCommand_Setup(code_bool assumeYes);

Amalgame_Compiler_McuCommand* Amalgame_Compiler_McuCommand_new() {
    Amalgame_Compiler_McuCommand* self = (Amalgame_Compiler_McuCommand*) GC_MALLOC(sizeof(Amalgame_Compiler_McuCommand));
    return self;
}

i64 Amalgame_Compiler_McuCommand_Run(i64 argc) {
    #line 21 "./src/mcu_cmd.am"
    code_string sub = Args_Get(2LL);
    #line 22 "./src/mcu_cmd.am"
    if (code_string_equals(sub, "doctor")) {
        return Amalgame_Compiler_McuCommand_Doctor();
    }
    #line 23 "./src/mcu_cmd.am"
    if (code_string_equals(sub, "setup")) {
        return Amalgame_Compiler_McuCommand_Setup(0);
    }
    #line 24 "./src/mcu_cmd.am"
    if (code_string_equals(sub, "setup-yes")) {
        return Amalgame_Compiler_McuCommand_Setup(1);
    }
    #line 25 "./src/mcu_cmd.am"
    Console_WriteError("Usage: amc mcu ");
    #line 26 "./src/mcu_cmd.am"
    Console_WriteError("  doctor   report installed / missing MCU tools");
    #line 27 "./src/mcu_cmd.am"
    Console_WriteError("  setup    install the MCU toolchain + libopencm3 (uses your package manager)");
    #line 28 "./src/mcu_cmd.am"
    if (((code_string_equals(sub, "-h")) || (code_string_equals(sub, "--help"))) || (String_Length(sub) == 0LL)) {
        return 0LL;
    }
    #line 29 "./src/mcu_cmd.am"
    return 1LL;
}

code_bool Amalgame_Compiler_McuCommand_IsWin() {
    #line 35 "./src/mcu_cmd.am"
    { /* inline-C */
        
                #ifdef _WIN32
                    return 1;
                #else
                    return 0;
                #endif
                
    }
}

code_bool Amalgame_Compiler_McuCommand_IsInteractive() {
    #line 44 "./src/mcu_cmd.am"
    { /* inline-C */
        
                #ifdef _WIN32
                    return _isatty(0) ? 1 : 0;
                #else
                    return isatty(0) ? 1 : 0;
                #endif
                
    }
}

code_string Amalgame_Compiler_McuCommand_DetectOs() {
    #line 55 "./src/mcu_cmd.am"
    if (Amalgame_Compiler_McuCommand_IsWin()) {
        return "windows";
    }
    #line 56 "./src/mcu_cmd.am"
    AmalgameProcessResult* uname = Process_RunCapture("uname -s 2>/dev/null");
    #line 57 "./src/mcu_cmd.am"
    if (String_Contains(uname->Stdout, "Darwin")) {
        return "macos";
    }
    #line 58 "./src/mcu_cmd.am"
    if (File_Exists("/etc/os-release")) {
        #line 59 "./src/mcu_cmd.am"
        code_string osr = File_ReadAll("/etc/os-release");
        #line 60 "./src/mcu_cmd.am"
        if (((String_Contains(osr, "ID=ubuntu") || String_Contains(osr, "ID=debian")) || String_Contains(osr, "ID_LIKE=debian")) || String_Contains(osr, "ID_LIKE=ubuntu")) {
            return "debian";
        }
        #line 61 "./src/mcu_cmd.am"
        if (((String_Contains(osr, "ID=fedora") || String_Contains(osr, "ID=rhel")) || String_Contains(osr, "rhel fedora")) || String_Contains(osr, "ID_LIKE=\"fedora")) {
            return "fedora";
        }
        #line 62 "./src/mcu_cmd.am"
        if (String_Contains(osr, "ID=arch") || String_Contains(osr, "ID_LIKE=arch")) {
            return "arch";
        }
    }
    #line 64 "./src/mcu_cmd.am"
    return "linux";
}

code_bool Amalgame_Compiler_McuCommand_Has(code_string tool) {
    #line 69 "./src/mcu_cmd.am"
    AmalgameProcessResult* p = Process_RunCapture(code_string_concat((code_string_concat("command -v '", tool)), "' >/dev/null 2>&1; echo $?"));
    #line 70 "./src/mcu_cmd.am"
    return String_Contains(p->Stdout, "0");
}

static void Amalgame_Compiler_McuCommand_Report(code_string tool, code_string role) {
    #line 74 "./src/mcu_cmd.am"
    code_string mark = "  [x] ";
    #line 75 "./src/mcu_cmd.am"
    if (!Amalgame_Compiler_McuCommand_Has(tool)) {
        mark = "  [ ] ";
    }
    #line 76 "./src/mcu_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat((code_string_concat(mark, tool)), "  — ")), role));
}

i64 Amalgame_Compiler_McuCommand_Doctor() {
    #line 80 "./src/mcu_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat("amc mcu doctor — MCU toolchain status (", Amalgame_Compiler_McuCommand_DetectOs())), ")"));
    #line 81 "./src/mcu_cmd.am"
    Amalgame_Compiler_McuCommand_Report("arm-none-eabi-gcc", "cross-compiler");
    #line 82 "./src/mcu_cmd.am"
    Amalgame_Compiler_McuCommand_Report("arm-none-eabi-objcopy", "binutils (.bin/.hex)");
    #line 83 "./src/mcu_cmd.am"
    Amalgame_Compiler_McuCommand_Report("openocd", "flash + on-chip gdb server");
    #line 84 "./src/mcu_cmd.am"
    Amalgame_Compiler_McuCommand_Report("gdb-multiarch", "debugger (or arm-none-eabi-gdb)");
    #line 85 "./src/mcu_cmd.am"
    Amalgame_Compiler_McuCommand_Report("st-info", "ST-LINK tools (optional)");
    #line 86 "./src/mcu_cmd.am"
    Amalgame_Compiler_McuCommand_Report("qemu-system-arm", "emulator (no-hardware testing)");
    #line 87 "./src/mcu_cmd.am"
    code_string lib = Amalgame_Compiler_McuCommand_Libopencm3Dir();
    #line 88 "./src/mcu_cmd.am"
    if (String_Length(lib) > 0LL) {
        #line 89 "./src/mcu_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat("  [x] libopencm3 — STM32 HAL (", lib)), ")"));
    } else {
        #line 91 "./src/mcu_cmd.am"
        Console_WriteLine("  [ ] libopencm3 — STM32 HAL (run `amc mcu setup`)");
    }
    #line 93 "./src/mcu_cmd.am"
    Console_WriteLine("");
    #line 94 "./src/mcu_cmd.am"
    Console_WriteLine("Missing tools? Run:  amc mcu setup");
    #line 95 "./src/mcu_cmd.am"
    return 0LL;
}

code_string Amalgame_Compiler_McuCommand_Libopencm3Dir() {
    #line 100 "./src/mcu_cmd.am"
    code_string envDir = Env_Get("LIBOPENCM3");
    #line 101 "./src/mcu_cmd.am"
    if ((String_Length(envDir) > 0LL) && File_Exists(code_string_concat(envDir, "/lib/libopencm3_stm32f7.a"))) {
        return envDir;
    }
    #line 102 "./src/mcu_cmd.am"
    code_string home = Env_Get("HOME");
    #line 103 "./src/mcu_cmd.am"
    if ((String_Length(home) > 0LL) && File_Exists(code_string_concat(home, "/libopencm3/lib/libopencm3_stm32f7.a"))) {
        #line 104 "./src/mcu_cmd.am"
        return code_string_concat(home, "/libopencm3");
    }
    #line 106 "./src/mcu_cmd.am"
    return "";
}

i64 Amalgame_Compiler_McuCommand_Setup(code_bool assumeYes) {
    #line 111 "./src/mcu_cmd.am"
    code_string os = Amalgame_Compiler_McuCommand_DetectOs();
    #line 112 "./src/mcu_cmd.am"
    Console_WriteLine(code_string_concat("amc mcu setup — detected OS: ", os));
    #line 114 "./src/mcu_cmd.am"
    code_string installCmd = "";
    #line 115 "./src/mcu_cmd.am"
    if (code_string_equals(os, "debian")) {
        #line 116 "./src/mcu_cmd.am"
        installCmd = "sudo apt-get update -qq && sudo apt-get install -y gcc-arm-none-eabi binutils-arm-none-eabi openocd gdb-multiarch stlink-tools qemu-system-arm git make";
    } else if (code_string_equals(os, "fedora")) {
        #line 118 "./src/mcu_cmd.am"
        installCmd = "sudo dnf install -y arm-none-eabi-gcc-cs arm-none-eabi-newlib arm-none-eabi-gdb openocd stlink qemu-system-arm git make";
    } else if (code_string_equals(os, "arch")) {
        #line 120 "./src/mcu_cmd.am"
        installCmd = "sudo pacman -S --needed --noconfirm arm-none-eabi-gcc arm-none-eabi-newlib arm-none-eabi-gdb openocd stlink qemu-arch-extra git make";
    } else if (code_string_equals(os, "macos")) {
        #line 122 "./src/mcu_cmd.am"
        installCmd = "brew install --cask gcc-arm-embedded ; brew install openocd stlink";
    } else if (code_string_equals(os, "windows")) {
        #line 124 "./src/mcu_cmd.am"
        installCmd = "winget install -e --id Arm.GnuArmEmbeddedToolchain && winget install -e --id xpack.openocd";
    } else {
        #line 126 "./src/mcu_cmd.am"
        Console_WriteError("amc mcu setup: unsupported OS. Install manually: arm-none-eabi-gcc, openocd, gdb-multiarch, qemu-system-arm, git, make");
        #line 127 "./src/mcu_cmd.am"
        return 1LL;
    }
    #line 130 "./src/mcu_cmd.am"
    Console_WriteLine("This will run:");
    #line 131 "./src/mcu_cmd.am"
    Console_WriteLine(code_string_concat("  ", installCmd));
    #line 132 "./src/mcu_cmd.am"
    if (!assumeYes) {
        #line 133 "./src/mcu_cmd.am"
        Console_Write("Proceed? [Y/n] ");
        #line 134 "./src/mcu_cmd.am"
        code_string ans = Console_ReadLine();
        #line 135 "./src/mcu_cmd.am"
        code_string a = String_ToLower(String_Trim(ans));
        #line 136 "./src/mcu_cmd.am"
        if ((code_string_equals(a, "n")) || (code_string_equals(a, "no"))) {
            #line 137 "./src/mcu_cmd.am"
            Console_WriteLine("aborted.");
            #line 138 "./src/mcu_cmd.am"
            return 1LL;
        }
    }
    #line 141 "./src/mcu_cmd.am"
    i64 r = Process_Run(installCmd);
    #line 142 "./src/mcu_cmd.am"
    if (r != 0LL) {
        #line 143 "./src/mcu_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("amc mcu setup: toolchain install failed (rc ", String_FromInt(r))), ")"));
        #line 144 "./src/mcu_cmd.am"
        return 1LL;
    }
    #line 149 "./src/mcu_cmd.am"
    if (!code_string_equals(os, "windows")) {
        #line 150 "./src/mcu_cmd.am"
        code_string home = Env_Get("HOME");
        #line 151 "./src/mcu_cmd.am"
        code_string dir = code_string_concat(home, "/libopencm3");
        #line 152 "./src/mcu_cmd.am"
        if (File_Exists(code_string_concat(dir, "/lib/libopencm3_stm32f7.a"))) {
            #line 153 "./src/mcu_cmd.am"
            Console_WriteLine(code_string_concat("libopencm3 already built at ", dir));
        } else {
            #line 155 "./src/mcu_cmd.am"
            Console_WriteLine(code_string_concat((code_string_concat("building libopencm3 (stm32/f7) at ", dir)), " …"));
            #line 156 "./src/mcu_cmd.am"
            code_string bc = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("if [ ! -d '", dir)), "/.git' ]; then git clone --depth 1 https://github.com/libopencm3/libopencm3 '")), dir)), "'; fi && make -C '")), dir)), "' TARGETS=stm32/f7");
            #line 157 "./src/mcu_cmd.am"
            i64 br = Process_Run(bc);
            #line 158 "./src/mcu_cmd.am"
            if (br != 0LL) {
                #line 159 "./src/mcu_cmd.am"
                Console_WriteError("amc mcu setup: libopencm3 build failed");
                #line 160 "./src/mcu_cmd.am"
                return 1LL;
            }
        }
    } else {
        #line 164 "./src/mcu_cmd.am"
        Console_WriteLine("On Windows, build libopencm3 under MSYS2 (`make TARGETS=stm32/f7`), then set LIBOPENCM3.");
    }
    #line 167 "./src/mcu_cmd.am"
    Console_WriteLine("");
    #line 168 "./src/mcu_cmd.am"
    Console_WriteLine("✓ MCU toolchain ready. amc auto-detects ~/libopencm3 — just build:");
    #line 169 "./src/mcu_cmd.am"
    Console_WriteLine("    amc build --target=cortex-m7 --board= --flash app.am -o fw");
    #line 170 "./src/mcu_cmd.am"
    return 0LL;
}

struct _Amalgame_Compiler_DocCommand {
};

i64 Amalgame_Compiler_DocCommand_Run(i64 argc);
static void Amalgame_Compiler_DocCommand_PrintUsage();
static code_string Amalgame_Compiler_DocCommand_EmitMarkdown(code_string path, Amalgame_Compiler_AstNode* prog, AmalgameList* comments);
static code_string Amalgame_Compiler_DocCommand_EmitClass(Amalgame_Compiler_AstNode* cls, AmalgameList* comments);
static code_string Amalgame_Compiler_DocCommand_EmitField(code_string clsName, Amalgame_Compiler_AstNode* field, AmalgameList* comments);
static code_string Amalgame_Compiler_DocCommand_EmitMethod(code_string clsName, Amalgame_Compiler_AstNode* method, AmalgameList* comments);
static code_string Amalgame_Compiler_DocCommand_EmitEnum(Amalgame_Compiler_AstNode* en, AmalgameList* comments);
static code_string Amalgame_Compiler_DocCommand_CollectCommentsBefore(AmalgameList* comments, i64 declLine, i64 indent);
static code_string Amalgame_Compiler_DocCommand_RenderRange(AmalgameList* comments, i64 lastIdx, i64 declLine, i64 indent);
static code_string Amalgame_Compiler_DocCommand_StripCommentMarker(code_string raw);
static code_string Amalgame_Compiler_DocCommand_Basename(code_string path);

Amalgame_Compiler_DocCommand* Amalgame_Compiler_DocCommand_new() {
    Amalgame_Compiler_DocCommand* self = (Amalgame_Compiler_DocCommand*) GC_MALLOC(sizeof(Amalgame_Compiler_DocCommand));
    return self;
}

i64 Amalgame_Compiler_DocCommand_Run(i64 argc) {
    #line 33 "./src/doc_cmd.am"
    Amalgame_Compiler_ArgParser* ap = Amalgame_Compiler_ArgParser_new();
    #line 34 "./src/doc_cmd.am"
    Amalgame_Compiler_ArgParser_Flag(ap, "-h");
    #line 35 "./src/doc_cmd.am"
    Amalgame_Compiler_ArgParser_Flag(ap, "--help");
    #line 36 "./src/doc_cmd.am"
    Amalgame_Compiler_ArgParser_Option(ap, "-o");
    #line 37 "./src/doc_cmd.am"
    Amalgame_Compiler_ArgParser_Parse(ap, argc, 2LL);
    #line 38 "./src/doc_cmd.am"
    if (Amalgame_Compiler_ArgParser_HelpRequested(ap)) {
        #line 39 "./src/doc_cmd.am"
        Amalgame_Compiler_DocCommand_PrintUsage();
        #line 40 "./src/doc_cmd.am"
        return 0LL;
    }
    #line 42 "./src/doc_cmd.am"
    if (String_Length(Amalgame_Compiler_ArgParser_GetUnknown(ap)) > 0LL) {
        #line 43 "./src/doc_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("amc doc: unknown argument '", Amalgame_Compiler_ArgParser_GetUnknown(ap))), "'"));
        #line 44 "./src/doc_cmd.am"
        return 1LL;
    }
    #line 46 "./src/doc_cmd.am"
    void* files = Amalgame_Compiler_ArgParser_GetPositionals(ap);
    #line 47 "./src/doc_cmd.am"
    if (AmalgameList_count(files) == 0LL) {
        #line 48 "./src/doc_cmd.am"
        Amalgame_Compiler_DocCommand_PrintUsage();
        #line 49 "./src/doc_cmd.am"
        return 1LL;
    }
    #line 51 "./src/doc_cmd.am"
    if (AmalgameList_count(files) > 1LL) {
        #line 52 "./src/doc_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("amc doc: pass exactly one .am file (got ", String_FromInt(AmalgameList_count(files)))), ")"));
        #line 53 "./src/doc_cmd.am"
        return 1LL;
    }
    #line 55 "./src/doc_cmd.am"
    code_string path = AmalgameList_get(files, 0LL);
    #line 56 "./src/doc_cmd.am"
    if (!String_EndsWith(path, ".am")) {
        #line 57 "./src/doc_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("amc doc: expected a .am file, got '", path)), "'"));
        #line 58 "./src/doc_cmd.am"
        return 1LL;
    }
    #line 60 "./src/doc_cmd.am"
    if (!File_Exists(path)) {
        #line 61 "./src/doc_cmd.am"
        Console_WriteError(code_string_concat("amc doc: file not found: ", path));
        #line 62 "./src/doc_cmd.am"
        return 1LL;
    }
    #line 64 "./src/doc_cmd.am"
    code_string src = File_ReadAll(path);
    #line 65 "./src/doc_cmd.am"
    Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(src, path);
    #line 66 "./src/doc_cmd.am"
    AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex);
    #line 67 "./src/doc_cmd.am"
    Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks);
    #line 68 "./src/doc_cmd.am"
    Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par);
    #line 69 "./src/doc_cmd.am"
    if (Amalgame_Compiler_Parser_HasErrors(par)) {
        #line 70 "./src/doc_cmd.am"
        Console_WriteError(code_string_concat("amc doc: parse errors in ", path));
        #line 71 "./src/doc_cmd.am"
        Console_WriteError(Amalgame_Compiler_Parser_GetErrors(par));
        #line 72 "./src/doc_cmd.am"
        return 1LL;
    }
    #line 74 "./src/doc_cmd.am"
    code_string md = Amalgame_Compiler_DocCommand_EmitMarkdown(path, prog, par->Comments);
    #line 75 "./src/doc_cmd.am"
    code_string outPath = Amalgame_Compiler_ArgParser_GetOption(ap, "-o");
    #line 76 "./src/doc_cmd.am"
    if (String_Length(outPath) > 0LL) {
        #line 77 "./src/doc_cmd.am"
        File_WriteAll(outPath, md);
        #line 78 "./src/doc_cmd.am"
        Console_WriteError(code_string_concat("amc doc: wrote ", outPath));
    } else {
        #line 80 "./src/doc_cmd.am"
        Console_Write(md);
    }
    #line 82 "./src/doc_cmd.am"
    return 0LL;
}

static void Amalgame_Compiler_DocCommand_PrintUsage() {
    #line 86 "./src/doc_cmd.am"
    Console_WriteError("Usage: amc doc  [-o ]");
    #line 87 "./src/doc_cmd.am"
    Console_WriteError("");
    #line 88 "./src/doc_cmd.am"
    Console_WriteError("Extract doc comments (leading `//` blocks before classes,");
    #line 89 "./src/doc_cmd.am"
    Console_WriteError("enums, public methods + fields) and emit a Markdown reference.");
    #line 90 "./src/doc_cmd.am"
    Console_WriteError("Default: stdout. With -o : write to that file.");
}

static code_string Amalgame_Compiler_DocCommand_EmitMarkdown(code_string path, Amalgame_Compiler_AstNode* prog, AmalgameList* comments) {
    #line 96 "./src/doc_cmd.am"
    code_string out = "";
    #line 99 "./src/doc_cmd.am"
    code_string ns = prog->Name;
    #line 100 "./src/doc_cmd.am"
    code_string heading = ns;
    #line 101 "./src/doc_cmd.am"
    if (String_Length(heading) == 0LL) {
        #line 102 "./src/doc_cmd.am"
        heading = Amalgame_Compiler_DocCommand_Basename(path);
    }
    #line 104 "./src/doc_cmd.am"
    out = (code_string_concat((code_string_concat((code_string_concat(out, "# ")), heading)), "\n\n"));
    #line 105 "./src/doc_cmd.am"
    out = (code_string_concat((code_string_concat((code_string_concat(out, "_Source: `")), path)), "`_\n\n"));
    #line 108 "./src/doc_cmd.am"
    i64 firstDeclLine = 999999999LL;
    #line 109 "./src/doc_cmd.am"
    i64 nc = AmalgameList_count(prog->Children);
    #line 110 "./src/doc_cmd.am"
    for (i64 i = 0LL; i < nc; i++) {
        #line 111 "./src/doc_cmd.am"
        Amalgame_Compiler_AstNode* d = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, i);
        #line 112 "./src/doc_cmd.am"
        if ((d->Line > 0LL) && (d->Line < firstDeclLine)) {
            firstDeclLine = d->Line;
        }
    }
    #line 114 "./src/doc_cmd.am"
    code_string intro = Amalgame_Compiler_DocCommand_CollectCommentsBefore(comments, firstDeclLine, 0LL);
    #line 115 "./src/doc_cmd.am"
    if (String_Length(intro) > 0LL) {
        #line 116 "./src/doc_cmd.am"
        out = (code_string_concat((code_string_concat(out, intro)), "\n"));
    }
    #line 120 "./src/doc_cmd.am"
    for (i64 j = 0LL; j < nc; j++) {
        #line 121 "./src/doc_cmd.am"
        Amalgame_Compiler_AstNode* decl = (Amalgame_Compiler_AstNode*)AmalgameList_get(prog->Children, j);
        #line 122 "./src/doc_cmd.am"
        Amalgame_Compiler_NodeKind k = decl->Kind;
        #line 123 "./src/doc_cmd.am"
        if (k == Amalgame_Compiler_NodeKind_CLASS_DECL) {
            #line 124 "./src/doc_cmd.am"
            out = (code_string_concat(out, Amalgame_Compiler_DocCommand_EmitClass(decl, comments)));
        } else if (k == Amalgame_Compiler_NodeKind_ENUM_DECL) {
            #line 126 "./src/doc_cmd.am"
            out = (code_string_concat(out, Amalgame_Compiler_DocCommand_EmitEnum(decl, comments)));
        }
    }
    #line 130 "./src/doc_cmd.am"
    return out;
}

static code_string Amalgame_Compiler_DocCommand_EmitClass(Amalgame_Compiler_AstNode* cls, AmalgameList* comments) {
    #line 134 "./src/doc_cmd.am"
    code_string out = code_string_concat((code_string_concat("## Class `", cls->Name)), "`\n\n");
    #line 135 "./src/doc_cmd.am"
    code_string lead = Amalgame_Compiler_DocCommand_CollectCommentsBefore(comments, cls->Line, 0LL);
    #line 136 "./src/doc_cmd.am"
    if (String_Length(lead) > 0LL) {
        out = (code_string_concat((code_string_concat(out, lead)), "\n"));
    }
    #line 140 "./src/doc_cmd.am"
    AmalgameList* kids = cls->Children;
    #line 141 "./src/doc_cmd.am"
    i64 mc = AmalgameList_count(kids);
    #line 142 "./src/doc_cmd.am"
    code_string fieldsOut = "";
    #line 143 "./src/doc_cmd.am"
    code_string methodsOut = "";
    #line 144 "./src/doc_cmd.am"
    for (i64 i = 0LL; i < mc; i++) {
        #line 145 "./src/doc_cmd.am"
        Amalgame_Compiler_AstNode* m = (Amalgame_Compiler_AstNode*)AmalgameList_get(kids, i);
        #line 146 "./src/doc_cmd.am"
        Amalgame_Compiler_NodeKind mk = m->Kind;
        #line 149 "./src/doc_cmd.am"
        if (m->Flag2) {
            continue;
        }
        #line 150 "./src/doc_cmd.am"
        if (mk == Amalgame_Compiler_NodeKind_VAR_DECL) {
            #line 151 "./src/doc_cmd.am"
            fieldsOut = (code_string_concat(fieldsOut, Amalgame_Compiler_DocCommand_EmitField(cls->Name, m, comments)));
        } else if (mk == Amalgame_Compiler_NodeKind_METHOD_DECL) {
            #line 153 "./src/doc_cmd.am"
            methodsOut = (code_string_concat(methodsOut, Amalgame_Compiler_DocCommand_EmitMethod(cls->Name, m, comments)));
        }
    }
    #line 156 "./src/doc_cmd.am"
    if (String_Length(fieldsOut) > 0LL) {
        #line 157 "./src/doc_cmd.am"
        out = (code_string_concat((code_string_concat(out, "### Fields\n\n")), fieldsOut));
    }
    #line 159 "./src/doc_cmd.am"
    if (String_Length(methodsOut) > 0LL) {
        #line 160 "./src/doc_cmd.am"
        out = (code_string_concat((code_string_concat(out, "### Methods\n\n")), methodsOut));
    }
    #line 162 "./src/doc_cmd.am"
    return code_string_concat(out, "\n");
}

static code_string Amalgame_Compiler_DocCommand_EmitField(code_string clsName, Amalgame_Compiler_AstNode* field, AmalgameList* comments) {
    #line 166 "./src/doc_cmd.am"
    code_string sig = code_string_concat((code_string_concat((code_string_concat((code_string_concat("- `", field->Name)), ": ")), field->Str)), "`");
    #line 167 "./src/doc_cmd.am"
    code_string out = code_string_concat(sig, "\n");
    #line 168 "./src/doc_cmd.am"
    code_string lead = Amalgame_Compiler_DocCommand_CollectCommentsBefore(comments, field->Line, 4LL);
    #line 169 "./src/doc_cmd.am"
    if (String_Length(lead) > 0LL) {
        out = (code_string_concat(out, lead));
    }
    #line 170 "./src/doc_cmd.am"
    out = (code_string_concat(out, "\n"));
    #line 171 "./src/doc_cmd.am"
    return out;
}

static code_string Amalgame_Compiler_DocCommand_EmitMethod(code_string clsName, Amalgame_Compiler_AstNode* method, AmalgameList* comments) {
    #line 176 "./src/doc_cmd.am"
    code_string sig = code_string_concat((code_string_concat((code_string_concat(clsName, ".")), method->Name)), "(");
    #line 177 "./src/doc_cmd.am"
    i64 pc = AmalgameList_count(method->Params);
    #line 178 "./src/doc_cmd.am"
    for (i64 pi = 0LL; pi < pc; pi++) {
        #line 179 "./src/doc_cmd.am"
        Amalgame_Compiler_AstNode* p = (Amalgame_Compiler_AstNode*)AmalgameList_get(method->Params, pi);
        #line 180 "./src/doc_cmd.am"
        if (pi > 0LL) {
            sig = (code_string_concat(sig, ", "));
        }
        #line 181 "./src/doc_cmd.am"
        sig = (code_string_concat(sig, p->Name));
        #line 182 "./src/doc_cmd.am"
        if (String_Length(p->Str) > 0LL) {
            #line 183 "./src/doc_cmd.am"
            sig = (code_string_concat((code_string_concat(sig, ": ")), p->Str));
        }
    }
    #line 186 "./src/doc_cmd.am"
    sig = (code_string_concat(sig, ")"));
    #line 187 "./src/doc_cmd.am"
    if ((String_Length(method->Str) > 0LL) && (!code_string_equals(method->Str, "void"))) {
        #line 188 "./src/doc_cmd.am"
        sig = (code_string_concat((code_string_concat(sig, " → ")), method->Str));
    }
    #line 190 "./src/doc_cmd.am"
    code_string out = code_string_concat((code_string_concat("#### `", sig)), "`\n\n");
    #line 191 "./src/doc_cmd.am"
    code_string lead = Amalgame_Compiler_DocCommand_CollectCommentsBefore(comments, method->Line, 0LL);
    #line 192 "./src/doc_cmd.am"
    if (String_Length(lead) > 0LL) {
        out = (code_string_concat((code_string_concat(out, lead)), "\n"));
    }
    #line 193 "./src/doc_cmd.am"
    return out;
}

static code_string Amalgame_Compiler_DocCommand_EmitEnum(Amalgame_Compiler_AstNode* en, AmalgameList* comments) {
    #line 197 "./src/doc_cmd.am"
    code_string out = code_string_concat((code_string_concat("## Enum `", en->Name)), "`\n\n");
    #line 198 "./src/doc_cmd.am"
    code_string lead = Amalgame_Compiler_DocCommand_CollectCommentsBefore(comments, en->Line, 0LL);
    #line 199 "./src/doc_cmd.am"
    if (String_Length(lead) > 0LL) {
        out = (code_string_concat((code_string_concat(out, lead)), "\n"));
    }
    #line 200 "./src/doc_cmd.am"
    AmalgameList* kids = en->Children;
    #line 201 "./src/doc_cmd.am"
    i64 n = AmalgameList_count(kids);
    #line 202 "./src/doc_cmd.am"
    if (n > 0LL) {
        #line 203 "./src/doc_cmd.am"
        out = (code_string_concat(out, "Variants:\n\n"));
        #line 204 "./src/doc_cmd.am"
        for (i64 i = 0LL; i < n; i++) {
            #line 205 "./src/doc_cmd.am"
            Amalgame_Compiler_AstNode* v = (Amalgame_Compiler_AstNode*)AmalgameList_get(kids, i);
            #line 206 "./src/doc_cmd.am"
            out = (code_string_concat((code_string_concat((code_string_concat(out, "- `")), v->Name)), "`\n"));
        }
        #line 208 "./src/doc_cmd.am"
        out = (code_string_concat(out, "\n"));
    }
    #line 210 "./src/doc_cmd.am"
    return out;
}

static code_string Amalgame_Compiler_DocCommand_CollectCommentsBefore(AmalgameList* comments, i64 declLine, i64 indent) {
    #line 221 "./src/doc_cmd.am"
    if (declLine <= 0LL) {
        return "";
    }
    #line 222 "./src/doc_cmd.am"
    i64 n = AmalgameList_count(comments);
    #line 224 "./src/doc_cmd.am"
    i64 lastIdx = -1LL;
    #line 225 "./src/doc_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 226 "./src/doc_cmd.am"
        Amalgame_Compiler_Token* c = (Amalgame_Compiler_Token*)AmalgameList_get(comments, i);
        #line 227 "./src/doc_cmd.am"
        if (c->Line < declLine) {
            lastIdx = i;
        } else {
            return Amalgame_Compiler_DocCommand_RenderRange(comments, lastIdx, declLine, indent);
        }
    }
    #line 229 "./src/doc_cmd.am"
    return Amalgame_Compiler_DocCommand_RenderRange(comments, lastIdx, declLine, indent);
}

static code_string Amalgame_Compiler_DocCommand_RenderRange(AmalgameList* comments, i64 lastIdx, i64 declLine, i64 indent) {
    #line 236 "./src/doc_cmd.am"
    if (lastIdx < 0LL) {
        return "";
    }
    #line 237 "./src/doc_cmd.am"
    Amalgame_Compiler_Token* last = (Amalgame_Compiler_Token*)AmalgameList_get(comments, lastIdx);
    #line 241 "./src/doc_cmd.am"
    if (last->Line != (declLine - 1LL)) {
        return "";
    }
    #line 243 "./src/doc_cmd.am"
    i64 startIdx = lastIdx;
    #line 244 "./src/doc_cmd.am"
    i64 prevLine = last->Line;
    #line 245 "./src/doc_cmd.am"
    i64 i = lastIdx - 1LL;
    #line 246 "./src/doc_cmd.am"
    while (i >= 0LL) {
        #line 247 "./src/doc_cmd.am"
        Amalgame_Compiler_Token* c = (Amalgame_Compiler_Token*)AmalgameList_get(comments, i);
        #line 248 "./src/doc_cmd.am"
        if (c->Line == (prevLine - 1LL)) {
            #line 249 "./src/doc_cmd.am"
            startIdx = i;
            #line 250 "./src/doc_cmd.am"
            prevLine = c->Line;
            #line 251 "./src/doc_cmd.am"
            i = (i - 1LL);
        } else {
            #line 253 "./src/doc_cmd.am"
            i = -1LL;
        }
    }
    #line 258 "./src/doc_cmd.am"
    code_string out = "";
    #line 259 "./src/doc_cmd.am"
    code_string pad = "";
    #line 260 "./src/doc_cmd.am"
    i64 p = 0LL;
    #line 261 "./src/doc_cmd.am"
    while (p < indent) {
        pad = (code_string_concat(pad, " "));
        p = (p + 1LL);
    }
    #line 262 "./src/doc_cmd.am"
    for (i64 k = startIdx; k < lastIdx + 1LL; k++) {
        #line 263 "./src/doc_cmd.am"
        Amalgame_Compiler_Token* c = (Amalgame_Compiler_Token*)AmalgameList_get(comments, k);
        #line 264 "./src/doc_cmd.am"
        code_string stripped = Amalgame_Compiler_DocCommand_StripCommentMarker(c->Value);
        #line 265 "./src/doc_cmd.am"
        out = (code_string_concat((code_string_concat((code_string_concat(out, pad)), stripped)), "\n"));
    }
    #line 267 "./src/doc_cmd.am"
    return out;
}

static code_string Amalgame_Compiler_DocCommand_StripCommentMarker(code_string raw) {
    #line 272 "./src/doc_cmd.am"
    code_string s = raw;
    #line 273 "./src/doc_cmd.am"
    if (String_StartsWith(s, "//")) {
        #line 274 "./src/doc_cmd.am"
        s = String_Substring(s, 2LL, String_Length(s) - 2LL);
    }
    #line 276 "./src/doc_cmd.am"
    return String_Trim(s);
}

static code_string Amalgame_Compiler_DocCommand_Basename(code_string path) {
    #line 280 "./src/doc_cmd.am"
    i64 sep = String_LastIndexOf(path, "/");
    #line 281 "./src/doc_cmd.am"
    if (sep < 0LL) {
        return path;
    }
    #line 282 "./src/doc_cmd.am"
    return String_Substring(path, sep + 1LL, (String_Length(path) - sep) - 1LL);
}

struct _Amalgame_Compiler_ArgParser {
    AmalgameList* RegisteredFlags;
    AmalgameList* SeenFlags;
    AmalgameList* RegisteredOptions;
    AmalgameList* OptionPairs;
    AmalgameList* Positionals;
    code_string Unknown;
};

Amalgame_Compiler_ArgParser* Amalgame_Compiler_ArgParser_Flag(Amalgame_Compiler_ArgParser* self, code_string name);
Amalgame_Compiler_ArgParser* Amalgame_Compiler_ArgParser_Option(Amalgame_Compiler_ArgParser* self, code_string name);
Amalgame_Compiler_ArgParser* Amalgame_Compiler_ArgParser_Parse(Amalgame_Compiler_ArgParser* self, i64 argc, i64 startIdx);
code_bool Amalgame_Compiler_ArgParser_HasFlag(Amalgame_Compiler_ArgParser* self, code_string name);
code_string Amalgame_Compiler_ArgParser_GetOption(Amalgame_Compiler_ArgParser* self, code_string name);
AmalgameList* Amalgame_Compiler_ArgParser_GetPositionals(Amalgame_Compiler_ArgParser* self);
code_string Amalgame_Compiler_ArgParser_GetUnknown(Amalgame_Compiler_ArgParser* self);
code_bool Amalgame_Compiler_ArgParser_HelpRequested(Amalgame_Compiler_ArgParser* self);
static code_bool Amalgame_Compiler_ArgParser_IsRegisteredFlag(Amalgame_Compiler_ArgParser* self, code_string name);
static code_bool Amalgame_Compiler_ArgParser_IsRegisteredOption(Amalgame_Compiler_ArgParser* self, code_string name);

Amalgame_Compiler_ArgParser* Amalgame_Compiler_ArgParser_new() {
    Amalgame_Compiler_ArgParser* self = (Amalgame_Compiler_ArgParser*) GC_MALLOC(sizeof(Amalgame_Compiler_ArgParser));
    #line 50 "./src/argparser.am"
    self->RegisteredFlags = AmalgameList_new();
    #line 51 "./src/argparser.am"
    self->SeenFlags = AmalgameList_new();
    #line 52 "./src/argparser.am"
    self->RegisteredOptions = AmalgameList_new();
    #line 53 "./src/argparser.am"
    self->OptionPairs = AmalgameList_new();
    #line 54 "./src/argparser.am"
    self->Positionals = AmalgameList_new();
    #line 55 "./src/argparser.am"
    self->Unknown = "";
    return self;
}

Amalgame_Compiler_ArgParser* Amalgame_Compiler_ArgParser_Flag(Amalgame_Compiler_ArgParser* self, code_string name) {
    #line 60 "./src/argparser.am"
    AmalgameList_add(self->RegisteredFlags, (void*)(intptr_t)(name));
    #line 61 "./src/argparser.am"
    return self;
}

Amalgame_Compiler_ArgParser* Amalgame_Compiler_ArgParser_Option(Amalgame_Compiler_ArgParser* self, code_string name) {
    #line 67 "./src/argparser.am"
    AmalgameList_add(self->RegisteredOptions, (void*)(intptr_t)(name));
    #line 68 "./src/argparser.am"
    return self;
}

Amalgame_Compiler_ArgParser* Amalgame_Compiler_ArgParser_Parse(Amalgame_Compiler_ArgParser* self, i64 argc, i64 startIdx) {
    #line 74 "./src/argparser.am"
    i64 i = startIdx;
    #line 75 "./src/argparser.am"
    while (i < argc) {
        #line 76 "./src/argparser.am"
        code_string a = Args_Get(i);
        #line 77 "./src/argparser.am"
        if (Amalgame_Compiler_ArgParser_IsRegisteredFlag(self, a)) {
            #line 78 "./src/argparser.am"
            AmalgameList_add(self->SeenFlags, (void*)(intptr_t)(a));
            #line 79 "./src/argparser.am"
            i = (i + 1LL);
            #line 80 "./src/argparser.am"
            continue;
        }
        #line 82 "./src/argparser.am"
        if (Amalgame_Compiler_ArgParser_IsRegisteredOption(self, a)) {
            #line 83 "./src/argparser.am"
            if ((i + 1LL) < argc) {
                #line 84 "./src/argparser.am"
                AmalgameList_add(self->OptionPairs, (void*)(intptr_t)(code_string_concat((code_string_concat(a, "=")), Args_Get(i + 1LL))));
                #line 85 "./src/argparser.am"
                i = (i + 2LL);
            } else {
                #line 90 "./src/argparser.am"
                if (String_Length(self->Unknown) == 0LL) {
                    #line 91 "./src/argparser.am"
                    self->Unknown = a;
                }
                #line 93 "./src/argparser.am"
                i = (i + 1LL);
            }
            #line 95 "./src/argparser.am"
            continue;
        }
        #line 97 "./src/argparser.am"
        if (String_StartsWith(a, "-")) {
            #line 98 "./src/argparser.am"
            if (String_Length(self->Unknown) == 0LL) {
                #line 99 "./src/argparser.am"
                self->Unknown = a;
            }
            #line 101 "./src/argparser.am"
            i = (i + 1LL);
            #line 102 "./src/argparser.am"
            continue;
        }
        #line 104 "./src/argparser.am"
        AmalgameList_add(self->Positionals, (void*)(intptr_t)(a));
        #line 105 "./src/argparser.am"
        i = (i + 1LL);
    }
    #line 107 "./src/argparser.am"
    return self;
}

code_bool Amalgame_Compiler_ArgParser_HasFlag(Amalgame_Compiler_ArgParser* self, code_string name) {
    #line 111 "./src/argparser.am"
    i64 n = AmalgameList_count(self->SeenFlags);
    #line 112 "./src/argparser.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 113 "./src/argparser.am"
        if (code_string_equals((code_string)AmalgameList_get(self->SeenFlags, i), name)) {
            return 1;
        }
    }
    #line 115 "./src/argparser.am"
    return 0;
}

code_string Amalgame_Compiler_ArgParser_GetOption(Amalgame_Compiler_ArgParser* self, code_string name) {
    #line 121 "./src/argparser.am"
    code_string prefix = code_string_concat(name, "=");
    #line 122 "./src/argparser.am"
    i64 plen = String_Length(prefix);
    #line 123 "./src/argparser.am"
    code_string result = "";
    #line 124 "./src/argparser.am"
    i64 n = AmalgameList_count(self->OptionPairs);
    #line 125 "./src/argparser.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 126 "./src/argparser.am"
        code_string v = (code_string)AmalgameList_get(self->OptionPairs, i);
        #line 127 "./src/argparser.am"
        if (String_StartsWith(v, prefix)) {
            #line 128 "./src/argparser.am"
            result = String_Substring(v, plen, String_Length(v) - plen);
        }
    }
    #line 131 "./src/argparser.am"
    return result;
}

AmalgameList* Amalgame_Compiler_ArgParser_GetPositionals(Amalgame_Compiler_ArgParser* self) {
    #line 134 "./src/argparser.am"
    return self->Positionals;
}

code_string Amalgame_Compiler_ArgParser_GetUnknown(Amalgame_Compiler_ArgParser* self) {
    #line 135 "./src/argparser.am"
    return self->Unknown;
}

code_bool Amalgame_Compiler_ArgParser_HelpRequested(Amalgame_Compiler_ArgParser* self) {
    #line 139 "./src/argparser.am"
    return Amalgame_Compiler_ArgParser_HasFlag(self, "-h") || Amalgame_Compiler_ArgParser_HasFlag(self, "--help");
}

static code_bool Amalgame_Compiler_ArgParser_IsRegisteredFlag(Amalgame_Compiler_ArgParser* self, code_string name) {
    #line 143 "./src/argparser.am"
    i64 n = AmalgameList_count(self->RegisteredFlags);
    #line 144 "./src/argparser.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 145 "./src/argparser.am"
        if (code_string_equals((code_string)AmalgameList_get(self->RegisteredFlags, i), name)) {
            return 1;
        }
    }
    #line 147 "./src/argparser.am"
    return 0;
}

static code_bool Amalgame_Compiler_ArgParser_IsRegisteredOption(Amalgame_Compiler_ArgParser* self, code_string name) {
    #line 151 "./src/argparser.am"
    i64 n = AmalgameList_count(self->RegisteredOptions);
    #line 152 "./src/argparser.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 153 "./src/argparser.am"
        if (code_string_equals((code_string)AmalgameList_get(self->RegisteredOptions, i), name)) {
            return 1;
        }
    }
    #line 155 "./src/argparser.am"
    return 0;
}

struct _Amalgame_Compiler_AddCommand {
};

static code_bool Amalgame_Compiler_AddCommand_MkdirP(code_string path);
static code_bool Amalgame_Compiler_AddCommand_RmRf(code_string path);
static code_bool Amalgame_Compiler_AddCommand_RenamePath(code_string from, code_string to);
static code_string Amalgame_Compiler_AddCommand_ListDir(code_string path);
void Amalgame_Compiler_AddCommand_PrintUsage();
i64 Amalgame_Compiler_AddCommand_Run(i64 argc, i64 startIdx);
i64 Amalgame_Compiler_AddCommand_RunOne(code_string spec, code_bool noPrecompile);
void Amalgame_Compiler_AddCommand_PrecompilePackage(code_string pkgDir, Amalgame_Compiler_TomlValue* stdlibTbl, code_string pkgVer);
void Amalgame_Compiler_AddCommand_PrecompileFacade(code_string pkgDir, Amalgame_Compiler_TomlValue* stdlibTbl, Amalgame_Compiler_TomlValue* depsTbl);
code_string Amalgame_Compiler_AddCommand_ResolveSelfPath();
i64 Amalgame_Compiler_AddCommand_NowSeconds();
code_string Amalgame_Compiler_AddCommand_HumanDuration(i64 seconds);
AmalgameList* Amalgame_Compiler_AddCommand_ParseSpec(code_string spec);
code_bool Amalgame_Compiler_AddCommand_IsSafeUrl(code_string url);
code_bool Amalgame_Compiler_AddCommand_IsSafeTag(code_string tag);
code_string Amalgame_Compiler_AddCommand_SlugFromUrl(code_string url);
code_string Amalgame_Compiler_AddCommand_DepNameFromSlug(code_string slug);
code_string Amalgame_Compiler_AddCommand_StripV(code_string tag);
code_string Amalgame_Compiler_AddCommand_CacheRoot();
code_string Amalgame_Compiler_AddCommand_IndexCachePath();
static code_bool Amalgame_Compiler_AddCommand_IsShortname(code_string lhs);
code_string Amalgame_Compiler_AddCommand_FetchIndex();
code_bool Amalgame_Compiler_AddCommand_IndexCacheIsFresh(code_string cachePath);
i64 Amalgame_Compiler_AddCommand_RunPackage(i64 argc);
void Amalgame_Compiler_AddCommand_PrintPackageUsage();
i64 Amalgame_Compiler_AddCommand_RunVersions(i64 argc, i64 startIdx);
i64 Amalgame_Compiler_AddCommand_EnsureInstalled();
i64 Amalgame_Compiler_AddCommand_RunCache(i64 argc, i64 startIdx);
i64 Amalgame_Compiler_AddCommand_RunUpdate(i64 argc, i64 startIdx);
i64 Amalgame_Compiler_AddCommand_RunInstallSpec(code_string spec);
i64 Amalgame_Compiler_AddCommand_RunList(i64 argc, i64 startIdx);
i64 Amalgame_Compiler_AddCommand_RunRemove(i64 argc, i64 startIdx);
void Amalgame_Compiler_AddCommand_RebuildLockFromTomlDeps(Amalgame_Compiler_TomlValue* depsTable, code_string lockPath);
i64 Amalgame_Compiler_AddCommand_RunSearch(i64 argc, i64 startIdx);
void Amalgame_Compiler_AddCommand_PrintVersionsForPackage(Amalgame_Compiler_TomlValue* verArr, code_string pkgName, code_string amcVer);
void Amalgame_Compiler_AddCommand_PrintVersionsJsonForPackage(Amalgame_Compiler_TomlValue* verArr, code_string pkgName, code_string urlS, code_string amcVer);
i64 Amalgame_Compiler_AddCommand_RunSuggest(i64 argc, i64 startIdx);
Amalgame_Compiler_TomlValue* Amalgame_Compiler_AddCommand_FindPackageByName(Amalgame_Compiler_TomlValue* pkgArr, code_string target);
code_string Amalgame_Compiler_AddCommand_LatestCompatibleTag(Amalgame_Compiler_TomlValue* verArr, code_string pkgName, code_string amcVer);
code_string Amalgame_Compiler_AddCommand_JsonEscape(code_string s);
i64 Amalgame_Compiler_AddCommand_RunInfo(i64 argc, i64 startIdx);
i64 Amalgame_Compiler_AddCommand_RunOutdated(i64 argc, i64 startIdx);
i64 Amalgame_Compiler_AddCommand_RunCheck(i64 argc, i64 startIdx);
i64 Amalgame_Compiler_AddCommand_RunNotice(i64 argc, i64 startIdx);
code_string Amalgame_Compiler_AddCommand_LastUrlSegment(code_string url);
code_string Amalgame_Compiler_AddCommand_ResolveLatestCompatible(code_string shortname);
code_string Amalgame_Compiler_AddCommand_ResolveShortname(code_string spec);
AmalgameList* Amalgame_Compiler_AddCommand_AllCachedRuntimeDirs();
code_string Amalgame_Compiler_AddCommand_LatestCacheRuntimeDir(code_string depKey);
code_string Amalgame_Compiler_AddCommand_ShortnameFromDepKey(code_string depKey);
code_string Amalgame_Compiler_AddCommand_FindExistingForTag(code_string baseDir, code_string tag);
code_string Amalgame_Compiler_AddCommand_ExtractRevFromDirName(code_string dir);
code_bool Amalgame_Compiler_AddCommand_UpdateProjectManifest(code_string depName, code_string url, code_string tag);
code_bool Amalgame_Compiler_AddCommand_UpdateLockFile(code_string depName, code_string url, code_string tag, code_string rev);

Amalgame_Compiler_AddCommand* Amalgame_Compiler_AddCommand_new() {
    Amalgame_Compiler_AddCommand* self = (Amalgame_Compiler_AddCommand*) GC_MALLOC(sizeof(Amalgame_Compiler_AddCommand));
    return self;
}

static code_bool Amalgame_Compiler_AddCommand_MkdirP(code_string path) {
    #line 231 "./src/add_cmd.am"
    i64 r = 0LL;
    #line 232 "./src/add_cmd.am"
    { /* inline-C */
         r = (i64) amalgame_pm_mkdirp(path); 
    }
    #line 233 "./src/add_cmd.am"
    return r != 0LL;
}

static code_bool Amalgame_Compiler_AddCommand_RmRf(code_string path) {
    #line 238 "./src/add_cmd.am"
    i64 r = 0LL;
    #line 239 "./src/add_cmd.am"
    { /* inline-C */
         r = (i64) amalgame_pm_rmrf(path); 
    }
    #line 240 "./src/add_cmd.am"
    return r != 0LL;
}

static code_bool Amalgame_Compiler_AddCommand_RenamePath(code_string from, code_string to) {
    #line 245 "./src/add_cmd.am"
    i64 r = 0LL;
    #line 246 "./src/add_cmd.am"
    { /* inline-C */
         r = (i64) amalgame_pm_rename(from, to); 
    }
    #line 247 "./src/add_cmd.am"
    return r != 0LL;
}

static code_string Amalgame_Compiler_AddCommand_ListDir(code_string path) {
    #line 253 "./src/add_cmd.am"
    { /* inline-C */
         return amalgame_pm_listdir(path); 
    }
}

void Amalgame_Compiler_AddCommand_PrintUsage() {
    #line 257 "./src/add_cmd.am"
    Console_WriteError("Usage: amc package add ... [--no-precompile]");
    #line 258 "./src/add_cmd.am"
    Console_WriteError("");
    #line 259 "./src/add_cmd.am"
    Console_WriteError("Install one or more Amalgame packages into the user cache and");
    #line 260 "./src/add_cmd.am"
    Console_WriteError("record them in amalgame.toml + amalgame.lock. Multiple specs");
    #line 261 "./src/add_cmd.am"
    Console_WriteError("install in order and stop on the first failure.");
    #line 262 "./src/add_cmd.am"
    Console_WriteError("");
    #line 263 "./src/add_cmd.am"
    Console_WriteError("Two spec forms:");
    #line 264 "./src/add_cmd.am"
    Console_WriteError("  [@]   resolved via amalgame-lang/packages-index.");
    #line 265 "./src/add_cmd.am"
    Console_WriteError("                        When @ is omitted, the latest tag whose");
    #line 266 "./src/add_cmd.am"
    Console_WriteError("                        [package].required-amalgame is satisfied by");
    #line 267 "./src/add_cmd.am"
    Console_WriteError("                        your running amc is picked automatically.");
    #line 268 "./src/add_cmd.am"
    Console_WriteError("  @       full git URL form for unindexed packages;");
    #line 269 "./src/add_cmd.am"
    Console_WriteError("                        @ is mandatory (no auto-resolve).");
    #line 270 "./src/add_cmd.am"
    Console_WriteError("");
    #line 271 "./src/add_cmd.am"
    Console_WriteError("Examples:");
    #line 272 "./src/add_cmd.am"
    Console_WriteError("  amc package add duckdb                              # auto-resolve");
    #line 273 "./src/add_cmd.am"
    Console_WriteError("  amc package add sqlite@v0.2.0");
    #line 274 "./src/add_cmd.am"
    Console_WriteError("  amc package add github.com/foo/bar@v1.2.3");
    #line 275 "./src/add_cmd.am"
    Console_WriteError("  amc package add ui-sdl ui-forms                     # multi-spec");
    #line 276 "./src/add_cmd.am"
    Console_WriteError("");
    #line 277 "./src/add_cmd.am"
    Console_WriteError("Cache: ~/.amalgame/packages////_/");
    #line 278 "./src/add_cmd.am"
    Console_WriteError("");
    #line 279 "./src/add_cmd.am"
    Console_WriteError("Validation performed on install:");
    #line 280 "./src/add_cmd.am"
    Console_WriteError("  - manifest amalgame.toml exists at repo root");
    #line 281 "./src/add_cmd.am"
    Console_WriteError("  - [package].name matches the URL repo slug");
    #line 282 "./src/add_cmd.am"
    Console_WriteError("  - [package].version matches the tag");
    #line 283 "./src/add_cmd.am"
    Console_WriteError("  - [package].license is declared");
    #line 284 "./src/add_cmd.am"
    Console_WriteError("  - [package].required-amalgame (if present) is satisfied by");
    #line 285 "./src/add_cmd.am"
    Console_WriteError("    the running amc. Supports >=, >, <, <=, =, ^, ~, and bare");
    #line 286 "./src/add_cmd.am"
    Console_WriteError("    (treated as >= for back-compat).");
    #line 287 "./src/add_cmd.am"
    Console_WriteError("");
    #line 288 "./src/add_cmd.am"
    Console_WriteError("Flags:");
    #line 289 "./src/add_cmd.am"
    Console_WriteError("  --no-precompile   Skip install-time compile even if the package's");
    #line 290 "./src/add_cmd.am"
    Console_WriteError("                    manifest opts in via [stdlib].precompile = true.");
    #line 291 "./src/add_cmd.am"
    Console_WriteError("                    Useful in CI batch installs where you want to");
    #line 292 "./src/add_cmd.am"
    Console_WriteError("                    separate install from build.");
    #line 293 "./src/add_cmd.am"
    Console_WriteError("  -h, --help        Print this help and exit.");
}

i64 Amalgame_Compiler_AddCommand_Run(i64 argc, i64 startIdx) {
    #line 297 "./src/add_cmd.am"
    AmalgameList* specs = AmalgameList_new();
    #line 298 "./src/add_cmd.am"
    code_bool noPrecompile = 0;
    #line 299 "./src/add_cmd.am"
    i64 i = startIdx;
    #line 300 "./src/add_cmd.am"
    while (i < argc) {
        #line 301 "./src/add_cmd.am"
        code_string a = Args_Get(i);
        #line 302 "./src/add_cmd.am"
        if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) {
            #line 303 "./src/add_cmd.am"
            Amalgame_Compiler_AddCommand_PrintUsage();
            #line 304 "./src/add_cmd.am"
            return 0LL;
        }
        #line 306 "./src/add_cmd.am"
        if (code_string_equals(a, "--no-precompile")) {
            #line 307 "./src/add_cmd.am"
            noPrecompile = 1;
            #line 308 "./src/add_cmd.am"
            i = (i + 1LL);
            #line 309 "./src/add_cmd.am"
            continue;
        }
        #line 311 "./src/add_cmd.am"
        if (String_StartsWith(a, "-")) {
            #line 312 "./src/add_cmd.am"
            Console_WriteError(code_string_concat("unknown flag: ", a));
            #line 313 "./src/add_cmd.am"
            Amalgame_Compiler_AddCommand_PrintUsage();
            #line 314 "./src/add_cmd.am"
            return 2LL;
        }
        #line 321 "./src/add_cmd.am"
        AmalgameList_add(specs, (void*)(intptr_t)(a));
        #line 322 "./src/add_cmd.am"
        i = (i + 1LL);
    }
    #line 324 "./src/add_cmd.am"
    if (AmalgameList_count(specs) == 0LL) {
        #line 325 "./src/add_cmd.am"
        Console_WriteError("missing @ or ");
        #line 326 "./src/add_cmd.am"
        Amalgame_Compiler_AddCommand_PrintUsage();
        #line 327 "./src/add_cmd.am"
        return 2LL;
    }
    #line 330 "./src/add_cmd.am"
    i64 nSpecs = AmalgameList_count(specs);
    #line 331 "./src/add_cmd.am"
    i64 si = 0LL;
    #line 332 "./src/add_cmd.am"
    while (si < nSpecs) {
        #line 333 "./src/add_cmd.am"
        code_string s = (code_string)AmalgameList_get(specs, si);
        #line 334 "./src/add_cmd.am"
        if (nSpecs > 1LL) {
            #line 335 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("── Installing ", s)), " (")), String_FromInt(si + 1LL))), "/")), String_FromInt(nSpecs))), ") ──"));
        }
        #line 337 "./src/add_cmd.am"
        i64 rc = Amalgame_Compiler_AddCommand_RunOne(s, noPrecompile);
        #line 338 "./src/add_cmd.am"
        if (rc != 0LL) {
            return rc;
        }
        #line 339 "./src/add_cmd.am"
        si = (si + 1LL);
    }
    #line 341 "./src/add_cmd.am"
    return 0LL;
}

i64 Amalgame_Compiler_AddCommand_RunOne(code_string spec, code_bool noPrecompile) {
    #line 355 "./src/add_cmd.am"
    code_string workingSpec = spec;
    #line 356 "./src/add_cmd.am"
    i64 hasAt = String_IndexOf(spec, "@");
    #line 357 "./src/add_cmd.am"
    if (hasAt < 0LL) {
        #line 358 "./src/add_cmd.am"
        if (!Amalgame_Compiler_AddCommand_IsShortname(spec)) {
            #line 359 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat("'", spec)), "' is a git URL — it needs an explicit @."));
            #line 360 "./src/add_cmd.am"
            Console_WriteError("       Auto-resolve (no @) only works for indexed shortnames.");
            #line 361 "./src/add_cmd.am"
            return 2LL;
        }
        #line 363 "./src/add_cmd.am"
        code_string resolvedTag = Amalgame_Compiler_AddCommand_ResolveLatestCompatible(spec);
        #line 364 "./src/add_cmd.am"
        if (String_Length(resolvedTag) == 0LL) {
            #line 366 "./src/add_cmd.am"
            return 1LL;
        }
        #line 368 "./src/add_cmd.am"
        workingSpec = (code_string_concat((code_string_concat(spec, "@")), resolvedTag));
        #line 369 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("Auto-resolved '", spec)), "' → '")), spec)), "@")), resolvedTag)), "' (latest compatible with amc ")), Amalgame_Compiler_PackageRegistry_AmcVersion())), ")"));
    }
    #line 377 "./src/add_cmd.am"
    code_string resolvedSpec = Amalgame_Compiler_AddCommand_ResolveShortname(workingSpec);
    #line 380 "./src/add_cmd.am"
    AmalgameList* parsed = Amalgame_Compiler_AddCommand_ParseSpec(resolvedSpec);
    #line 381 "./src/add_cmd.am"
    if (AmalgameList_count(parsed) != 2LL) {
        #line 382 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("expected @ or @ — got '", spec)), "'"));
        #line 383 "./src/add_cmd.am"
        return 2LL;
    }
    #line 385 "./src/add_cmd.am"
    code_string url = (code_string)AmalgameList_get(parsed, 0LL);
    #line 386 "./src/add_cmd.am"
    code_string tag = (code_string)AmalgameList_get(parsed, 1LL);
    #line 387 "./src/add_cmd.am"
    if (!Amalgame_Compiler_AddCommand_IsSafeUrl(url)) {
        #line 388 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("rejected url '", url)), "' — only [A-Za-z0-9./_:-] allowed"));
        #line 389 "./src/add_cmd.am"
        return 2LL;
    }
    #line 391 "./src/add_cmd.am"
    if (!Amalgame_Compiler_AddCommand_IsSafeTag(tag)) {
        #line 392 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("rejected tag '", tag)), "' — only [A-Za-z0-9._+-] allowed"));
        #line 393 "./src/add_cmd.am"
        return 2LL;
    }
    #line 397 "./src/add_cmd.am"
    code_string pkgName = Amalgame_Compiler_AddCommand_SlugFromUrl(url);
    #line 398 "./src/add_cmd.am"
    if (String_Length(pkgName) == 0LL) {
        #line 399 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("could not derive package name from url '", url)), "'"));
        #line 400 "./src/add_cmd.am"
        return 2LL;
    }
    #line 408 "./src/add_cmd.am"
    code_string depName = Amalgame_Compiler_AddCommand_DepNameFromSlug(pkgName);
    #line 410 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat("Resolving ", url)), "@")), tag)), "..."));
    #line 413 "./src/add_cmd.am"
    code_string cacheRoot = Amalgame_Compiler_AddCommand_CacheRoot();
    #line 414 "./src/add_cmd.am"
    code_string baseDir = code_string_concat((code_string_concat(cacheRoot, "/")), url);
    #line 417 "./src/add_cmd.am"
    code_bool _mk = Amalgame_Compiler_AddCommand_MkdirP(baseDir);
    #line 424 "./src/add_cmd.am"
    code_string existingDir = Amalgame_Compiler_AddCommand_FindExistingForTag(baseDir, tag);
    #line 425 "./src/add_cmd.am"
    code_string pkgDir = "";
    #line 426 "./src/add_cmd.am"
    code_string rev = "";
    #line 427 "./src/add_cmd.am"
    if (String_Length(existingDir) > 0LL) {
        #line 428 "./src/add_cmd.am"
        pkgDir = existingDir;
        #line 429 "./src/add_cmd.am"
        rev = Amalgame_Compiler_AddCommand_ExtractRevFromDirName(pkgDir);
        #line 430 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat("Already cached at ", pkgDir));
    } else {
        #line 432 "./src/add_cmd.am"
        code_string tmpDir = code_string_concat((code_string_concat((code_string_concat(baseDir, "/")), tag)), "_clone");
        #line 434 "./src/add_cmd.am"
        code_bool _wipe = Amalgame_Compiler_AddCommand_RmRf(tmpDir);
        #line 435 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat("Cloning into ", tmpDir)), "..."));
        #line 438 "./src/add_cmd.am"
        code_string cloneCmd = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("git clone --depth 1 --branch \"", tag)), "\" \"https://")), url)), ".git\" \"")), tmpDir)), "\" 2>&1");
        #line 439 "./src/add_cmd.am"
        i64 cloneExit = Process_Run(cloneCmd);
        #line 440 "./src/add_cmd.am"
        if (cloneExit != 0LL) {
            #line 441 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat("git clone failed (exit ", String_FromInt(cloneExit))), ")"));
            #line 442 "./src/add_cmd.am"
            code_bool _wipe2 = Amalgame_Compiler_AddCommand_RmRf(tmpDir);
            #line 443 "./src/add_cmd.am"
            return 1LL;
        }
        #line 446 "./src/add_cmd.am"
        AmalgameProcessResult* revRes = Process_RunCapture(code_string_concat((code_string_concat("git -C \"", tmpDir)), "\" rev-parse HEAD 2>&1"));
        #line 447 "./src/add_cmd.am"
        if (revRes->Exit != 0LL) {
            #line 448 "./src/add_cmd.am"
            Console_WriteError(code_string_concat("git rev-parse failed: ", revRes->Stdout));
            #line 449 "./src/add_cmd.am"
            code_bool _wipe3 = Amalgame_Compiler_AddCommand_RmRf(tmpDir);
            #line 450 "./src/add_cmd.am"
            return 1LL;
        }
        #line 452 "./src/add_cmd.am"
        rev = String_Trim(revRes->Stdout);
        #line 453 "./src/add_cmd.am"
        if (String_Length(rev) < 7LL) {
            #line 454 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat("invalid HEAD sha: '", rev)), "'"));
            #line 455 "./src/add_cmd.am"
            code_bool _wipe4 = Amalgame_Compiler_AddCommand_RmRf(tmpDir);
            #line 456 "./src/add_cmd.am"
            return 1LL;
        }
        #line 458 "./src/add_cmd.am"
        code_string shortSha = String_Substring(rev, 0LL, 8LL);
        #line 459 "./src/add_cmd.am"
        pkgDir = (code_string_concat((code_string_concat((code_string_concat((code_string_concat(baseDir, "/")), tag)), "_")), shortSha));
        #line 461 "./src/add_cmd.am"
        if (!Amalgame_Compiler_AddCommand_RenamePath(tmpDir, pkgDir)) {
            #line 462 "./src/add_cmd.am"
            Console_WriteError("could not finalize cache directory");
            #line 463 "./src/add_cmd.am"
            return 1LL;
        }
        #line 466 "./src/add_cmd.am"
        code_bool _gitWipe = Amalgame_Compiler_AddCommand_RmRf(code_string_concat(pkgDir, "/.git"));
    }
    #line 470 "./src/add_cmd.am"
    code_string manifestPath = code_string_concat(pkgDir, "/amalgame.toml");
    #line 471 "./src/add_cmd.am"
    if (!File_Exists(manifestPath)) {
        #line 472 "./src/add_cmd.am"
        Console_WriteError(code_string_concat("not an Amalgame package: missing ", manifestPath));
        #line 473 "./src/add_cmd.am"
        return 1LL;
    }
    #line 475 "./src/add_cmd.am"
    code_string manifestSrc = File_ReadAll(manifestPath);
    #line 476 "./src/add_cmd.am"
    Amalgame_Compiler_TomlParser* parser = Amalgame_Compiler_TomlParser_new(manifestSrc);
    #line 477 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* manifest = Amalgame_Compiler_Toml_ParseWithError(manifestSrc, parser);
    #line 478 "./src/add_cmd.am"
    if (parser->HasError) {
        #line 479 "./src/add_cmd.am"
        Console_WriteError(code_string_concat("malformed amalgame.toml: ", parser->ErrMsg));
        #line 480 "./src/add_cmd.am"
        return 1LL;
    }
    #line 482 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* pkgTable = Amalgame_Compiler_TomlValue_Get(manifest, "package");
    #line 483 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsTable(pkgTable)) {
        #line 484 "./src/add_cmd.am"
        Console_WriteError("amalgame.toml missing [package] table");
        #line 485 "./src/add_cmd.am"
        return 1LL;
    }
    #line 487 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* mfName = Amalgame_Compiler_TomlValue_Get(pkgTable, "name");
    #line 488 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* mfVer = Amalgame_Compiler_TomlValue_Get(pkgTable, "version");
    #line 489 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* mfLic = Amalgame_Compiler_TomlValue_Get(pkgTable, "license");
    #line 490 "./src/add_cmd.am"
    code_string mfNameStr = Amalgame_Compiler_TomlValue_AsString(mfName);
    #line 491 "./src/add_cmd.am"
    code_string mfVerStr = Amalgame_Compiler_TomlValue_AsString(mfVer);
    #line 492 "./src/add_cmd.am"
    code_string mfLicStr = Amalgame_Compiler_TomlValue_AsString(mfLic);
    #line 493 "./src/add_cmd.am"
    if (String_Length(mfNameStr) == 0LL) {
        #line 494 "./src/add_cmd.am"
        Console_WriteError("amalgame.toml missing [package].name");
        #line 495 "./src/add_cmd.am"
        return 1LL;
    }
    #line 497 "./src/add_cmd.am"
    if (String_Length(mfVerStr) == 0LL) {
        #line 498 "./src/add_cmd.am"
        Console_WriteError("amalgame.toml missing [package].version");
        #line 499 "./src/add_cmd.am"
        return 1LL;
    }
    #line 501 "./src/add_cmd.am"
    if (String_Length(mfLicStr) == 0LL) {
        #line 502 "./src/add_cmd.am"
        Console_WriteError("amalgame.toml missing [package].license — declare your distribution licence");
        #line 503 "./src/add_cmd.am"
        return 1LL;
    }
    #line 510 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* mfReq = Amalgame_Compiler_TomlValue_Get(pkgTable, "required-amalgame");
    #line 511 "./src/add_cmd.am"
    code_string mfReqStr = Amalgame_Compiler_TomlValue_AsString(mfReq);
    #line 512 "./src/add_cmd.am"
    if (String_Length(mfReqStr) > 0LL) {
        #line 513 "./src/add_cmd.am"
        code_string amc = Amalgame_Compiler_PackageRegistry_AmcVersion();
        #line 514 "./src/add_cmd.am"
        if (!Amalgame_Compiler_PackageRegistry_VersionSatisfies(amc, mfReqStr)) {
            #line 515 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("amalgame-", mfNameStr)), " ")), tag)), " requires amc ")), mfReqStr));
            #line 516 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat("       your amc is ", amc)), " — upgrade and retry"));
            #line 517 "./src/add_cmd.am"
            return 1LL;
        }
    }
    #line 526 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* mfSchema = Amalgame_Compiler_TomlValue_Get(pkgTable, "schema-version");
    #line 527 "./src/add_cmd.am"
    i64 mfSchemaInt = Amalgame_Compiler_TomlValue_AsInt(mfSchema);
    #line 528 "./src/add_cmd.am"
    i64 supported = Amalgame_Compiler_PackageRegistry_SupportedManifestSchema();
    #line 529 "./src/add_cmd.am"
    if (mfSchemaInt > supported) {
        #line 530 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("amalgame-", mfNameStr)), " ")), tag)), " requires manifest schema v")), String_FromInt(mfSchemaInt)));
        #line 531 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("       your amc supports up to v", String_FromInt(supported))), " — upgrade and retry"));
        #line 532 "./src/add_cmd.am"
        return 1LL;
    }
    #line 534 "./src/add_cmd.am"
    if (!code_string_equals(mfNameStr, pkgName)) {
        #line 535 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat("manifest name '", mfNameStr)), "' does not match URL slug '")), pkgName)), "'"));
        #line 536 "./src/add_cmd.am"
        return 1LL;
    }
    #line 547 "./src/add_cmd.am"
    code_string expectedVer = Amalgame_Compiler_AddCommand_StripV(tag);
    #line 548 "./src/add_cmd.am"
    code_string mfBase = mfVerStr;
    #line 549 "./src/add_cmd.am"
    if (String_EndsWith(mfBase, "-dev")) {
        #line 550 "./src/add_cmd.am"
        mfBase = String_Substring(mfBase, 0LL, String_Length(mfBase) - 4LL);
    }
    #line 552 "./src/add_cmd.am"
    if (!code_string_equals(mfBase, expectedVer)) {
        #line 553 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("manifest version '", mfVerStr)), "' does not match tag '")), tag)), "' (expected '")), expectedVer)), "' or '")), expectedVer)), "-dev')"));
        #line 554 "./src/add_cmd.am"
        return 1LL;
    }
    #line 557 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("Validated ", mfNameStr)), " v")), mfVerStr)), " (licence ")), mfLicStr)), ")"));
    #line 558 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat("Cached at ", pkgDir));
    #line 584 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* depsTable = Amalgame_Compiler_TomlValue_Get(manifest, "dependencies");
    #line 585 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsTable(depsTable)) {
        #line 586 "./src/add_cmd.am"
        AmalgameList* depKeys = Amalgame_Compiler_TomlValue_Keys(depsTable);
        #line 587 "./src/add_cmd.am"
        i64 ndep = AmalgameList_count(depKeys);
        #line 588 "./src/add_cmd.am"
        for (i64 di = 0LL; di < ndep; di++) {
            #line 589 "./src/add_cmd.am"
            code_string depKey = (code_string)AmalgameList_get(depKeys, di);
            #line 590 "./src/add_cmd.am"
            Amalgame_Compiler_TomlValue* depVal = Amalgame_Compiler_TomlValue_Get(depsTable, depKey);
            #line 591 "./src/add_cmd.am"
            code_string transSpec = "";
            #line 592 "./src/add_cmd.am"
            if (Amalgame_Compiler_TomlValue_IsString(depVal)) {
                #line 601 "./src/add_cmd.am"
                transSpec = Amalgame_Compiler_AddCommand_ShortnameFromDepKey(depKey);
            } else if (Amalgame_Compiler_TomlValue_IsTable(depVal)) {
                #line 603 "./src/add_cmd.am"
                code_string depGit = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(depVal, "git"));
                #line 604 "./src/add_cmd.am"
                code_string depTag = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(depVal, "tag"));
                #line 605 "./src/add_cmd.am"
                if ((String_Length(depGit) > 0LL) && (String_Length(depTag) > 0LL)) {
                    #line 606 "./src/add_cmd.am"
                    transSpec = (code_string_concat((code_string_concat(depGit, "@")), depTag));
                }
            }
            #line 609 "./src/add_cmd.am"
            if (String_Length(transSpec) == 0LL) {
                #line 610 "./src/add_cmd.am"
                Console_WriteError(code_string_concat((code_string_concat((code_string_concat("[", mfNameStr)), "]: unrecognised dependency entry: ")), depKey));
                #line 611 "./src/add_cmd.am"
                return 1LL;
            }
            #line 619 "./src/add_cmd.am"
            code_string depCached = Amalgame_Compiler_AddCommand_LatestCacheRuntimeDir(depKey);
            #line 620 "./src/add_cmd.am"
            if (String_Length(depCached) > 0LL) {
                #line 621 "./src/add_cmd.am"
                Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat("── ", mfNameStr)), " depends on ")), depKey)), " — already cached, reusing ──"));
                #line 622 "./src/add_cmd.am"
                continue;
            }
            #line 624 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat("── ", mfNameStr)), " depends on ")), depKey)), " — auto-installing ──"));
            #line 625 "./src/add_cmd.am"
            i64 trc = Amalgame_Compiler_AddCommand_RunOne(transSpec, noPrecompile);
            #line 626 "./src/add_cmd.am"
            if (trc != 0LL) {
                #line 627 "./src/add_cmd.am"
                Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat("transitive dependency ", depKey)), " failed (")), transSpec)), ")"));
                #line 628 "./src/add_cmd.am"
                return trc;
            }
        }
    }
    #line 644 "./src/add_cmd.am"
    if (!noPrecompile) {
        #line 645 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* stdlibTblPre = Amalgame_Compiler_TomlValue_Get(manifest, "stdlib");
        #line 646 "./src/add_cmd.am"
        if (Amalgame_Compiler_TomlValue_IsTable(stdlibTblPre)) {
            #line 647 "./src/add_cmd.am"
            if (Amalgame_Compiler_TomlValue_AsBool(Amalgame_Compiler_TomlValue_Get(stdlibTblPre, "precompile"))) {
                #line 648 "./src/add_cmd.am"
                code_string pkgVer = code_string_concat((code_string_concat(mfNameStr, "@")), tag);
                #line 649 "./src/add_cmd.am"
                Amalgame_Compiler_AddCommand_PrecompilePackage(pkgDir, stdlibTblPre, pkgVer);
            }
            #line 657 "./src/add_cmd.am"
            code_string facadeRel = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(stdlibTblPre, "facade"));
            #line 658 "./src/add_cmd.am"
            if (String_Length(facadeRel) > 0LL) {
                #line 659 "./src/add_cmd.am"
                Amalgame_Compiler_AddCommand_PrecompileFacade(pkgDir, stdlibTblPre, depsTable);
            }
        }
    }
    #line 665 "./src/add_cmd.am"
    if (!Amalgame_Compiler_AddCommand_UpdateProjectManifest(depName, url, tag)) {
        #line 666 "./src/add_cmd.am"
        Console_WriteError("could not update amalgame.toml");
        #line 667 "./src/add_cmd.am"
        return 1LL;
    }
    #line 675 "./src/add_cmd.am"
    code_string tomlAfter = File_ReadAll("amalgame.toml");
    #line 676 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* docAfter = Amalgame_Compiler_Toml_Parse(tomlAfter);
    #line 677 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* depsAfter = Amalgame_Compiler_TomlValue_Get(docAfter, "dependencies");
    #line 678 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsTable(depsAfter)) {
        #line 679 "./src/add_cmd.am"
        Amalgame_Compiler_AddCommand_RebuildLockFromTomlDeps(depsAfter, "amalgame.lock");
    }
    #line 682 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat((code_string_concat("Added ", depName)), " ")), tag));
    #line 683 "./src/add_cmd.am"
    return 0LL;
}

void Amalgame_Compiler_AddCommand_PrecompilePackage(code_string pkgDir, Amalgame_Compiler_TomlValue* stdlibTbl, code_string pkgVer) {
    #line 704 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* classVal = Amalgame_Compiler_TomlValue_Get(stdlibTbl, "class");
    #line 705 "./src/add_cmd.am"
    code_string className = Amalgame_Compiler_TomlValue_AsString(classVal);
    #line 706 "./src/add_cmd.am"
    if (String_Length(className) == 0LL) {
        return;
    }
    #line 707 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* sourcesArr = Amalgame_Compiler_TomlValue_Get(stdlibTbl, "sources");
    #line 708 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsArray(sourcesArr)) {
        return;
    }
    #line 709 "./src/add_cmd.am"
    i64 sn = Amalgame_Compiler_TomlValue_Count(sourcesArr);
    #line 710 "./src/add_cmd.am"
    if (sn == 0LL) {
        return;
    }
    #line 711 "./src/add_cmd.am"
    code_string cflags = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(stdlibTbl, "cflags"));
    #line 712 "./src/add_cmd.am"
    code_string cxxflags = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(stdlibTbl, "cxxflags"));
    #line 715 "./src/add_cmd.am"
    code_string buildDir = Amalgame_Compiler_PackageRegistry_PrecompileCacheDir(pkgDir);
    #line 716 "./src/add_cmd.am"
    if (!Amalgame_Compiler_AddCommand_MkdirP(buildDir)) {
        #line 717 "./src/add_cmd.am"
        Console_WriteError(code_string_concat("amc package add: could not create ", buildDir));
        #line 718 "./src/add_cmd.am"
        return;
    }
    #line 729 "./src/add_cmd.am"
    code_string amcPath0 = Amalgame_Compiler_AddCommand_ResolveSelfPath();
    #line 730 "./src/add_cmd.am"
    code_string amcRuntime = Env_Get("AMC_RUNTIME");
    #line 731 "./src/add_cmd.am"
    if (String_Length(amcRuntime) == 0LL) {
        #line 732 "./src/add_cmd.am"
        i64 slashIdx = String_LastIndexOf(amcPath0, "/");
        #line 733 "./src/add_cmd.am"
        if (slashIdx >= 0LL) {
            #line 734 "./src/add_cmd.am"
            code_string amcDir0 = String_Substring(amcPath0, 0LL, slashIdx);
            #line 735 "./src/add_cmd.am"
            code_string xdgPath0 = code_string_concat(amcDir0, "/../share/amalgame/runtime");
            #line 736 "./src/add_cmd.am"
            if (File_Exists(code_string_concat(xdgPath0, "/_runtime.h"))) {
                #line 737 "./src/add_cmd.am"
                amcRuntime = xdgPath0;
            } else {
                #line 739 "./src/add_cmd.am"
                amcRuntime = (code_string_concat(amcDir0, "/runtime"));
            }
        }
    }
    #line 745 "./src/add_cmd.am"
    Amalgame_Compiler_Calibration* cal = Amalgame_Compiler_Calibration_Load();
    #line 750 "./src/add_cmd.am"
    i64 totalCKb = 0LL;
    #line 751 "./src/add_cmd.am"
    i64 totalCSec = 0LL;
    #line 752 "./src/add_cmd.am"
    i64 totalCxxKb = 0LL;
    #line 753 "./src/add_cmd.am"
    i64 totalCxxSec = 0LL;
    #line 755 "./src/add_cmd.am"
    for (i64 j = 0LL; j < sn; j++) {
        #line 756 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* srcTv = Amalgame_Compiler_TomlValue_At(sourcesArr, j);
        #line 757 "./src/add_cmd.am"
        code_string srcRel = Amalgame_Compiler_TomlValue_AsString(srcTv);
        #line 758 "./src/add_cmd.am"
        if (String_Length(srcRel) == 0LL) {
            continue;
        }
        #line 759 "./src/add_cmd.am"
        code_string srcAbs = code_string_concat((code_string_concat(pkgDir, "/")), srcRel);
        #line 761 "./src/add_cmd.am"
        i64 lastSlash = String_LastIndexOf(srcAbs, "/");
        #line 762 "./src/add_cmd.am"
        code_string srcLeaf = srcAbs;
        #line 763 "./src/add_cmd.am"
        if (lastSlash >= 0LL) {
            #line 764 "./src/add_cmd.am"
            srcLeaf = String_Substring(srcAbs, lastSlash + 1LL, (String_Length(srcAbs) - lastSlash) - 1LL);
        }
        #line 766 "./src/add_cmd.am"
        code_string objPath = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(buildDir, "/")), className)), "-")), srcLeaf)), ".o");
        #line 767 "./src/add_cmd.am"
        if (File_Exists(objPath)) {
            #line 768 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat("  reused cache: ", srcLeaf));
            #line 769 "./src/add_cmd.am"
            continue;
        }
        #line 771 "./src/add_cmd.am"
        i64 sizeBytes = File_Size(srcAbs);
        #line 772 "./src/add_cmd.am"
        i64 sizeKb = sizeBytes / 1024LL;
        #line 773 "./src/add_cmd.am"
        code_bool isCxx = Amalgame_Compiler_PackageRegistry_IsCxxSource(srcAbs);
        #line 774 "./src/add_cmd.am"
        code_string lang = (isCxx ? "cxx" : "c");
        #line 777 "./src/add_cmd.am"
        i64 etaSec = Amalgame_Compiler_Calibration_EstimateSeconds(cal, lang, sizeKb);
        #line 778 "./src/add_cmd.am"
        code_string header = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("  Compiling ", srcLeaf)), " (")), String_FromInt(sizeKb))), " KB ")), lang)), ")");
        #line 779 "./src/add_cmd.am"
        if (etaSec > 0LL) {
            #line 780 "./src/add_cmd.am"
            header = (code_string_concat((code_string_concat(header, " — estimated ")), Amalgame_Compiler_AddCommand_HumanDuration(etaSec)));
        } else {
            #line 782 "./src/add_cmd.am"
            header = (code_string_concat((code_string_concat((code_string_concat(header, " — first ")), lang)), " compile on this machine, no ETA yet"));
        }
        #line 784 "./src/add_cmd.am"
        Console_WriteLine(header);
        #line 788 "./src/add_cmd.am"
        code_string cmd = "";
        #line 789 "./src/add_cmd.am"
        if (isCxx) {
            #line 790 "./src/add_cmd.am"
            cmd = "g++ -O2";
        } else {
            #line 792 "./src/add_cmd.am"
            cmd = "gcc -O2";
        }
        #line 794 "./src/add_cmd.am"
        if (String_Length(amcRuntime) > 0LL) {
            #line 795 "./src/add_cmd.am"
            cmd = (code_string_concat((code_string_concat((code_string_concat(cmd, " -I\"")), amcRuntime)), "\""));
        }
        #line 800 "./src/add_cmd.am"
        AmalgameList* cachedPkgDirs = Amalgame_Compiler_AddCommand_AllCachedRuntimeDirs();
        #line 801 "./src/add_cmd.am"
        i64 cpn = AmalgameList_count(cachedPkgDirs);
        #line 802 "./src/add_cmd.am"
        for (i64 cpi = 0LL; cpi < cpn; cpi++) {
            #line 803 "./src/add_cmd.am"
            cmd = (code_string_concat((code_string_concat((code_string_concat(cmd, " -I\"")), (code_string)AmalgameList_get(cachedPkgDirs, cpi))), "\""));
        }
        #line 805 "./src/add_cmd.am"
        if (isCxx && (String_Length(cxxflags) > 0LL)) {
            #line 806 "./src/add_cmd.am"
            cmd = (code_string_concat((code_string_concat(cmd, " ")), cxxflags));
        }
        #line 808 "./src/add_cmd.am"
        if (!isCxx && (String_Length(cflags) > 0LL)) {
            #line 809 "./src/add_cmd.am"
            cmd = (code_string_concat((code_string_concat(cmd, " ")), cflags));
        }
        #line 811 "./src/add_cmd.am"
        cmd = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(cmd, " -w -c \"")), srcAbs)), "\" -o \"")), objPath)), "\" 2>&1"));
        #line 814 "./src/add_cmd.am"
        i64 t0 = Amalgame_Compiler_AddCommand_NowSeconds();
        #line 815 "./src/add_cmd.am"
        AmalgameProcessResult* res = Process_RunCapture(cmd);
        #line 816 "./src/add_cmd.am"
        i64 t1 = Amalgame_Compiler_AddCommand_NowSeconds();
        #line 817 "./src/add_cmd.am"
        i64 elapsedS = t1 - t0;
        #line 819 "./src/add_cmd.am"
        if (res->Exit != 0LL) {
            #line 820 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat("  FAILED to compile ", srcLeaf)), ":"));
            #line 821 "./src/add_cmd.am"
            Console_WriteError(res->Stdout);
            #line 822 "./src/add_cmd.am"
            continue;
        }
        #line 824 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat((code_string_concat("  ✓ ", srcLeaf)), " in ")), Amalgame_Compiler_AddCommand_HumanDuration(elapsedS)));
        #line 827 "./src/add_cmd.am"
        if (isCxx) {
            #line 828 "./src/add_cmd.am"
            totalCxxKb = (totalCxxKb + sizeKb);
            #line 829 "./src/add_cmd.am"
            totalCxxSec = (totalCxxSec + elapsedS);
        } else {
            #line 831 "./src/add_cmd.am"
            totalCKb = (totalCKb + sizeKb);
            #line 832 "./src/add_cmd.am"
            totalCSec = (totalCSec + elapsedS);
        }
    }
    #line 838 "./src/add_cmd.am"
    code_bool dirty = 0;
    #line 839 "./src/add_cmd.am"
    if ((totalCKb > 0LL) && (totalCSec > 0LL)) {
        #line 840 "./src/add_cmd.am"
        Amalgame_Compiler_Calibration_Add(cal, "c", totalCKb, totalCSec, pkgVer);
        #line 841 "./src/add_cmd.am"
        dirty = 1;
    }
    #line 843 "./src/add_cmd.am"
    if ((totalCxxKb > 0LL) && (totalCxxSec > 0LL)) {
        #line 844 "./src/add_cmd.am"
        Amalgame_Compiler_Calibration_Add(cal, "cxx", totalCxxKb, totalCxxSec, pkgVer);
        #line 845 "./src/add_cmd.am"
        dirty = 1;
    }
    #line 847 "./src/add_cmd.am"
    if (dirty) {
        #line 848 "./src/add_cmd.am"
        if (!Amalgame_Compiler_Calibration_Save(cal)) {
            #line 849 "./src/add_cmd.am"
            Console_WriteError(code_string_concat("  warning: could not save calibration to ", Amalgame_Compiler_PackageRegistry_CalibrationPath()));
        }
    }
}

void Amalgame_Compiler_AddCommand_PrecompileFacade(code_string pkgDir, Amalgame_Compiler_TomlValue* stdlibTbl, Amalgame_Compiler_TomlValue* depsTbl) {
    #line 877 "./src/add_cmd.am"
    code_string className = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(stdlibTbl, "class"));
    #line 878 "./src/add_cmd.am"
    if (String_Length(className) == 0LL) {
        #line 879 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* classesArr = Amalgame_Compiler_TomlValue_Get(stdlibTbl, "classes");
        #line 880 "./src/add_cmd.am"
        if (Amalgame_Compiler_TomlValue_IsArray(classesArr) && (Amalgame_Compiler_TomlValue_Count(classesArr) > 0LL)) {
            #line 881 "./src/add_cmd.am"
            className = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_At(classesArr, 0LL));
        }
    }
    #line 884 "./src/add_cmd.am"
    if (String_Length(className) == 0LL) {
        return;
    }
    #line 885 "./src/add_cmd.am"
    code_string facadeRel = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(stdlibTbl, "facade"));
    #line 886 "./src/add_cmd.am"
    if (String_Length(facadeRel) == 0LL) {
        return;
    }
    #line 888 "./src/add_cmd.am"
    code_string facadeAbs = code_string_concat((code_string_concat(pkgDir, "/")), facadeRel);
    #line 889 "./src/add_cmd.am"
    if (!File_Exists(facadeAbs)) {
        #line 890 "./src/add_cmd.am"
        Console_WriteError(code_string_concat("  facade source not found: ", facadeAbs));
        #line 891 "./src/add_cmd.am"
        return;
    }
    #line 896 "./src/add_cmd.am"
    code_string buildDir = Amalgame_Compiler_PackageRegistry_PrecompileCacheDir(pkgDir);
    #line 897 "./src/add_cmd.am"
    if (!Amalgame_Compiler_AddCommand_MkdirP(buildDir)) {
        #line 898 "./src/add_cmd.am"
        Console_WriteError(code_string_concat("amc package add: could not create ", buildDir));
        #line 899 "./src/add_cmd.am"
        return;
    }
    #line 915 "./src/add_cmd.am"
    code_string amcPath = Amalgame_Compiler_AddCommand_ResolveSelfPath();
    #line 916 "./src/add_cmd.am"
    code_string amcRuntime = Env_Get("AMC_RUNTIME");
    #line 917 "./src/add_cmd.am"
    if (String_Length(amcRuntime) == 0LL) {
        #line 918 "./src/add_cmd.am"
        i64 slashIdx = String_LastIndexOf(amcPath, "/");
        #line 919 "./src/add_cmd.am"
        if (slashIdx >= 0LL) {
            #line 920 "./src/add_cmd.am"
            code_string amcDir = String_Substring(amcPath, 0LL, slashIdx);
            #line 921 "./src/add_cmd.am"
            code_string xdgPath = code_string_concat(amcDir, "/../share/amalgame/runtime");
            #line 922 "./src/add_cmd.am"
            if (File_Exists(code_string_concat(xdgPath, "/_runtime.h"))) {
                #line 923 "./src/add_cmd.am"
                amcRuntime = xdgPath;
            } else {
                #line 925 "./src/add_cmd.am"
                amcRuntime = (code_string_concat(amcDir, "/runtime"));
            }
        }
    }
    #line 930 "./src/add_cmd.am"
    code_string baseOut = code_string_concat((code_string_concat((code_string_concat(buildDir, "/")), className)), "-facade");
    #line 931 "./src/add_cmd.am"
    code_string cFile = code_string_concat(baseOut, ".c");
    #line 932 "./src/add_cmd.am"
    code_string oFile = code_string_concat(baseOut, ".o");
    #line 933 "./src/add_cmd.am"
    code_string archive = code_string_concat((code_string_concat((code_string_concat(buildDir, "/libamalgame-pkg-")), className)), ".a");
    #line 935 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat("  Compiling facade ", facadeRel)), " → libamalgame-pkg-")), className)), ".a"));
    #line 944 "./src/add_cmd.am"
    code_string facadeSourcesAbs = code_string_concat((code_string_concat("\"", facadeAbs)), "\"");
    #line 945 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* srcArr = Amalgame_Compiler_TomlValue_Get(stdlibTbl, "sources");
    #line 946 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsArray(srcArr)) {
        #line 947 "./src/add_cmd.am"
        i64 srcN = Amalgame_Compiler_TomlValue_Count(srcArr);
        #line 948 "./src/add_cmd.am"
        for (i64 si = 0LL; si < srcN; si++) {
            #line 949 "./src/add_cmd.am"
            code_string srcRel = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_At(srcArr, si));
            #line 950 "./src/add_cmd.am"
            if (String_Length(srcRel) == 0LL) {
                continue;
            }
            #line 951 "./src/add_cmd.am"
            code_string srcAbs = code_string_concat((code_string_concat(pkgDir, "/")), srcRel);
            #line 952 "./src/add_cmd.am"
            if (!File_Exists(srcAbs)) {
                continue;
            }
            #line 955 "./src/add_cmd.am"
            if (code_string_equals(srcRel, facadeRel)) {
                continue;
            }
            #line 956 "./src/add_cmd.am"
            facadeSourcesAbs = (code_string_concat((code_string_concat((code_string_concat(facadeSourcesAbs, " \"")), srcAbs)), "\""));
        }
    }
    #line 963 "./src/add_cmd.am"
    code_string amcCmd = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("\"", amcPath)), "\" --lib --quiet ")), facadeSourcesAbs)), " -o \"")), baseOut)), "\" 2>&1");
    #line 964 "./src/add_cmd.am"
    AmalgameProcessResult* amcRes = Process_RunCapture(amcCmd);
    #line 965 "./src/add_cmd.am"
    if (amcRes->Exit != 0LL) {
        #line 966 "./src/add_cmd.am"
        Console_WriteError("  FAILED to compile facade (amc):");
        #line 967 "./src/add_cmd.am"
        Console_WriteError(amcRes->Stdout);
        #line 968 "./src/add_cmd.am"
        return;
    }
    #line 984 "./src/add_cmd.am"
    code_string gccCmd = code_string_concat((code_string_concat("gcc -O2 -Iruntime -I\"", pkgDir)), "/runtime\"");
    #line 985 "./src/add_cmd.am"
    if (String_Length(amcRuntime) > 0LL) {
        #line 986 "./src/add_cmd.am"
        gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, " -I\"")), amcRuntime)), "\""));
    }
    #line 1002 "./src/add_cmd.am"
    AmalgameList* cachedDirs = Amalgame_Compiler_AddCommand_AllCachedRuntimeDirs();
    #line 1003 "./src/add_cmd.am"
    i64 cdn = AmalgameList_count(cachedDirs);
    #line 1004 "./src/add_cmd.am"
    for (i64 ci = 0LL; ci < cdn; ci++) {
        #line 1005 "./src/add_cmd.am"
        gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, " -I\"")), (code_string)AmalgameList_get(cachedDirs, ci))), "\""));
    }
    #line 1007 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* cflagsVal = Amalgame_Compiler_TomlValue_Get(stdlibTbl, "cflags");
    #line 1008 "./src/add_cmd.am"
    code_string cflagsStr = Amalgame_Compiler_TomlValue_AsString(cflagsVal);
    #line 1009 "./src/add_cmd.am"
    if (String_Length(cflagsStr) > 0LL) {
        #line 1010 "./src/add_cmd.am"
        gccCmd = (code_string_concat((code_string_concat(gccCmd, " ")), cflagsStr));
    }
    #line 1012 "./src/add_cmd.am"
    gccCmd = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(gccCmd, " -w -c \"")), cFile)), "\" -o \"")), oFile)), "\" 2>&1"));
    #line 1013 "./src/add_cmd.am"
    AmalgameProcessResult* gccRes = Process_RunCapture(gccCmd);
    #line 1014 "./src/add_cmd.am"
    if (gccRes->Exit != 0LL) {
        #line 1015 "./src/add_cmd.am"
        Console_WriteError("  FAILED to compile facade (gcc):");
        #line 1016 "./src/add_cmd.am"
        Console_WriteError(gccRes->Stdout);
        #line 1017 "./src/add_cmd.am"
        return;
    }
    #line 1023 "./src/add_cmd.am"
    if (File_Exists(archive) && !File_Delete(archive)) {
        #line 1024 "./src/add_cmd.am"
        Console_WriteError(code_string_concat("  warning: could not remove stale archive ", archive));
    }
    #line 1026 "./src/add_cmd.am"
    code_string arCmd = code_string_concat((code_string_concat((code_string_concat((code_string_concat("ar rcs \"", archive)), "\" \"")), oFile)), "\" 2>&1");
    #line 1027 "./src/add_cmd.am"
    AmalgameProcessResult* arRes = Process_RunCapture(arCmd);
    #line 1028 "./src/add_cmd.am"
    if (arRes->Exit != 0LL) {
        #line 1029 "./src/add_cmd.am"
        Console_WriteError("  FAILED to archive facade (ar):");
        #line 1030 "./src/add_cmd.am"
        Console_WriteError(arRes->Stdout);
        #line 1031 "./src/add_cmd.am"
        return;
    }
    #line 1033 "./src/add_cmd.am"
    i64 arSize = File_Size(archive);
    #line 1034 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat("  ✓ libamalgame-pkg-", className)), ".a (")), String_FromInt(arSize))), " bytes)"));
}

code_string Amalgame_Compiler_AddCommand_ResolveSelfPath() {
    #line 1047 "./src/add_cmd.am"
    { /* inline-C */
        
                    #ifdef _WIN32
                        char buf[4096];
                        DWORD n = GetModuleFileNameA(NULL, buf, sizeof(buf));
                        if (n == 0 || n >= sizeof(buf)) { return (code_string) ""; }
                        for (DWORD i = 0; i < n; i++) { if (buf[i] == '\\') buf[i] = '/'; }
                        char* out = (char*) GC_MALLOC((size_t)(n + 1));
                        memcpy(out, buf, (size_t)(n + 1));
                        return (code_string) out;
                    #else
                        char buf[4096];
                        ssize_t n = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
                        if (n <= 0) { return (code_string) ""; }
                        buf[n] = '\0';
                        char* out = (char*) GC_MALLOC((size_t)(n + 1));
                        memcpy(out, buf, (size_t)(n + 1));
                        return (code_string) out;
                    #endif
                
    }
}

i64 Amalgame_Compiler_AddCommand_NowSeconds() {
    #line 1072 "./src/add_cmd.am"
    { /* inline-C */
         return (i64) time(NULL); 
    }
}

code_string Amalgame_Compiler_AddCommand_HumanDuration(i64 seconds) {
    #line 1078 "./src/add_cmd.am"
    if (seconds < 60LL) {
        return code_string_concat(String_FromInt(seconds), "s");
    }
    #line 1079 "./src/add_cmd.am"
    i64 m = seconds / 60LL;
    #line 1080 "./src/add_cmd.am"
    i64 s = seconds % 60LL;
    #line 1081 "./src/add_cmd.am"
    return code_string_concat((code_string_concat((code_string_concat(String_FromInt(m), "m")), String_FromInt(s))), "s");
}

AmalgameList* Amalgame_Compiler_AddCommand_ParseSpec(code_string spec) {
    #line 1090 "./src/add_cmd.am"
    AmalgameList* out = AmalgameList_new();
    #line 1091 "./src/add_cmd.am"
    i64 atIdx = String_LastIndexOf(spec, "@");
    #line 1092 "./src/add_cmd.am"
    if ((atIdx <= 0LL) || (atIdx >= (String_Length(spec) - 1LL))) {
        return out;
    }
    #line 1093 "./src/add_cmd.am"
    code_string url = String_Substring(spec, 0LL, atIdx);
    #line 1094 "./src/add_cmd.am"
    code_string tag = String_Substring(spec, atIdx + 1LL, (String_Length(spec) - atIdx) - 1LL);
    #line 1096 "./src/add_cmd.am"
    code_string cleanUrl = url;
    #line 1097 "./src/add_cmd.am"
    if (String_StartsWith(cleanUrl, "https://")) {
        #line 1098 "./src/add_cmd.am"
        cleanUrl = String_Substring(cleanUrl, 8LL, String_Length(cleanUrl) - 8LL);
    }
    #line 1100 "./src/add_cmd.am"
    if (String_StartsWith(cleanUrl, "http://")) {
        #line 1101 "./src/add_cmd.am"
        cleanUrl = String_Substring(cleanUrl, 7LL, String_Length(cleanUrl) - 7LL);
    }
    #line 1103 "./src/add_cmd.am"
    AmalgameList_add(out, (void*)(intptr_t)(cleanUrl));
    #line 1104 "./src/add_cmd.am"
    AmalgameList_add(out, (void*)(intptr_t)(tag));
    #line 1105 "./src/add_cmd.am"
    return out;
}

code_bool Amalgame_Compiler_AddCommand_IsSafeUrl(code_string url) {
    #line 1109 "./src/add_cmd.am"
    i64 n = String_Length(url);
    #line 1110 "./src/add_cmd.am"
    if (n == 0LL) {
        return 0;
    }
    #line 1111 "./src/add_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 1112 "./src/add_cmd.am"
        code_string c = String_CharAt1(url, i);
        #line 1113 "./src/add_cmd.am"
        code_bool ok = 0;
        #line 1114 "./src/add_cmd.am"
        if (((((code_string_equals(c, ".")) || (code_string_equals(c, "/"))) || (code_string_equals(c, "_"))) || (code_string_equals(c, "-"))) || (code_string_equals(c, ":"))) {
            ok = 1;
        }
        #line 1115 "./src/add_cmd.am"
        if (String_IndexOf("0123456789", c) >= 0LL) {
            ok = 1;
        }
        #line 1116 "./src/add_cmd.am"
        if (String_IndexOf("abcdefghijklmnopqrstuvwxyz", c) >= 0LL) {
            ok = 1;
        }
        #line 1117 "./src/add_cmd.am"
        if (String_IndexOf("ABCDEFGHIJKLMNOPQRSTUVWXYZ", c) >= 0LL) {
            ok = 1;
        }
        #line 1118 "./src/add_cmd.am"
        if (!ok) {
            return 0;
        }
    }
    #line 1120 "./src/add_cmd.am"
    return 1;
}

code_bool Amalgame_Compiler_AddCommand_IsSafeTag(code_string tag) {
    #line 1124 "./src/add_cmd.am"
    i64 n = String_Length(tag);
    #line 1125 "./src/add_cmd.am"
    if (n == 0LL) {
        return 0;
    }
    #line 1126 "./src/add_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 1127 "./src/add_cmd.am"
        code_string c = String_CharAt1(tag, i);
        #line 1128 "./src/add_cmd.am"
        code_bool ok = 0;
        #line 1129 "./src/add_cmd.am"
        if ((((code_string_equals(c, ".")) || (code_string_equals(c, "_"))) || (code_string_equals(c, "-"))) || (code_string_equals(c, "+"))) {
            ok = 1;
        }
        #line 1130 "./src/add_cmd.am"
        if (String_IndexOf("0123456789", c) >= 0LL) {
            ok = 1;
        }
        #line 1131 "./src/add_cmd.am"
        if (String_IndexOf("abcdefghijklmnopqrstuvwxyz", c) >= 0LL) {
            ok = 1;
        }
        #line 1132 "./src/add_cmd.am"
        if (String_IndexOf("ABCDEFGHIJKLMNOPQRSTUVWXYZ", c) >= 0LL) {
            ok = 1;
        }
        #line 1133 "./src/add_cmd.am"
        if (!ok) {
            return 0;
        }
    }
    #line 1135 "./src/add_cmd.am"
    return 1;
}

code_string Amalgame_Compiler_AddCommand_SlugFromUrl(code_string url) {
    #line 1140 "./src/add_cmd.am"
    i64 slashIdx = String_LastIndexOf(url, "/");
    #line 1141 "./src/add_cmd.am"
    if (slashIdx < 0LL) {
        return url;
    }
    #line 1142 "./src/add_cmd.am"
    return String_Substring(url, slashIdx + 1LL, (String_Length(url) - slashIdx) - 1LL);
}

code_string Amalgame_Compiler_AddCommand_DepNameFromSlug(code_string slug) {
    #line 1156 "./src/add_cmd.am"
    if (!String_StartsWith(slug, "amalgame-")) {
        #line 1157 "./src/add_cmd.am"
        return slug;
    }
    #line 1159 "./src/add_cmd.am"
    code_string rest = String_Substring(slug, 9LL, String_Length(slug) - 9LL);
    #line 1160 "./src/add_cmd.am"
    i64 lastDash = String_LastIndexOf(rest, "-");
    #line 1161 "./src/add_cmd.am"
    if (lastDash < 0LL) {
        #line 1162 "./src/add_cmd.am"
        return rest;
    }
    #line 1164 "./src/add_cmd.am"
    return String_Substring(rest, lastDash + 1LL, (String_Length(rest) - lastDash) - 1LL);
}

code_string Amalgame_Compiler_AddCommand_StripV(code_string tag) {
    #line 1170 "./src/add_cmd.am"
    if (String_StartsWith(tag, "v")) {
        #line 1171 "./src/add_cmd.am"
        return String_Substring(tag, 1LL, String_Length(tag) - 1LL);
    }
    #line 1173 "./src/add_cmd.am"
    return tag;
}

code_string Amalgame_Compiler_AddCommand_CacheRoot() {
    #line 1179 "./src/add_cmd.am"
    code_string override = Env_Get("AMALGAME_PACKAGES_DIR");
    #line 1180 "./src/add_cmd.am"
    if (String_Length(override) > 0LL) {
        #line 1181 "./src/add_cmd.am"
        return override;
    }
    #line 1183 "./src/add_cmd.am"
    code_string home = Env_Get("HOME");
    #line 1184 "./src/add_cmd.am"
    if (String_Length(home) > 0LL) {
        #line 1185 "./src/add_cmd.am"
        return code_string_concat(home, "/.amalgame/packages");
    }
    #line 1191 "./src/add_cmd.am"
    code_string userProfile = Env_Get("USERPROFILE");
    #line 1192 "./src/add_cmd.am"
    if (String_Length(userProfile) > 0LL) {
        #line 1193 "./src/add_cmd.am"
        return code_string_concat(String_Replace(userProfile, "\\", "/"), "/.amalgame/packages");
    }
    #line 1195 "./src/add_cmd.am"
    return "/tmp/amalgame-packages";
}

code_string Amalgame_Compiler_AddCommand_IndexCachePath() {
    #line 1203 "./src/add_cmd.am"
    code_string home = Env_Get("HOME");
    #line 1204 "./src/add_cmd.am"
    if (String_Length(home) > 0LL) {
        #line 1205 "./src/add_cmd.am"
        return code_string_concat(home, "/.amalgame/cache/packages-index.toml");
    }
    #line 1210 "./src/add_cmd.am"
    code_string userProfile = Env_Get("USERPROFILE");
    #line 1211 "./src/add_cmd.am"
    if (String_Length(userProfile) > 0LL) {
        #line 1212 "./src/add_cmd.am"
        return code_string_concat(String_Replace(userProfile, "\\", "/"), "/.amalgame/cache/packages-index.toml");
    }
    #line 1214 "./src/add_cmd.am"
    return "/tmp/amalgame-index.toml";
}

static code_bool Amalgame_Compiler_AddCommand_IsShortname(code_string lhs) {
    #line 1223 "./src/add_cmd.am"
    if (String_IndexOf(lhs, "/") >= 0LL) {
        return 0;
    }
    #line 1224 "./src/add_cmd.am"
    if (String_IndexOf(lhs, ".") >= 0LL) {
        return 0;
    }
    #line 1225 "./src/add_cmd.am"
    return String_Length(lhs) > 0LL;
}

code_string Amalgame_Compiler_AddCommand_FetchIndex() {
    #line 1236 "./src/add_cmd.am"
    code_string cachePath = Amalgame_Compiler_AddCommand_IndexCachePath();
    #line 1237 "./src/add_cmd.am"
    if (File_Exists(cachePath) && Amalgame_Compiler_AddCommand_IndexCacheIsFresh(cachePath)) {
        #line 1238 "./src/add_cmd.am"
        return File_ReadAll(cachePath);
    }
    #line 1241 "./src/add_cmd.am"
    code_string cacheDir = String_Substring(cachePath, 0LL, String_LastIndexOf(cachePath, "/"));
    #line 1242 "./src/add_cmd.am"
    code_bool _mkdir = Amalgame_Compiler_AddCommand_MkdirP(cacheDir);
    #line 1248 "./src/add_cmd.am"
    code_string indexUrl = "https://raw.githubusercontent.com/amalgame-lang/packages-index/main/packages.toml";
    #line 1249 "./src/add_cmd.am"
    code_string cmd = code_string_concat((code_string_concat((code_string_concat((code_string_concat("curl -fsSL --ssl-no-revoke \"", indexUrl)), "\" -o \"")), cachePath)), "\" 2>&1");
    #line 1250 "./src/add_cmd.am"
    i64 exit = Process_Run(cmd);
    #line 1251 "./src/add_cmd.am"
    if ((exit != 0LL) || !File_Exists(cachePath)) {
        #line 1255 "./src/add_cmd.am"
        if (File_Exists(cachePath)) {
            #line 1256 "./src/add_cmd.am"
            Console_WriteError(code_string_concat("warning: index fetch failed, serving stale cache from ", cachePath));
            #line 1257 "./src/add_cmd.am"
            return File_ReadAll(cachePath);
        }
        #line 1259 "./src/add_cmd.am"
        return "";
    }
    #line 1261 "./src/add_cmd.am"
    return File_ReadAll(cachePath);
}

code_bool Amalgame_Compiler_AddCommand_IndexCacheIsFresh(code_string cachePath) {
    #line 1270 "./src/add_cmd.am"
    i64 ttlSecs = 1800LL;
    #line 1271 "./src/add_cmd.am"
    i64 mtime = File_Mtime(cachePath);
    #line 1272 "./src/add_cmd.am"
    if (mtime <= 0LL) {
        return 1;
    }
    #line 1273 "./src/add_cmd.am"
    i64 now = Amalgame_Compiler_AddCommand_NowSeconds();
    #line 1274 "./src/add_cmd.am"
    if (now <= 0LL) {
        return 1;
    }
    #line 1275 "./src/add_cmd.am"
    return (now - mtime) < ttlSecs;
}

i64 Amalgame_Compiler_AddCommand_RunPackage(i64 argc) {
    #line 1297 "./src/add_cmd.am"
    if (argc < 3LL) {
        #line 1298 "./src/add_cmd.am"
        Amalgame_Compiler_AddCommand_PrintPackageUsage();
        #line 1299 "./src/add_cmd.am"
        return 2LL;
    }
    #line 1301 "./src/add_cmd.am"
    code_string sub = Args_Get(2LL);
    #line 1302 "./src/add_cmd.am"
    if ((code_string_equals(sub, "-h")) || (code_string_equals(sub, "--help"))) {
        #line 1303 "./src/add_cmd.am"
        Amalgame_Compiler_AddCommand_PrintPackageUsage();
        #line 1304 "./src/add_cmd.am"
        return 0LL;
    }
    #line 1309 "./src/add_cmd.am"
    if (code_string_equals(sub, "add")) {
        return Amalgame_Compiler_AddCommand_Run(argc, 3LL);
    }
    #line 1310 "./src/add_cmd.am"
    if (code_string_equals(sub, "search")) {
        return Amalgame_Compiler_AddCommand_RunSearch(argc, 3LL);
    }
    #line 1311 "./src/add_cmd.am"
    if (code_string_equals(sub, "suggest")) {
        return Amalgame_Compiler_AddCommand_RunSuggest(argc, 3LL);
    }
    #line 1312 "./src/add_cmd.am"
    if (code_string_equals(sub, "versions")) {
        return Amalgame_Compiler_AddCommand_RunVersions(argc, 3LL);
    }
    #line 1313 "./src/add_cmd.am"
    if (code_string_equals(sub, "info")) {
        return Amalgame_Compiler_AddCommand_RunInfo(argc, 3LL);
    }
    #line 1314 "./src/add_cmd.am"
    if (code_string_equals(sub, "outdated")) {
        return Amalgame_Compiler_AddCommand_RunOutdated(argc, 3LL);
    }
    #line 1315 "./src/add_cmd.am"
    if (code_string_equals(sub, "notice")) {
        return Amalgame_Compiler_AddCommand_RunNotice(argc, 3LL);
    }
    #line 1316 "./src/add_cmd.am"
    if (code_string_equals(sub, "check")) {
        return Amalgame_Compiler_AddCommand_RunCheck(argc, 3LL);
    }
    #line 1317 "./src/add_cmd.am"
    if (code_string_equals(sub, "list")) {
        return Amalgame_Compiler_AddCommand_RunList(argc, 3LL);
    }
    #line 1318 "./src/add_cmd.am"
    if (code_string_equals(sub, "remove")) {
        return Amalgame_Compiler_AddCommand_RunRemove(argc, 3LL);
    }
    #line 1319 "./src/add_cmd.am"
    if (code_string_equals(sub, "update")) {
        return Amalgame_Compiler_AddCommand_RunUpdate(argc, 3LL);
    }
    #line 1320 "./src/add_cmd.am"
    if (code_string_equals(sub, "cache")) {
        return Amalgame_Compiler_AddCommand_RunCache(argc, 3LL);
    }
    #line 1321 "./src/add_cmd.am"
    Console_WriteError(code_string_concat((code_string_concat("amc package: unknown subcommand '", sub)), "'"));
    #line 1322 "./src/add_cmd.am"
    Amalgame_Compiler_AddCommand_PrintPackageUsage();
    #line 1323 "./src/add_cmd.am"
    return 2LL;
}

void Amalgame_Compiler_AddCommand_PrintPackageUsage() {
    #line 1327 "./src/add_cmd.am"
    Console_WriteError("Usage: amc package  [args...]");
    #line 1328 "./src/add_cmd.am"
    Console_WriteError("       amc pkg      [args...]");
    #line 1329 "./src/add_cmd.am"
    Console_WriteError("");
    #line 1330 "./src/add_cmd.am"
    Console_WriteError("Subcommands:");
    #line 1331 "./src/add_cmd.am"
    Console_WriteError("  add [@]        Install a package; auto-resolve latest");
    #line 1332 "./src/add_cmd.am"
    Console_WriteError("                                compatible tag if @ is omitted (indexed");
    #line 1333 "./src/add_cmd.am"
    Console_WriteError("                                shortnames only)");
    #line 1334 "./src/add_cmd.am"
    Console_WriteError("    [--no-precompile]            Skip install-time compile (manifest opt-in)");
    #line 1335 "./src/add_cmd.am"
    Console_WriteError("  search [keyword] [--refresh]  List or filter packages-index with version compat");
    #line 1336 "./src/add_cmd.am"
    Console_WriteError("    [--no-versions]              Skip the per-package versions block (faster)");
    #line 1337 "./src/add_cmd.am"
    Console_WriteError("  suggest  [--json]    Suggest packages that match a class or namespace");
    #line 1338 "./src/add_cmd.am"
    Console_WriteError("    [--refresh]                  (intended for LSP / `using X;` quickfix integration)");
    #line 1339 "./src/add_cmd.am"
    Console_WriteError("  versions  [--refresh]   Show all indexed versions of a single package");
    #line 1340 "./src/add_cmd.am"
    Console_WriteError("    [--json]                     Emit machine-readable JSON");
    #line 1341 "./src/add_cmd.am"
    Console_WriteError("  info  [--refresh]       Show description, url, license, versions, install");
    #line 1342 "./src/add_cmd.am"
    Console_WriteError("  outdated [--refresh]          List installed deps with a newer compatible tag");
    #line 1343 "./src/add_cmd.am"
    Console_WriteError("  notice                        Aggregate licence + authorship of installed deps");
    #line 1344 "./src/add_cmd.am"
    Console_WriteError("  check [--frozen]              Verify amalgame.lock matches the installed cache");
    #line 1345 "./src/add_cmd.am"
    Console_WriteError("                                (--frozen exits 1 on mismatch — for CI)");
    #line 1346 "./src/add_cmd.am"
    Console_WriteError("  list                          Show installed deps");
    #line 1347 "./src/add_cmd.am"
    Console_WriteError("  remove [@] [...]   Strip dep(s) from amalgame.toml + lock.");
    #line 1348 "./src/add_cmd.am"
    Console_WriteError("                                `@` is a safety check (refuses to remove");
    #line 1349 "./src/add_cmd.am"
    Console_WriteError("                                if the installed tag differs)");
    #line 1350 "./src/add_cmd.am"
    Console_WriteError("  update @           Bump a pinned tag");
    #line 1351 "./src/add_cmd.am"
    Console_WriteError("  cache clear [--all]           Drop cached index / packages");
    #line 1352 "./src/add_cmd.am"
    Console_WriteError("");
    #line 1353 "./src/add_cmd.am"
    Console_WriteError("Example:");
    #line 1354 "./src/add_cmd.am"
    Console_WriteError("  amc package search duckdb");
    #line 1355 "./src/add_cmd.am"
    Console_WriteError("  amc package add redis@v0.2.0");
    #line 1356 "./src/add_cmd.am"
    Console_WriteError("  amc package versions sqlite");
}

i64 Amalgame_Compiler_AddCommand_RunVersions(i64 argc, i64 startIdx) {
    #line 1366 "./src/add_cmd.am"
    code_string pkgName = "";
    #line 1367 "./src/add_cmd.am"
    code_bool refresh = 0;
    #line 1368 "./src/add_cmd.am"
    code_bool jsonOut = 0;
    #line 1369 "./src/add_cmd.am"
    i64 i = startIdx;
    #line 1370 "./src/add_cmd.am"
    while (i < argc) {
        #line 1371 "./src/add_cmd.am"
        code_string a = Args_Get(i);
        #line 1372 "./src/add_cmd.am"
        if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) {
            #line 1373 "./src/add_cmd.am"
            Console_WriteError("Usage: amc package versions  [--refresh] [--json]");
            #line 1374 "./src/add_cmd.am"
            Console_WriteError("");
            #line 1375 "./src/add_cmd.am"
            Console_WriteError("Show indexed versions of  with compat against your");
            #line 1376 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat("amc ", Amalgame_Compiler_PackageRegistry_AmcVersion())), "."));
            #line 1377 "./src/add_cmd.am"
            Console_WriteError("");
            #line 1378 "./src/add_cmd.am"
            Console_WriteError("--refresh  force re-download of the index (cache TTL 30 min).");
            #line 1379 "./src/add_cmd.am"
            Console_WriteError("--json     emit machine-readable JSON on stdout (for scripts).");
            #line 1380 "./src/add_cmd.am"
            return 0LL;
        }
        #line 1382 "./src/add_cmd.am"
        if (code_string_equals(a, "--refresh")) {
            #line 1383 "./src/add_cmd.am"
            refresh = 1;
        } else if (code_string_equals(a, "--json")) {
            #line 1385 "./src/add_cmd.am"
            jsonOut = 1;
        } else if (String_Length(pkgName) == 0LL) {
            #line 1387 "./src/add_cmd.am"
            pkgName = a;
        }
        #line 1389 "./src/add_cmd.am"
        i = (i + 1LL);
    }
    #line 1391 "./src/add_cmd.am"
    if (String_Length(pkgName) == 0LL) {
        #line 1392 "./src/add_cmd.am"
        Console_WriteError("amc package versions: missing ");
        #line 1393 "./src/add_cmd.am"
        return 2LL;
    }
    #line 1395 "./src/add_cmd.am"
    if (refresh) {
        #line 1396 "./src/add_cmd.am"
        code_string cachePath = Amalgame_Compiler_AddCommand_IndexCachePath();
        #line 1397 "./src/add_cmd.am"
        if (File_Exists(cachePath)) {
            #line 1398 "./src/add_cmd.am"
            code_bool _rm = File_Delete(cachePath);
        }
    }
    #line 1401 "./src/add_cmd.am"
    code_string indexSrc = Amalgame_Compiler_AddCommand_FetchIndex();
    #line 1402 "./src/add_cmd.am"
    if (String_Length(indexSrc) == 0LL) {
        #line 1403 "./src/add_cmd.am"
        Console_WriteError("could not fetch packages-index");
        #line 1404 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1406 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(indexSrc);
    #line 1407 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsNull(doc)) {
        #line 1408 "./src/add_cmd.am"
        Console_WriteError("packages-index parse error");
        #line 1409 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1412 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* pkgArr = Amalgame_Compiler_TomlValue_Get(doc, "package");
    #line 1413 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsArray(pkgArr)) {
        #line 1414 "./src/add_cmd.am"
        Console_WriteError("packages-index has no [[package]] entries");
        #line 1415 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1417 "./src/add_cmd.am"
    code_bool found = 0;
    #line 1418 "./src/add_cmd.am"
    code_string urlS = "";
    #line 1419 "./src/add_cmd.am"
    i64 pn = Amalgame_Compiler_TomlValue_Count(pkgArr);
    #line 1420 "./src/add_cmd.am"
    for (i64 j = 0LL; j < pn; j++) {
        #line 1421 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* p = Amalgame_Compiler_TomlValue_At(pkgArr, j);
        #line 1422 "./src/add_cmd.am"
        if (code_string_equals(Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(p, "name")), pkgName)) {
            #line 1423 "./src/add_cmd.am"
            found = 1;
            #line 1424 "./src/add_cmd.am"
            urlS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(p, "url"));
        }
    }
    #line 1427 "./src/add_cmd.am"
    if (!found) {
        #line 1428 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("amc package versions: '", pkgName)), "' not found in packages-index."));
        #line 1429 "./src/add_cmd.am"
        Console_WriteError("       Use full URL form for unindexed packages:");
        #line 1430 "./src/add_cmd.am"
        Console_WriteError("       `amc package add github.com//@`");
        #line 1431 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1433 "./src/add_cmd.am"
    code_string amcVer = Amalgame_Compiler_PackageRegistry_AmcVersion();
    #line 1434 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* verArr = Amalgame_Compiler_TomlValue_Get(doc, "version");
    #line 1435 "./src/add_cmd.am"
    if (jsonOut) {
        #line 1436 "./src/add_cmd.am"
        Amalgame_Compiler_AddCommand_PrintVersionsJsonForPackage(verArr, pkgName, urlS, amcVer);
        #line 1437 "./src/add_cmd.am"
        return 0LL;
    }
    #line 1439 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat(pkgName, " — ")), urlS));
    #line 1440 "./src/add_cmd.am"
    Amalgame_Compiler_AddCommand_PrintVersionsForPackage(verArr, pkgName, amcVer);
    #line 1441 "./src/add_cmd.am"
    return 0LL;
}

i64 Amalgame_Compiler_AddCommand_EnsureInstalled() {
    #line 1457 "./src/add_cmd.am"
    code_string lockPath = "amalgame.lock";
    #line 1458 "./src/add_cmd.am"
    if (!File_Exists(lockPath)) {
        return 0LL;
    }
    #line 1459 "./src/add_cmd.am"
    code_string lockSrc = File_ReadAll(lockPath);
    #line 1460 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* lockDoc = Amalgame_Compiler_Toml_Parse(lockSrc);
    #line 1461 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsNull(lockDoc)) {
        return 0LL;
    }
    #line 1462 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* pkgs = Amalgame_Compiler_TomlValue_Get(lockDoc, "package");
    #line 1463 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsArray(pkgs)) {
        return 0LL;
    }
    #line 1465 "./src/add_cmd.am"
    code_string cacheRoot = Amalgame_Compiler_AddCommand_CacheRoot();
    #line 1466 "./src/add_cmd.am"
    i64 n = Amalgame_Compiler_TomlValue_Count(pkgs);
    #line 1467 "./src/add_cmd.am"
    i64 installed = 0LL;
    #line 1468 "./src/add_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 1469 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(pkgs, i);
        #line 1470 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* gitV = Amalgame_Compiler_TomlValue_Get(entry, "git");
        #line 1471 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* tagV = Amalgame_Compiler_TomlValue_Get(entry, "tag");
        #line 1472 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* revV = Amalgame_Compiler_TomlValue_Get(entry, "rev");
        #line 1473 "./src/add_cmd.am"
        code_string gitS = Amalgame_Compiler_TomlValue_AsString(gitV);
        #line 1474 "./src/add_cmd.am"
        code_string tagS = Amalgame_Compiler_TomlValue_AsString(tagV);
        #line 1475 "./src/add_cmd.am"
        code_string revS = Amalgame_Compiler_TomlValue_AsString(revV);
        #line 1476 "./src/add_cmd.am"
        if ((String_Length(gitS) == 0LL) || (String_Length(tagS) == 0LL)) {
            continue;
        }
        #line 1477 "./src/add_cmd.am"
        if (String_Length(revS) < 8LL) {
            continue;
        }
        #line 1478 "./src/add_cmd.am"
        code_string shortSha = String_Substring(revS, 0LL, 8LL);
        #line 1479 "./src/add_cmd.am"
        code_string pkgDir = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(cacheRoot, "/")), gitS)), "/")), tagS)), "_")), shortSha);
        #line 1480 "./src/add_cmd.am"
        code_string manifestPath = code_string_concat(pkgDir, "/amalgame.toml");
        #line 1481 "./src/add_cmd.am"
        if (File_Exists(manifestPath)) {
            continue;
        }
        #line 1485 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat("Installing missing dep: ", gitS)), "@")), tagS)), "..."));
        #line 1486 "./src/add_cmd.am"
        code_string amcPath0 = Args_Get(0LL);
        #line 1487 "./src/add_cmd.am"
        code_string amcExe = amcPath0;
        #line 1488 "./src/add_cmd.am"
        if (String_Length(amcExe) == 0LL) {
            amcExe = "amc";
        }
        #line 1489 "./src/add_cmd.am"
        i64 exit = Process_Run(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("\"", amcExe)), "\" package add \"")), gitS)), "@")), tagS)), "\""));
        #line 1490 "./src/add_cmd.am"
        if (exit != 0LL) {
            #line 1491 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat((code_string_concat("amc package add failed for ", gitS)), "@")), tagS));
            #line 1492 "./src/add_cmd.am"
            return -1LL;
        }
        #line 1494 "./src/add_cmd.am"
        installed = (installed + 1LL);
    }
    #line 1496 "./src/add_cmd.am"
    return installed;
}

i64 Amalgame_Compiler_AddCommand_RunCache(i64 argc, i64 startIdx) {
    #line 1510 "./src/add_cmd.am"
    if (argc <= startIdx) {
        #line 1511 "./src/add_cmd.am"
        Console_WriteError("Usage: amc package cache ");
        #line 1512 "./src/add_cmd.am"
        Console_WriteError("");
        #line 1513 "./src/add_cmd.am"
        Console_WriteError("Subcommands:");
        #line 1514 "./src/add_cmd.am"
        Console_WriteError("  clear         drop the packages-index cache");
        #line 1515 "./src/add_cmd.am"
        Console_WriteError("  clear --all   also wipe ~/.amalgame/packages/");
        #line 1516 "./src/add_cmd.am"
        return 2LL;
    }
    #line 1518 "./src/add_cmd.am"
    code_string sub = Args_Get(startIdx);
    #line 1519 "./src/add_cmd.am"
    if (code_string_equals(sub, "clear")) {
        #line 1520 "./src/add_cmd.am"
        code_bool alsoPackages = 0;
        #line 1521 "./src/add_cmd.am"
        code_bool helpAsked = 0;
        #line 1522 "./src/add_cmd.am"
        i64 i = startIdx + 1LL;
        #line 1523 "./src/add_cmd.am"
        while (i < argc) {
            #line 1524 "./src/add_cmd.am"
            code_string a = Args_Get(i);
            #line 1525 "./src/add_cmd.am"
            if (code_string_equals(a, "--all")) {
                alsoPackages = 1;
            }
            #line 1526 "./src/add_cmd.am"
            if (code_string_equals(a, "-h")) {
                helpAsked = 1;
            }
            #line 1527 "./src/add_cmd.am"
            if (code_string_equals(a, "--help")) {
                helpAsked = 1;
            }
            #line 1528 "./src/add_cmd.am"
            i = (i + 1LL);
        }
        #line 1530 "./src/add_cmd.am"
        if (helpAsked) {
            #line 1531 "./src/add_cmd.am"
            Console_WriteError("Usage: amc cache clear [--all]");
            #line 1532 "./src/add_cmd.am"
            return 0LL;
        }
        #line 1535 "./src/add_cmd.am"
        code_string idxPath = Amalgame_Compiler_AddCommand_IndexCachePath();
        #line 1536 "./src/add_cmd.am"
        code_bool _idxRm = File_Delete(idxPath);
        #line 1537 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat("Cleared packages-index cache (", idxPath)), ")"));
        #line 1538 "./src/add_cmd.am"
        if (alsoPackages) {
            #line 1539 "./src/add_cmd.am"
            code_string pkgRoot = Amalgame_Compiler_AddCommand_CacheRoot();
            #line 1540 "./src/add_cmd.am"
            code_bool _pkgRm = Amalgame_Compiler_AddCommand_RmRf(pkgRoot);
            #line 1541 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat((code_string_concat("Cleared package cache (", pkgRoot)), ")"));
            #line 1542 "./src/add_cmd.am"
            Console_WriteLine("Run `amc add` again to reinstall each dep.");
        }
        #line 1544 "./src/add_cmd.am"
        return 0LL;
    }
    #line 1546 "./src/add_cmd.am"
    Console_WriteError(code_string_concat("unknown cache subcommand: ", sub));
    #line 1547 "./src/add_cmd.am"
    return 2LL;
}

i64 Amalgame_Compiler_AddCommand_RunUpdate(i64 argc, i64 startIdx) {
    #line 1563 "./src/add_cmd.am"
    code_string spec = "";
    #line 1564 "./src/add_cmd.am"
    i64 i = startIdx;
    #line 1565 "./src/add_cmd.am"
    while (i < argc) {
        #line 1566 "./src/add_cmd.am"
        code_string a = Args_Get(i);
        #line 1567 "./src/add_cmd.am"
        if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) {
            #line 1568 "./src/add_cmd.am"
            Console_WriteError("Usage: amc package update @");
            #line 1569 "./src/add_cmd.am"
            Console_WriteError("");
            #line 1570 "./src/add_cmd.am"
            Console_WriteError("Bump the pinned tag for the named dep. Equivalent to");
            #line 1571 "./src/add_cmd.am"
            Console_WriteError("`amc package remove ` then `amc package add @`.");
            #line 1572 "./src/add_cmd.am"
            return 0LL;
        }
        #line 1574 "./src/add_cmd.am"
        if (String_StartsWith(a, "-")) {
            #line 1575 "./src/add_cmd.am"
            Console_WriteError(code_string_concat("unknown flag: ", a));
            #line 1576 "./src/add_cmd.am"
            return 2LL;
        }
        #line 1578 "./src/add_cmd.am"
        if (String_Length(spec) == 0LL) {
            spec = a;
        }
        #line 1579 "./src/add_cmd.am"
        i = (i + 1LL);
    }
    #line 1581 "./src/add_cmd.am"
    if (String_Length(spec) == 0LL) {
        #line 1582 "./src/add_cmd.am"
        Console_WriteError("usage: amc package update @");
        #line 1583 "./src/add_cmd.am"
        return 2LL;
    }
    #line 1585 "./src/add_cmd.am"
    i64 atIdx = String_LastIndexOf(spec, "@");
    #line 1586 "./src/add_cmd.am"
    if ((atIdx <= 0LL) || (atIdx >= (String_Length(spec) - 1LL))) {
        #line 1587 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("expected @ — got '", spec)), "'"));
        #line 1588 "./src/add_cmd.am"
        return 2LL;
    }
    #line 1590 "./src/add_cmd.am"
    code_string depName = String_Substring(spec, 0LL, atIdx);
    #line 1591 "./src/add_cmd.am"
    code_string newTag = String_Substring(spec, atIdx + 1LL, (String_Length(spec) - atIdx) - 1LL);
    #line 1594 "./src/add_cmd.am"
    if (!File_Exists("amalgame.toml")) {
        #line 1595 "./src/add_cmd.am"
        Console_WriteError("no amalgame.toml in cwd — nothing to update");
        #line 1596 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1598 "./src/add_cmd.am"
    code_string tomlSrc = File_ReadAll("amalgame.toml");
    #line 1599 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(tomlSrc);
    #line 1600 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsNull(doc)) {
        #line 1601 "./src/add_cmd.am"
        Console_WriteError("amalgame.toml parse error");
        #line 1602 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1604 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* deps = Amalgame_Compiler_TomlValue_Get(doc, "dependencies");
    #line 1605 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsTable(deps) || !Amalgame_Compiler_TomlValue_Has(deps, depName)) {
        #line 1606 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat("'", depName)), "' is not a declared dependency. Use `amc package add ")), spec)), "` to install it fresh."));
        #line 1607 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1611 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_Get(deps, depName);
    #line 1612 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* gitV = Amalgame_Compiler_TomlValue_Get(entry, "git");
    #line 1613 "./src/add_cmd.am"
    code_string gitUrl = Amalgame_Compiler_TomlValue_AsString(gitV);
    #line 1614 "./src/add_cmd.am"
    if (String_Length(gitUrl) == 0LL) {
        #line 1615 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("dependency '", depName)), "' has no git url — manifest is malformed"));
        #line 1616 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1618 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("Updating ", depName)), " → ")), newTag)), " (from ")), gitUrl)), ")"));
    #line 1630 "./src/add_cmd.am"
    return Amalgame_Compiler_AddCommand_RunInstallSpec(code_string_concat((code_string_concat(gitUrl, "@")), newTag));
}

i64 Amalgame_Compiler_AddCommand_RunInstallSpec(code_string spec) {
    #line 1638 "./src/add_cmd.am"
    AmalgameList* parsed = Amalgame_Compiler_AddCommand_ParseSpec(spec);
    #line 1639 "./src/add_cmd.am"
    if (AmalgameList_count(parsed) != 2LL) {
        #line 1640 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("RunInstallSpec: malformed spec '", spec)), "'"));
        #line 1641 "./src/add_cmd.am"
        return 2LL;
    }
    #line 1643 "./src/add_cmd.am"
    code_string url = (code_string)AmalgameList_get(parsed, 0LL);
    #line 1644 "./src/add_cmd.am"
    code_string tag = (code_string)AmalgameList_get(parsed, 1LL);
    #line 1645 "./src/add_cmd.am"
    if (!Amalgame_Compiler_AddCommand_IsSafeUrl(url)) {
        return 2LL;
    }
    #line 1646 "./src/add_cmd.am"
    if (!Amalgame_Compiler_AddCommand_IsSafeTag(tag)) {
        return 2LL;
    }
    #line 1654 "./src/add_cmd.am"
    code_string amcPath = Args_Get(0LL);
    #line 1655 "./src/add_cmd.am"
    if (String_Length(amcPath) == 0LL) {
        amcPath = "amc";
    }
    #line 1656 "./src/add_cmd.am"
    return Process_Run(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("\"", amcPath)), "\" package add \"")), url)), "@")), tag)), "\""));
}

i64 Amalgame_Compiler_AddCommand_RunList(i64 argc, i64 startIdx) {
    #line 1666 "./src/add_cmd.am"
    Amalgame_Compiler_PackageRegistry* reg = Amalgame_Compiler_PackageRegistry_Load();
    #line 1667 "./src/add_cmd.am"
    i64 n = AmalgameList_count(reg->Packages);
    #line 1668 "./src/add_cmd.am"
    if (n == 0LL) {
        #line 1669 "./src/add_cmd.am"
        Console_WriteLine("No packages installed in this project.");
        #line 1670 "./src/add_cmd.am"
        Console_WriteLine("(no amalgame.lock in cwd, or the lock has no [[package]] entries)");
        #line 1671 "./src/add_cmd.am"
        return 0LL;
    }
    #line 1673 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat(String_FromInt(n), " package(s) installed:"));
    #line 1674 "./src/add_cmd.am"
    Console_WriteLine("");
    #line 1675 "./src/add_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 1676 "./src/add_cmd.am"
        Amalgame_Compiler_LoadedPackage* lp = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(reg->Packages, i);
        #line 1681 "./src/add_cmd.am"
        code_string headline = code_string_concat("  ", lp->ClassName);
        #line 1682 "./src/add_cmd.am"
        if (String_Length(lp->Tag) > 0LL) {
            #line 1683 "./src/add_cmd.am"
            headline = (code_string_concat((code_string_concat(headline, " @ ")), lp->Tag));
        }
        #line 1685 "./src/add_cmd.am"
        headline = (code_string_concat((code_string_concat(headline, " — ")), lp->Name));
        #line 1686 "./src/add_cmd.am"
        Console_WriteLine(headline);
        #line 1687 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat("    namespace: ", lp->Ns));
        #line 1688 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat("    header:    ", lp->Header));
        #line 1689 "./src/add_cmd.am"
        Console_WriteLine("");
    }
    #line 1691 "./src/add_cmd.am"
    return 0LL;
}

i64 Amalgame_Compiler_AddCommand_RunRemove(i64 argc, i64 startIdx) {
    #line 1709 "./src/add_cmd.am"
    AmalgameList* toRemove = AmalgameList_new();
    #line 1710 "./src/add_cmd.am"
    AmalgameList* expectTags = AmalgameList_new();
    #line 1711 "./src/add_cmd.am"
    i64 i = startIdx;
    #line 1712 "./src/add_cmd.am"
    while (i < argc) {
        #line 1713 "./src/add_cmd.am"
        code_string a = Args_Get(i);
        #line 1714 "./src/add_cmd.am"
        if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) {
            #line 1715 "./src/add_cmd.am"
            Console_WriteError("Usage: amc package remove [@] [[@]...]");
            #line 1716 "./src/add_cmd.am"
            Console_WriteError("");
            #line 1717 "./src/add_cmd.am"
            Console_WriteError("Strip the named dep(s) from amalgame.toml + amalgame.lock.");
            #line 1718 "./src/add_cmd.am"
            Console_WriteError("With `@`, refuse to remove unless the installed tag matches —");
            #line 1719 "./src/add_cmd.am"
            Console_WriteError("safer than the bare-name form when you're not sure what's pinned.");
            #line 1720 "./src/add_cmd.am"
            Console_WriteError("Cached package files are kept; a future `amc package gc` verb will");
            #line 1721 "./src/add_cmd.am"
            Console_WriteError("clean unreferenced cache dirs.");
            #line 1722 "./src/add_cmd.am"
            return 0LL;
        }
        #line 1724 "./src/add_cmd.am"
        if (String_StartsWith(a, "-")) {
            #line 1725 "./src/add_cmd.am"
            Console_WriteError(code_string_concat("unknown flag: ", a));
            #line 1726 "./src/add_cmd.am"
            return 2LL;
        }
        #line 1729 "./src/add_cmd.am"
        i64 atIdx = String_IndexOf(a, "@");
        #line 1730 "./src/add_cmd.am"
        if (atIdx > 0LL) {
            #line 1731 "./src/add_cmd.am"
            AmalgameList_add(toRemove, (void*)(intptr_t)(String_Substring(a, 0LL, atIdx)));
            #line 1732 "./src/add_cmd.am"
            AmalgameList_add(expectTags, (void*)(intptr_t)(String_Substring(a, atIdx + 1LL, (String_Length(a) - atIdx) - 1LL)));
        } else {
            #line 1734 "./src/add_cmd.am"
            AmalgameList_add(toRemove, (void*)(intptr_t)(a));
            #line 1735 "./src/add_cmd.am"
            AmalgameList_add(expectTags, (void*)(intptr_t)(""));
        }
        #line 1737 "./src/add_cmd.am"
        i = (i + 1LL);
    }
    #line 1739 "./src/add_cmd.am"
    if (AmalgameList_count(toRemove) == 0LL) {
        #line 1740 "./src/add_cmd.am"
        Console_WriteError("usage: amc package remove [@] [...]");
        #line 1741 "./src/add_cmd.am"
        return 2LL;
    }
    #line 1745 "./src/add_cmd.am"
    code_string tomlPath = "amalgame.toml";
    #line 1746 "./src/add_cmd.am"
    if (!File_Exists(tomlPath)) {
        #line 1747 "./src/add_cmd.am"
        Console_WriteError("no amalgame.toml in cwd — nothing to remove");
        #line 1748 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1750 "./src/add_cmd.am"
    code_string tomlSrc = File_ReadAll(tomlPath);
    #line 1751 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(tomlSrc);
    #line 1752 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsNull(doc)) {
        #line 1753 "./src/add_cmd.am"
        Console_WriteError("amalgame.toml parse error");
        #line 1754 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1756 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* depsTable = Amalgame_Compiler_TomlValue_Get(doc, "dependencies");
    #line 1757 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsTable(depsTable)) {
        #line 1758 "./src/add_cmd.am"
        Console_WriteError("amalgame.toml has no [dependencies] table — nothing to remove");
        #line 1759 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1764 "./src/add_cmd.am"
    i64 remN = AmalgameList_count(toRemove);
    #line 1765 "./src/add_cmd.am"
    for (i64 ri = 0LL; ri < remN; ri++) {
        #line 1766 "./src/add_cmd.am"
        code_string name = (code_string)AmalgameList_get(toRemove, ri);
        #line 1767 "./src/add_cmd.am"
        code_string want = (code_string)AmalgameList_get(expectTags, ri);
        #line 1768 "./src/add_cmd.am"
        if (!Amalgame_Compiler_TomlValue_Has(depsTable, name)) {
            #line 1769 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat("'", name)), "' is not a declared dependency"));
            #line 1770 "./src/add_cmd.am"
            return 1LL;
        }
        #line 1772 "./src/add_cmd.am"
        if (String_Length(want) > 0LL) {
            #line 1777 "./src/add_cmd.am"
            Amalgame_Compiler_TomlValue* depEntry = Amalgame_Compiler_TomlValue_Get(depsTable, name);
            #line 1778 "./src/add_cmd.am"
            code_string installedTag = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(depEntry, "tag"));
            #line 1779 "./src/add_cmd.am"
            if (!code_string_equals(installedTag, want)) {
                #line 1780 "./src/add_cmd.am"
                Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("'", name)), "' is pinned to ")), installedTag)), ", not ")), want)), " — refusing to remove."));
                #line 1781 "./src/add_cmd.am"
                Console_WriteError("       Drop the @ suffix to remove whatever version is installed.");
                #line 1782 "./src/add_cmd.am"
                return 1LL;
            }
        }
    }
    #line 1790 "./src/add_cmd.am"
    AmalgameList* oldKeys = Amalgame_Compiler_TomlValue_Keys(depsTable);
    #line 1791 "./src/add_cmd.am"
    i64 oldN = AmalgameList_count(oldKeys);
    #line 1792 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* newDeps = Amalgame_Compiler_TomlValue_new();
    #line 1793 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue_BecomeTable(newDeps);
    #line 1794 "./src/add_cmd.am"
    for (i64 ki = 0LL; ki < oldN; ki++) {
        #line 1795 "./src/add_cmd.am"
        code_string k = (code_string)AmalgameList_get(oldKeys, ki);
        #line 1796 "./src/add_cmd.am"
        code_bool skip = 0;
        #line 1797 "./src/add_cmd.am"
        for (i64 rj = 0LL; rj < remN; rj++) {
            #line 1802 "./src/add_cmd.am"
            code_string removeName = (code_string)AmalgameList_get(toRemove, rj);
            #line 1803 "./src/add_cmd.am"
            if (code_string_equals(removeName, k)) {
                skip = 1;
            }
        }
        #line 1805 "./src/add_cmd.am"
        if (!skip) {
            #line 1806 "./src/add_cmd.am"
            Amalgame_Compiler_TomlValue* v = Amalgame_Compiler_TomlValue_Get(depsTable, k);
            #line 1807 "./src/add_cmd.am"
            Amalgame_Compiler_TomlValue_SetEntry(newDeps, k, v);
        }
    }
    #line 1810 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue_SetEntry(doc, "dependencies", newDeps);
    #line 1811 "./src/add_cmd.am"
    code_string out = Amalgame_Compiler_Toml_Serialize(doc);
    #line 1812 "./src/add_cmd.am"
    code_bool ok = File_WriteAll(tomlPath, out);
    #line 1813 "./src/add_cmd.am"
    if (!ok) {
        #line 1814 "./src/add_cmd.am"
        Console_WriteError("could not write amalgame.toml");
        #line 1815 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1821 "./src/add_cmd.am"
    code_string lockPath = "amalgame.lock";
    #line 1822 "./src/add_cmd.am"
    if (File_Exists(lockPath)) {
        #line 1823 "./src/add_cmd.am"
        Amalgame_Compiler_AddCommand_RebuildLockFromTomlDeps(newDeps, lockPath);
    }
    #line 1827 "./src/add_cmd.am"
    for (i64 ri2 = 0LL; ri2 < remN; ri2++) {
        #line 1828 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat("Removed '", (code_string)AmalgameList_get(toRemove, ri2))), "' from amalgame.toml + amalgame.lock."));
    }
    #line 1830 "./src/add_cmd.am"
    Console_WriteLine("(cached files at ~/.amalgame/packages/... were kept — `amc gc` reclaims those)");
    #line 1831 "./src/add_cmd.am"
    return 0LL;
}

void Amalgame_Compiler_AddCommand_RebuildLockFromTomlDeps(Amalgame_Compiler_TomlValue* depsTable, code_string lockPath) {
    #line 1840 "./src/add_cmd.am"
    code_string cacheRoot = Amalgame_Compiler_AddCommand_CacheRoot();
    #line 1841 "./src/add_cmd.am"
    code_string out = "# amalgame.lock — auto-generated, commit me\n";
    #line 1842 "./src/add_cmd.am"
    AmalgameList* keys = Amalgame_Compiler_TomlValue_Keys(depsTable);
    #line 1843 "./src/add_cmd.am"
    i64 n = AmalgameList_count(keys);
    #line 1844 "./src/add_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 1845 "./src/add_cmd.am"
        code_string depName = (code_string)AmalgameList_get(keys, i);
        #line 1846 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_Get(depsTable, depName);
        #line 1847 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* gitV = Amalgame_Compiler_TomlValue_Get(entry, "git");
        #line 1848 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* tagV = Amalgame_Compiler_TomlValue_Get(entry, "tag");
        #line 1849 "./src/add_cmd.am"
        code_string gitS = Amalgame_Compiler_TomlValue_AsString(gitV);
        #line 1850 "./src/add_cmd.am"
        code_string tagS = Amalgame_Compiler_TomlValue_AsString(tagV);
        #line 1851 "./src/add_cmd.am"
        if ((String_Length(gitS) == 0LL) || (String_Length(tagS) == 0LL)) {
            continue;
        }
        #line 1853 "./src/add_cmd.am"
        code_string baseDir = code_string_concat((code_string_concat(cacheRoot, "/")), gitS);
        #line 1854 "./src/add_cmd.am"
        code_string existing = Amalgame_Compiler_AddCommand_FindExistingForTag(baseDir, tagS);
        #line 1855 "./src/add_cmd.am"
        if (String_Length(existing) == 0LL) {
            continue;
        }
        #line 1856 "./src/add_cmd.am"
        code_string rev = Amalgame_Compiler_AddCommand_ExtractRevFromDirName(existing);
        #line 1860 "./src/add_cmd.am"
        out = (code_string_concat(out, "\n[[package]]\n"));
        #line 1861 "./src/add_cmd.am"
        out = (code_string_concat((code_string_concat((code_string_concat(out, "name = \"")), depName)), "\"\n"));
        #line 1862 "./src/add_cmd.am"
        out = (code_string_concat((code_string_concat((code_string_concat(out, "git  = \"")), gitS)), "\"\n"));
        #line 1863 "./src/add_cmd.am"
        out = (code_string_concat((code_string_concat((code_string_concat(out, "tag  = \"")), tagS)), "\"\n"));
        #line 1864 "./src/add_cmd.am"
        out = (code_string_concat((code_string_concat((code_string_concat(out, "rev  = \"")), rev)), "\"\n"));
    }
    #line 1866 "./src/add_cmd.am"
    code_bool _ok = File_WriteAll(lockPath, out);
}

i64 Amalgame_Compiler_AddCommand_RunSearch(i64 argc, i64 startIdx) {
    #line 1877 "./src/add_cmd.am"
    code_string keyword = "";
    #line 1878 "./src/add_cmd.am"
    code_bool refresh = 0;
    #line 1879 "./src/add_cmd.am"
    code_bool noVersions = 0;
    #line 1880 "./src/add_cmd.am"
    i64 i = startIdx;
    #line 1881 "./src/add_cmd.am"
    while (i < argc) {
        #line 1882 "./src/add_cmd.am"
        code_string a = Args_Get(i);
        #line 1883 "./src/add_cmd.am"
        if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) {
            #line 1884 "./src/add_cmd.am"
            Console_WriteError("Usage: amc package search [keyword] [--refresh] [--no-versions]");
            #line 1885 "./src/add_cmd.am"
            Console_WriteError("");
            #line 1886 "./src/add_cmd.am"
            Console_WriteError("List packages in amalgame-lang/packages-index.");
            #line 1887 "./src/add_cmd.am"
            Console_WriteError("With a keyword, filter by name + description substring.");
            #line 1888 "./src/add_cmd.am"
            Console_WriteError("Each match shows its known versions and compat status");
            #line 1889 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat("against your amc ", Amalgame_Compiler_PackageRegistry_AmcVersion())), "."));
            #line 1890 "./src/add_cmd.am"
            Console_WriteError("");
            #line 1891 "./src/add_cmd.am"
            Console_WriteError("--refresh       force re-download of the index (cache TTL 30 min).");
            #line 1892 "./src/add_cmd.am"
            Console_WriteError("--no-versions   omit the per-package versions block — faster browse,");
            #line 1893 "./src/add_cmd.am"
            Console_WriteError("                useful when you only want names + urls.");
            #line 1894 "./src/add_cmd.am"
            return 0LL;
        }
        #line 1896 "./src/add_cmd.am"
        if (code_string_equals(a, "--refresh")) {
            #line 1897 "./src/add_cmd.am"
            refresh = 1;
        } else if (code_string_equals(a, "--no-versions")) {
            #line 1899 "./src/add_cmd.am"
            noVersions = 1;
        } else if (String_Length(keyword) == 0LL) {
            #line 1901 "./src/add_cmd.am"
            keyword = a;
        }
        #line 1903 "./src/add_cmd.am"
        i = (i + 1LL);
    }
    #line 1905 "./src/add_cmd.am"
    code_string kw = String_ToLower(keyword);
    #line 1906 "./src/add_cmd.am"
    if (refresh) {
        #line 1907 "./src/add_cmd.am"
        code_string cachePath = Amalgame_Compiler_AddCommand_IndexCachePath();
        #line 1908 "./src/add_cmd.am"
        if (File_Exists(cachePath)) {
            #line 1909 "./src/add_cmd.am"
            code_bool _rm = File_Delete(cachePath);
        }
    }
    #line 1912 "./src/add_cmd.am"
    code_string indexSrc = Amalgame_Compiler_AddCommand_FetchIndex();
    #line 1913 "./src/add_cmd.am"
    if (String_Length(indexSrc) == 0LL) {
        #line 1914 "./src/add_cmd.am"
        Console_WriteError("could not fetch packages-index");
        #line 1915 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1917 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(indexSrc);
    #line 1918 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsNull(doc)) {
        #line 1919 "./src/add_cmd.am"
        Console_WriteError("packages-index parse error");
        #line 1920 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1922 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* pkgArr = Amalgame_Compiler_TomlValue_Get(doc, "package");
    #line 1923 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsArray(pkgArr)) {
        #line 1924 "./src/add_cmd.am"
        Console_WriteError("packages-index has no [[package]] entries");
        #line 1925 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1927 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* verArr = Amalgame_Compiler_TomlValue_Get(doc, "version");
    #line 1928 "./src/add_cmd.am"
    code_string amcVer = Amalgame_Compiler_PackageRegistry_AmcVersion();
    #line 1929 "./src/add_cmd.am"
    i64 n = Amalgame_Compiler_TomlValue_Count(pkgArr);
    #line 1930 "./src/add_cmd.am"
    i64 matches = 0LL;
    #line 1931 "./src/add_cmd.am"
    for (i64 j = 0LL; j < n; j++) {
        #line 1932 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(pkgArr, j);
        #line 1933 "./src/add_cmd.am"
        code_string nameS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "name"));
        #line 1934 "./src/add_cmd.am"
        code_string descS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "description"));
        #line 1935 "./src/add_cmd.am"
        code_string tierS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "tier"));
        #line 1936 "./src/add_cmd.am"
        code_string urlS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "url"));
        #line 1937 "./src/add_cmd.am"
        code_string licS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "license"));
        #line 1938 "./src/add_cmd.am"
        code_bool skip = 0;
        #line 1939 "./src/add_cmd.am"
        if (String_Length(kw) > 0LL) {
            #line 1940 "./src/add_cmd.am"
            code_string nameL = String_ToLower(nameS);
            #line 1941 "./src/add_cmd.am"
            code_string descL = String_ToLower(descS);
            #line 1942 "./src/add_cmd.am"
            if ((String_IndexOf(nameL, kw) < 0LL) && (String_IndexOf(descL, kw) < 0LL)) {
                #line 1943 "./src/add_cmd.am"
                skip = 1;
            }
        }
        #line 1946 "./src/add_cmd.am"
        if (skip) {
            continue;
        }
        #line 1947 "./src/add_cmd.am"
        code_string badge = "  ";
        #line 1948 "./src/add_cmd.am"
        if (code_string_equals(tierS, "official")) {
            badge = "✓ ";
        }
        #line 1949 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat((code_string_concat(badge, nameS)), " — ")), descS));
        #line 1950 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("    ", urlS)), " (")), tierS)), ", ")), licS)), ")"));
        #line 1951 "./src/add_cmd.am"
        if (!noVersions) {
            #line 1952 "./src/add_cmd.am"
            Amalgame_Compiler_AddCommand_PrintVersionsForPackage(verArr, nameS, amcVer);
        }
        #line 1954 "./src/add_cmd.am"
        Console_WriteLine("");
        #line 1955 "./src/add_cmd.am"
        matches = (matches + 1LL);
    }
    #line 1957 "./src/add_cmd.am"
    if (matches == 0LL) {
        #line 1958 "./src/add_cmd.am"
        if (String_Length(kw) > 0LL) {
            #line 1959 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat((code_string_concat("No packages match '", keyword)), "'."));
        } else {
            #line 1961 "./src/add_cmd.am"
            Console_WriteLine("(packages-index is empty)");
        }
        #line 1963 "./src/add_cmd.am"
        return 1LL;
    }
    #line 1965 "./src/add_cmd.am"
    return 0LL;
}

void Amalgame_Compiler_AddCommand_PrintVersionsForPackage(Amalgame_Compiler_TomlValue* verArr, code_string pkgName, code_string amcVer) {
    #line 1974 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsArray(verArr)) {
        #line 1975 "./src/add_cmd.am"
        Console_WriteLine("    versions: (no [[version]] entries in index)");
        #line 1976 "./src/add_cmd.am"
        return;
    }
    #line 1978 "./src/add_cmd.am"
    i64 n = Amalgame_Compiler_TomlValue_Count(verArr);
    #line 1982 "./src/add_cmd.am"
    AmalgameList* tags = AmalgameList_new();
    #line 1983 "./src/add_cmd.am"
    AmalgameList* reqs = AmalgameList_new();
    #line 1984 "./src/add_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 1985 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(verArr, i);
        #line 1986 "./src/add_cmd.am"
        code_string pkg = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "package"));
        #line 1987 "./src/add_cmd.am"
        if (!code_string_equals(pkg, pkgName)) {
            continue;
        }
        #line 1988 "./src/add_cmd.am"
        code_string tag = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "tag"));
        #line 1989 "./src/add_cmd.am"
        code_string req = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "required-amalgame"));
        #line 1990 "./src/add_cmd.am"
        if (String_Length(tag) == 0LL) {
            continue;
        }
        #line 1991 "./src/add_cmd.am"
        AmalgameList_add(tags, (void*)(intptr_t)(tag));
        #line 1992 "./src/add_cmd.am"
        AmalgameList_add(reqs, (void*)(intptr_t)(req));
    }
    #line 1994 "./src/add_cmd.am"
    i64 count = AmalgameList_count(tags);
    #line 1995 "./src/add_cmd.am"
    if (count == 0LL) {
        #line 1996 "./src/add_cmd.am"
        Console_WriteLine("    versions: (none indexed yet — use full URL form)");
        #line 1997 "./src/add_cmd.am"
        return;
    }
    #line 2001 "./src/add_cmd.am"
    i64 latestCompat = -1LL;
    #line 2002 "./src/add_cmd.am"
    for (i64 j = 0LL; j < count; j++) {
        #line 2003 "./src/add_cmd.am"
        code_string req = (code_string)AmalgameList_get(reqs, j);
        #line 2004 "./src/add_cmd.am"
        if (Amalgame_Compiler_PackageRegistry_VersionSatisfies(amcVer, req)) {
            #line 2005 "./src/add_cmd.am"
            latestCompat = j;
        }
    }
    #line 2008 "./src/add_cmd.am"
    Console_WriteLine("    versions:");
    #line 2010 "./src/add_cmd.am"
    i64 k = count - 1LL;
    #line 2011 "./src/add_cmd.am"
    while (k >= 0LL) {
        #line 2012 "./src/add_cmd.am"
        code_string tag = (code_string)AmalgameList_get(tags, k);
        #line 2013 "./src/add_cmd.am"
        code_string req = (code_string)AmalgameList_get(reqs, k);
        #line 2014 "./src/add_cmd.am"
        code_string line = code_string_concat("      ", tag);
        #line 2015 "./src/add_cmd.am"
        code_bool compat = 1;
        #line 2016 "./src/add_cmd.am"
        if (String_Length(req) > 0LL) {
            #line 2017 "./src/add_cmd.am"
            compat = Amalgame_Compiler_PackageRegistry_VersionSatisfies(amcVer, req);
        }
        #line 2019 "./src/add_cmd.am"
        if (compat) {
            #line 2020 "./src/add_cmd.am"
            line = (code_string_concat(line, " ✓"));
        } else {
            #line 2022 "./src/add_cmd.am"
            line = (code_string_concat(line, " ✗"));
        }
        #line 2024 "./src/add_cmd.am"
        if (String_Length(req) > 0LL) {
            #line 2025 "./src/add_cmd.am"
            line = (code_string_concat((code_string_concat((code_string_concat(line, " (needs amc ")), req)), ")"));
        }
        #line 2027 "./src/add_cmd.am"
        if (k == latestCompat) {
            #line 2028 "./src/add_cmd.am"
            line = (code_string_concat(line, "  ← latest compatible"));
        }
        #line 2030 "./src/add_cmd.am"
        Console_WriteLine(line);
        #line 2031 "./src/add_cmd.am"
        k = (k - 1LL);
    }
}

void Amalgame_Compiler_AddCommand_PrintVersionsJsonForPackage(Amalgame_Compiler_TomlValue* verArr, code_string pkgName, code_string urlS, code_string amcVer) {
    #line 2042 "./src/add_cmd.am"
    AmalgameList* tags = AmalgameList_new();
    #line 2043 "./src/add_cmd.am"
    AmalgameList* reqs = AmalgameList_new();
    #line 2044 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsArray(verArr)) {
        #line 2045 "./src/add_cmd.am"
        i64 n = Amalgame_Compiler_TomlValue_Count(verArr);
        #line 2046 "./src/add_cmd.am"
        for (i64 i = 0LL; i < n; i++) {
            #line 2047 "./src/add_cmd.am"
            Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(verArr, i);
            #line 2048 "./src/add_cmd.am"
            if (!code_string_equals(Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "package")), pkgName)) {
                continue;
            }
            #line 2049 "./src/add_cmd.am"
            code_string tag = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "tag"));
            #line 2050 "./src/add_cmd.am"
            if (String_Length(tag) == 0LL) {
                continue;
            }
            #line 2051 "./src/add_cmd.am"
            AmalgameList_add(tags, (void*)(intptr_t)(tag));
            #line 2052 "./src/add_cmd.am"
            AmalgameList_add(reqs, (void*)(intptr_t)(Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "required-amalgame"))));
        }
    }
    #line 2055 "./src/add_cmd.am"
    i64 count = AmalgameList_count(tags);
    #line 2056 "./src/add_cmd.am"
    i64 latestCompat = -1LL;
    #line 2057 "./src/add_cmd.am"
    for (i64 j = 0LL; j < count; j++) {
        #line 2058 "./src/add_cmd.am"
        if (Amalgame_Compiler_PackageRegistry_VersionSatisfies(amcVer, (code_string)AmalgameList_get(reqs, j))) {
            #line 2059 "./src/add_cmd.am"
            latestCompat = j;
        }
    }
    #line 2062 "./src/add_cmd.am"
    code_string out = "{\n";
    #line 2063 "./src/add_cmd.am"
    out = (code_string_concat((code_string_concat((code_string_concat(out, "  \"package\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(pkgName))), "\",\n"));
    #line 2064 "./src/add_cmd.am"
    out = (code_string_concat((code_string_concat((code_string_concat(out, "  \"url\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(urlS))), "\",\n"));
    #line 2065 "./src/add_cmd.am"
    out = (code_string_concat((code_string_concat((code_string_concat(out, "  \"amc\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(amcVer))), "\",\n"));
    #line 2066 "./src/add_cmd.am"
    out = (code_string_concat(out, "  \"versions\": ["));
    #line 2067 "./src/add_cmd.am"
    if (count == 0LL) {
        #line 2068 "./src/add_cmd.am"
        out = (code_string_concat(out, "]\n}"));
        #line 2069 "./src/add_cmd.am"
        Console_WriteLine(out);
        #line 2070 "./src/add_cmd.am"
        return;
    }
    #line 2072 "./src/add_cmd.am"
    out = (code_string_concat(out, "\n"));
    #line 2075 "./src/add_cmd.am"
    i64 k = count - 1LL;
    #line 2076 "./src/add_cmd.am"
    while (k >= 0LL) {
        #line 2077 "./src/add_cmd.am"
        code_string tag = (code_string)AmalgameList_get(tags, k);
        #line 2078 "./src/add_cmd.am"
        code_string req = (code_string)AmalgameList_get(reqs, k);
        #line 2079 "./src/add_cmd.am"
        code_bool compat = 1;
        #line 2080 "./src/add_cmd.am"
        if (String_Length(req) > 0LL) {
            #line 2081 "./src/add_cmd.am"
            compat = Amalgame_Compiler_PackageRegistry_VersionSatisfies(amcVer, req);
        }
        #line 2083 "./src/add_cmd.am"
        code_string entryOut = "    {";
        #line 2084 "./src/add_cmd.am"
        entryOut = (code_string_concat((code_string_concat((code_string_concat(entryOut, "\"tag\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(tag))), "\""));
        #line 2085 "./src/add_cmd.am"
        entryOut = (code_string_concat((code_string_concat((code_string_concat(entryOut, ", \"required-amalgame\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(req))), "\""));
        #line 2086 "./src/add_cmd.am"
        if (compat) {
            #line 2087 "./src/add_cmd.am"
            entryOut = (code_string_concat(entryOut, ", \"compatible\": true"));
        } else {
            #line 2089 "./src/add_cmd.am"
            entryOut = (code_string_concat(entryOut, ", \"compatible\": false"));
        }
        #line 2091 "./src/add_cmd.am"
        if (k == latestCompat) {
            #line 2092 "./src/add_cmd.am"
            entryOut = (code_string_concat(entryOut, ", \"latest_compatible\": true"));
        } else {
            #line 2094 "./src/add_cmd.am"
            entryOut = (code_string_concat(entryOut, ", \"latest_compatible\": false"));
        }
        #line 2096 "./src/add_cmd.am"
        entryOut = (code_string_concat(entryOut, "}"));
        #line 2097 "./src/add_cmd.am"
        if (k > 0LL) {
            #line 2098 "./src/add_cmd.am"
            entryOut = (code_string_concat(entryOut, ","));
        }
        #line 2100 "./src/add_cmd.am"
        out = (code_string_concat((code_string_concat(out, entryOut)), "\n"));
        #line 2101 "./src/add_cmd.am"
        k = (k - 1LL);
    }
    #line 2103 "./src/add_cmd.am"
    out = (code_string_concat(out, "  ]\n}"));
    #line 2104 "./src/add_cmd.am"
    Console_WriteLine(out);
}

i64 Amalgame_Compiler_AddCommand_RunSuggest(i64 argc, i64 startIdx) {
    #line 2137 "./src/add_cmd.am"
    code_string query = "";
    #line 2138 "./src/add_cmd.am"
    code_bool refresh = 0;
    #line 2139 "./src/add_cmd.am"
    code_bool jsonOut = 0;
    #line 2140 "./src/add_cmd.am"
    i64 i = startIdx;
    #line 2141 "./src/add_cmd.am"
    while (i < argc) {
        #line 2142 "./src/add_cmd.am"
        code_string a = Args_Get(i);
        #line 2143 "./src/add_cmd.am"
        if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) {
            #line 2144 "./src/add_cmd.am"
            Console_WriteError("Usage: amc package suggest  [--json] [--refresh]");
            #line 2145 "./src/add_cmd.am"
            Console_WriteError("");
            #line 2146 "./src/add_cmd.am"
            Console_WriteError("Suggest packages from the curated index that match a class");
            #line 2147 "./src/add_cmd.am"
            Console_WriteError("or namespace. Intended for LSP `using X;` quickfix integration.");
            #line 2148 "./src/add_cmd.am"
            Console_WriteError("");
            #line 2149 "./src/add_cmd.am"
            Console_WriteError("Examples:");
            #line 2150 "./src/add_cmd.am"
            Console_WriteError("  amc package suggest Crypto --json");
            #line 2151 "./src/add_cmd.am"
            Console_WriteError("  amc package suggest Amalgame.IO.FileWatcher");
            #line 2152 "./src/add_cmd.am"
            Console_WriteError("  amc package suggest yaml");
            #line 2153 "./src/add_cmd.am"
            return 0LL;
        }
        #line 2155 "./src/add_cmd.am"
        if (code_string_equals(a, "--refresh")) {
            #line 2156 "./src/add_cmd.am"
            refresh = 1;
        } else if (code_string_equals(a, "--json")) {
            #line 2158 "./src/add_cmd.am"
            jsonOut = 1;
        } else if (String_Length(query) == 0LL) {
            #line 2160 "./src/add_cmd.am"
            query = a;
        }
        #line 2162 "./src/add_cmd.am"
        i = (i + 1LL);
    }
    #line 2164 "./src/add_cmd.am"
    if (String_Length(query) == 0LL) {
        #line 2165 "./src/add_cmd.am"
        Console_WriteError("amc package suggest: missing  argument");
        #line 2166 "./src/add_cmd.am"
        Console_WriteError("Run `amc package suggest --help` for usage.");
        #line 2167 "./src/add_cmd.am"
        return 2LL;
    }
    #line 2173 "./src/add_cmd.am"
    code_string tail = query;
    #line 2174 "./src/add_cmd.am"
    i64 lastDot = String_LastIndexOf(query, ".");
    #line 2175 "./src/add_cmd.am"
    if ((lastDot >= 0LL) && ((lastDot + 1LL) < String_Length(query))) {
        #line 2176 "./src/add_cmd.am"
        tail = String_Substring(query, lastDot + 1LL, (String_Length(query) - lastDot) - 1LL);
    }
    #line 2178 "./src/add_cmd.am"
    code_string tailL = String_ToLower(tail);
    #line 2179 "./src/add_cmd.am"
    code_string queryL = String_ToLower(query);
    #line 2181 "./src/add_cmd.am"
    if (refresh) {
        #line 2182 "./src/add_cmd.am"
        code_string cachePath = Amalgame_Compiler_AddCommand_IndexCachePath();
        #line 2183 "./src/add_cmd.am"
        if (File_Exists(cachePath)) {
            #line 2184 "./src/add_cmd.am"
            code_bool _rm = File_Delete(cachePath);
        }
    }
    #line 2187 "./src/add_cmd.am"
    code_string indexSrc = Amalgame_Compiler_AddCommand_FetchIndex();
    #line 2188 "./src/add_cmd.am"
    if (String_Length(indexSrc) == 0LL) {
        #line 2189 "./src/add_cmd.am"
        if (jsonOut) {
            #line 2190 "./src/add_cmd.am"
            Console_WriteLine("[]");
        } else {
            #line 2192 "./src/add_cmd.am"
            Console_WriteError("could not fetch packages-index");
        }
        #line 2194 "./src/add_cmd.am"
        return 1LL;
    }
    #line 2196 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(indexSrc);
    #line 2197 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsNull(doc)) {
        #line 2198 "./src/add_cmd.am"
        if (jsonOut) {
            #line 2199 "./src/add_cmd.am"
            Console_WriteLine("[]");
        } else {
            #line 2201 "./src/add_cmd.am"
            Console_WriteError("packages-index parse error");
        }
        #line 2203 "./src/add_cmd.am"
        return 1LL;
    }
    #line 2205 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* pkgArr = Amalgame_Compiler_TomlValue_Get(doc, "package");
    #line 2206 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsArray(pkgArr)) {
        #line 2207 "./src/add_cmd.am"
        if (jsonOut) {
            #line 2208 "./src/add_cmd.am"
            Console_WriteLine("[]");
        } else {
            #line 2210 "./src/add_cmd.am"
            Console_WriteError("packages-index has no [[package]] entries");
        }
        #line 2212 "./src/add_cmd.am"
        return 1LL;
    }
    #line 2214 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* verArr = Amalgame_Compiler_TomlValue_Get(doc, "version");
    #line 2215 "./src/add_cmd.am"
    code_string amcVer = Amalgame_Compiler_PackageRegistry_AmcVersion();
    #line 2220 "./src/add_cmd.am"
    AmalgameList* matchedNames = AmalgameList_new();
    #line 2221 "./src/add_cmd.am"
    AmalgameList* matchedReasons = AmalgameList_new();
    #line 2222 "./src/add_cmd.am"
    i64 n = Amalgame_Compiler_TomlValue_Count(pkgArr);
    #line 2223 "./src/add_cmd.am"
    for (i64 j = 0LL; j < n; j++) {
        #line 2224 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(pkgArr, j);
        #line 2225 "./src/add_cmd.am"
        code_string nameS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "name"));
        #line 2226 "./src/add_cmd.am"
        code_string nameL = String_ToLower(nameS);
        #line 2227 "./src/add_cmd.am"
        if ((code_string_equals(nameL, tailL)) && (lastDot >= 0LL)) {
            #line 2228 "./src/add_cmd.am"
            AmalgameList_add(matchedNames, (void*)(intptr_t)(nameS));
            #line 2229 "./src/add_cmd.am"
            AmalgameList_add(matchedReasons, (void*)(intptr_t)("namespace-tail"));
        } else if ((code_string_equals(nameL, queryL)) || (code_string_equals(nameL, tailL))) {
            #line 2231 "./src/add_cmd.am"
            AmalgameList_add(matchedNames, (void*)(intptr_t)(nameS));
            #line 2232 "./src/add_cmd.am"
            AmalgameList_add(matchedReasons, (void*)(intptr_t)("class-name"));
        }
    }
    #line 2236 "./src/add_cmd.am"
    if (AmalgameList_count(matchedNames) == 0LL) {
        #line 2237 "./src/add_cmd.am"
        for (i64 j = 0LL; j < n; j++) {
            #line 2238 "./src/add_cmd.am"
            Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(pkgArr, j);
            #line 2239 "./src/add_cmd.am"
            code_string nameS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "name"));
            #line 2240 "./src/add_cmd.am"
            code_string nameL = String_ToLower(nameS);
            #line 2241 "./src/add_cmd.am"
            if (String_IndexOf(nameL, tailL) >= 0LL) {
                #line 2242 "./src/add_cmd.am"
                AmalgameList_add(matchedNames, (void*)(intptr_t)(nameS));
                #line 2243 "./src/add_cmd.am"
                AmalgameList_add(matchedReasons, (void*)(intptr_t)("name-substring"));
            }
        }
    }
    #line 2249 "./src/add_cmd.am"
    if (AmalgameList_count(matchedNames) == 0LL) {
        #line 2250 "./src/add_cmd.am"
        for (i64 j = 0LL; j < n; j++) {
            #line 2251 "./src/add_cmd.am"
            Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(pkgArr, j);
            #line 2252 "./src/add_cmd.am"
            code_string nameS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "name"));
            #line 2253 "./src/add_cmd.am"
            code_string descL = String_ToLower(Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "description")));
            #line 2254 "./src/add_cmd.am"
            if (String_IndexOf(descL, tailL) >= 0LL) {
                #line 2255 "./src/add_cmd.am"
                AmalgameList_add(matchedNames, (void*)(intptr_t)(nameS));
                #line 2256 "./src/add_cmd.am"
                AmalgameList_add(matchedReasons, (void*)(intptr_t)("description-substring"));
            }
        }
    }
    #line 2261 "./src/add_cmd.am"
    i64 mc = AmalgameList_count(matchedNames);
    #line 2262 "./src/add_cmd.am"
    if (jsonOut) {
        #line 2263 "./src/add_cmd.am"
        code_string out = "[";
        #line 2264 "./src/add_cmd.am"
        if (mc == 0LL) {
            #line 2265 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat(out, "]"));
            #line 2266 "./src/add_cmd.am"
            return 0LL;
        }
        #line 2268 "./src/add_cmd.am"
        for (i64 k = 0LL; k < mc; k++) {
            #line 2269 "./src/add_cmd.am"
            code_string nm = (code_string)AmalgameList_get(matchedNames, k);
            #line 2270 "./src/add_cmd.am"
            code_string reason = (code_string)AmalgameList_get(matchedReasons, k);
            #line 2271 "./src/add_cmd.am"
            Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_AddCommand_FindPackageByName(pkgArr, nm);
            #line 2272 "./src/add_cmd.am"
            code_string descS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "description"));
            #line 2273 "./src/add_cmd.am"
            code_string tierS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "tier"));
            #line 2274 "./src/add_cmd.am"
            code_string urlS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "url"));
            #line 2275 "./src/add_cmd.am"
            code_string licS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "license"));
            #line 2276 "./src/add_cmd.am"
            code_string catS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "category"));
            #line 2277 "./src/add_cmd.am"
            code_string latest = Amalgame_Compiler_AddCommand_LatestCompatibleTag(verArr, nm, amcVer);
            #line 2278 "./src/add_cmd.am"
            code_string item = "\n  {";
            #line 2279 "./src/add_cmd.am"
            item = (code_string_concat((code_string_concat((code_string_concat(item, "\"name\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(nm))), "\","));
            #line 2280 "./src/add_cmd.am"
            item = (code_string_concat((code_string_concat((code_string_concat(item, "\"url\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(urlS))), "\","));
            #line 2281 "./src/add_cmd.am"
            item = (code_string_concat((code_string_concat((code_string_concat(item, "\"description\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(descS))), "\","));
            #line 2282 "./src/add_cmd.am"
            item = (code_string_concat((code_string_concat((code_string_concat(item, "\"tier\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(tierS))), "\","));
            #line 2283 "./src/add_cmd.am"
            item = (code_string_concat((code_string_concat((code_string_concat(item, "\"license\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(licS))), "\","));
            #line 2284 "./src/add_cmd.am"
            item = (code_string_concat((code_string_concat((code_string_concat(item, "\"category\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(catS))), "\","));
            #line 2285 "./src/add_cmd.am"
            item = (code_string_concat((code_string_concat((code_string_concat(item, "\"latest_compatible_tag\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(latest))), "\","));
            #line 2286 "./src/add_cmd.am"
            item = (code_string_concat((code_string_concat((code_string_concat(item, "\"match_reason\": \"")), Amalgame_Compiler_AddCommand_JsonEscape(reason))), "\"}"));
            #line 2287 "./src/add_cmd.am"
            if ((k + 1LL) < mc) {
                #line 2288 "./src/add_cmd.am"
                item = (code_string_concat(item, ","));
            }
            #line 2290 "./src/add_cmd.am"
            out = (code_string_concat(out, item));
        }
        #line 2292 "./src/add_cmd.am"
        out = (code_string_concat(out, "\n]"));
        #line 2293 "./src/add_cmd.am"
        Console_WriteLine(out);
        #line 2294 "./src/add_cmd.am"
        return 0LL;
    }
    #line 2297 "./src/add_cmd.am"
    if (mc == 0LL) {
        #line 2298 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat("No packages match '", query)), "'."));
        #line 2299 "./src/add_cmd.am"
        Console_WriteLine("Run `amc package search` to browse the full curated index.");
        #line 2300 "./src/add_cmd.am"
        return 1LL;
    }
    #line 2302 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat("Suggestions for '", query)), "':"));
    #line 2303 "./src/add_cmd.am"
    Console_WriteLine("");
    #line 2304 "./src/add_cmd.am"
    for (i64 k = 0LL; k < mc; k++) {
        #line 2305 "./src/add_cmd.am"
        code_string nm = (code_string)AmalgameList_get(matchedNames, k);
        #line 2306 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_AddCommand_FindPackageByName(pkgArr, nm);
        #line 2307 "./src/add_cmd.am"
        code_string descS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "description"));
        #line 2308 "./src/add_cmd.am"
        code_string urlS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "url"));
        #line 2309 "./src/add_cmd.am"
        code_string latest = Amalgame_Compiler_AddCommand_LatestCompatibleTag(verArr, nm, amcVer);
        #line 2310 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat((code_string_concat("  ", nm)), " — ")), descS));
        #line 2311 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat("    ", urlS));
        #line 2312 "./src/add_cmd.am"
        if (String_Length(latest) > 0LL) {
            #line 2313 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat((code_string_concat((code_string_concat("    install: amc package add ", nm)), "@")), latest));
        } else {
            #line 2315 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat((code_string_concat("    install: amc package add ", nm)), "  (no compatible tag indexed yet)"));
        }
        #line 2317 "./src/add_cmd.am"
        Console_WriteLine("");
    }
    #line 2319 "./src/add_cmd.am"
    return 0LL;
}

Amalgame_Compiler_TomlValue* Amalgame_Compiler_AddCommand_FindPackageByName(Amalgame_Compiler_TomlValue* pkgArr, code_string target) {
    #line 2325 "./src/add_cmd.am"
    i64 n = Amalgame_Compiler_TomlValue_Count(pkgArr);
    #line 2326 "./src/add_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 2327 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(pkgArr, i);
        #line 2328 "./src/add_cmd.am"
        if (code_string_equals(Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "name")), target)) {
            #line 2329 "./src/add_cmd.am"
            return entry;
        }
    }
    #line 2332 "./src/add_cmd.am"
    return Amalgame_Compiler_TomlValue_new();
}

code_string Amalgame_Compiler_AddCommand_LatestCompatibleTag(Amalgame_Compiler_TomlValue* verArr, code_string pkgName, code_string amcVer) {
    #line 2340 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsArray(verArr)) {
        return "";
    }
    #line 2341 "./src/add_cmd.am"
    i64 n = Amalgame_Compiler_TomlValue_Count(verArr);
    #line 2342 "./src/add_cmd.am"
    code_string found = "";
    #line 2343 "./src/add_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 2344 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(verArr, i);
        #line 2345 "./src/add_cmd.am"
        if (!code_string_equals(Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "package")), pkgName)) {
            continue;
        }
        #line 2346 "./src/add_cmd.am"
        code_string tag = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "tag"));
        #line 2347 "./src/add_cmd.am"
        code_string req = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "required-amalgame"));
        #line 2348 "./src/add_cmd.am"
        if (String_Length(tag) == 0LL) {
            continue;
        }
        #line 2349 "./src/add_cmd.am"
        if ((String_Length(req) == 0LL) || Amalgame_Compiler_PackageRegistry_VersionSatisfies(amcVer, req)) {
            #line 2350 "./src/add_cmd.am"
            found = tag;
        }
    }
    #line 2353 "./src/add_cmd.am"
    return found;
}

code_string Amalgame_Compiler_AddCommand_JsonEscape(code_string s) {
    #line 2362 "./src/add_cmd.am"
    code_string out = String_Replace(s, "\\", "\\\\");
    #line 2363 "./src/add_cmd.am"
    out = String_Replace(out, "\"", "\\\"");
    #line 2364 "./src/add_cmd.am"
    out = String_Replace(out, "\n", "\\n");
    #line 2365 "./src/add_cmd.am"
    out = String_Replace(out, String_FromByte(13LL), "\\r");
    #line 2366 "./src/add_cmd.am"
    out = String_Replace(out, "\t", "\\t");
    #line 2367 "./src/add_cmd.am"
    return out;
}

i64 Amalgame_Compiler_AddCommand_RunInfo(i64 argc, i64 startIdx) {
    #line 2382 "./src/add_cmd.am"
    code_string pkgName = "";
    #line 2383 "./src/add_cmd.am"
    code_bool refresh = 0;
    #line 2384 "./src/add_cmd.am"
    i64 i = startIdx;
    #line 2385 "./src/add_cmd.am"
    while (i < argc) {
        #line 2386 "./src/add_cmd.am"
        code_string a = Args_Get(i);
        #line 2387 "./src/add_cmd.am"
        if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) {
            #line 2388 "./src/add_cmd.am"
            Console_WriteError("Usage: amc package info  [--refresh]");
            #line 2389 "./src/add_cmd.am"
            Console_WriteError("");
            #line 2390 "./src/add_cmd.am"
            Console_WriteError("Show description, url, license, indexed versions and");
            #line 2391 "./src/add_cmd.am"
            Console_WriteError("install status for a single indexed package.");
            #line 2392 "./src/add_cmd.am"
            Console_WriteError("");
            #line 2393 "./src/add_cmd.am"
            Console_WriteError("--refresh  force re-download of the index (cache TTL 30 min).");
            #line 2394 "./src/add_cmd.am"
            return 0LL;
        }
        #line 2396 "./src/add_cmd.am"
        if (code_string_equals(a, "--refresh")) {
            #line 2397 "./src/add_cmd.am"
            refresh = 1;
        } else if (String_Length(pkgName) == 0LL) {
            #line 2399 "./src/add_cmd.am"
            pkgName = a;
        }
        #line 2401 "./src/add_cmd.am"
        i = (i + 1LL);
    }
    #line 2403 "./src/add_cmd.am"
    if (String_Length(pkgName) == 0LL) {
        #line 2404 "./src/add_cmd.am"
        Console_WriteError("amc package info: missing ");
        #line 2405 "./src/add_cmd.am"
        return 2LL;
    }
    #line 2407 "./src/add_cmd.am"
    if (refresh) {
        #line 2408 "./src/add_cmd.am"
        code_string cachePath = Amalgame_Compiler_AddCommand_IndexCachePath();
        #line 2409 "./src/add_cmd.am"
        if (File_Exists(cachePath)) {
            #line 2410 "./src/add_cmd.am"
            code_bool _rm = File_Delete(cachePath);
        }
    }
    #line 2413 "./src/add_cmd.am"
    code_string indexSrc = Amalgame_Compiler_AddCommand_FetchIndex();
    #line 2414 "./src/add_cmd.am"
    if (String_Length(indexSrc) == 0LL) {
        #line 2415 "./src/add_cmd.am"
        Console_WriteError("could not fetch packages-index");
        #line 2416 "./src/add_cmd.am"
        return 1LL;
    }
    #line 2418 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(indexSrc);
    #line 2419 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsNull(doc)) {
        #line 2420 "./src/add_cmd.am"
        Console_WriteError("packages-index parse error");
        #line 2421 "./src/add_cmd.am"
        return 1LL;
    }
    #line 2423 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* pkgArr = Amalgame_Compiler_TomlValue_Get(doc, "package");
    #line 2424 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsArray(pkgArr)) {
        #line 2425 "./src/add_cmd.am"
        Console_WriteError("packages-index has no [[package]] entries");
        #line 2426 "./src/add_cmd.am"
        return 1LL;
    }
    #line 2428 "./src/add_cmd.am"
    code_bool found = 0;
    #line 2429 "./src/add_cmd.am"
    code_string descS = "";
    #line 2430 "./src/add_cmd.am"
    code_string urlS = "";
    #line 2431 "./src/add_cmd.am"
    code_string tierS = "";
    #line 2432 "./src/add_cmd.am"
    code_string licS = "";
    #line 2433 "./src/add_cmd.am"
    code_string catS = "";
    #line 2434 "./src/add_cmd.am"
    code_string maintS = "";
    #line 2435 "./src/add_cmd.am"
    i64 pn = Amalgame_Compiler_TomlValue_Count(pkgArr);
    #line 2436 "./src/add_cmd.am"
    for (i64 j = 0LL; j < pn; j++) {
        #line 2437 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* p = Amalgame_Compiler_TomlValue_At(pkgArr, j);
        #line 2438 "./src/add_cmd.am"
        if (code_string_equals(Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(p, "name")), pkgName)) {
            #line 2439 "./src/add_cmd.am"
            found = 1;
            #line 2440 "./src/add_cmd.am"
            descS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(p, "description"));
            #line 2441 "./src/add_cmd.am"
            urlS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(p, "url"));
            #line 2442 "./src/add_cmd.am"
            tierS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(p, "tier"));
            #line 2443 "./src/add_cmd.am"
            licS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(p, "license"));
            #line 2444 "./src/add_cmd.am"
            catS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(p, "category"));
            #line 2445 "./src/add_cmd.am"
            maintS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(p, "maintainer"));
        }
    }
    #line 2448 "./src/add_cmd.am"
    if (!found) {
        #line 2449 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("amc package info: '", pkgName)), "' not found in packages-index."));
        #line 2450 "./src/add_cmd.am"
        Console_WriteError("       For unindexed packages, use the full URL form:");
        #line 2451 "./src/add_cmd.am"
        Console_WriteError("       `amc package add github.com//@`");
        #line 2452 "./src/add_cmd.am"
        return 1LL;
    }
    #line 2454 "./src/add_cmd.am"
    code_string badge = "  ";
    #line 2455 "./src/add_cmd.am"
    if (code_string_equals(tierS, "official")) {
        badge = "✓ ";
    }
    #line 2456 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat((code_string_concat(badge, pkgName)), " — ")), descS));
    #line 2457 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat("  url:        ", urlS));
    #line 2458 "./src/add_cmd.am"
    if (String_Length(tierS) > 0LL) {
        Console_WriteLine(code_string_concat("  tier:       ", tierS));
    }
    #line 2459 "./src/add_cmd.am"
    if (String_Length(licS) > 0LL) {
        Console_WriteLine(code_string_concat("  license:    ", licS));
    }
    #line 2460 "./src/add_cmd.am"
    if (String_Length(catS) > 0LL) {
        Console_WriteLine(code_string_concat("  category:   ", catS));
    }
    #line 2461 "./src/add_cmd.am"
    if (String_Length(maintS) > 0LL) {
        Console_WriteLine(code_string_concat("  maintainer: ", maintS));
    }
    #line 2465 "./src/add_cmd.am"
    Amalgame_Compiler_PackageRegistry* reg = Amalgame_Compiler_PackageRegistry_Load();
    #line 2466 "./src/add_cmd.am"
    code_bool installed = 0;
    #line 2467 "./src/add_cmd.am"
    code_string installedTag = "";
    #line 2468 "./src/add_cmd.am"
    code_string urlSlug = Amalgame_Compiler_AddCommand_LastUrlSegment(urlS);
    #line 2469 "./src/add_cmd.am"
    i64 np = AmalgameList_count(reg->Packages);
    #line 2470 "./src/add_cmd.am"
    for (i64 k = 0LL; k < np; k++) {
        #line 2471 "./src/add_cmd.am"
        Amalgame_Compiler_LoadedPackage* lp = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(reg->Packages, k);
        #line 2472 "./src/add_cmd.am"
        if (code_string_equals(lp->Name, urlSlug)) {
            #line 2473 "./src/add_cmd.am"
            installed = 1;
            #line 2474 "./src/add_cmd.am"
            installedTag = lp->Tag;
        }
    }
    #line 2477 "./src/add_cmd.am"
    if (installed) {
        #line 2478 "./src/add_cmd.am"
        if (String_Length(installedTag) > 0LL) {
            #line 2479 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat((code_string_concat("  installed:  yes (", installedTag)), ")"));
        } else {
            #line 2481 "./src/add_cmd.am"
            Console_WriteLine("  installed:  yes");
        }
    } else {
        #line 2484 "./src/add_cmd.am"
        Console_WriteLine("  installed:  no");
    }
    #line 2487 "./src/add_cmd.am"
    code_string amcVer = Amalgame_Compiler_PackageRegistry_AmcVersion();
    #line 2488 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* verArr = Amalgame_Compiler_TomlValue_Get(doc, "version");
    #line 2489 "./src/add_cmd.am"
    Amalgame_Compiler_AddCommand_PrintVersionsForPackage(verArr, pkgName, amcVer);
    #line 2490 "./src/add_cmd.am"
    return 0LL;
}

i64 Amalgame_Compiler_AddCommand_RunOutdated(i64 argc, i64 startIdx) {
    #line 2513 "./src/add_cmd.am"
    code_bool refresh = 0;
    #line 2514 "./src/add_cmd.am"
    i64 i = startIdx;
    #line 2515 "./src/add_cmd.am"
    while (i < argc) {
        #line 2516 "./src/add_cmd.am"
        code_string a = Args_Get(i);
        #line 2517 "./src/add_cmd.am"
        if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) {
            #line 2518 "./src/add_cmd.am"
            Console_WriteError("Usage: amc package outdated [--refresh]");
            #line 2519 "./src/add_cmd.am"
            Console_WriteError("");
            #line 2520 "./src/add_cmd.am"
            Console_WriteError("Compare amalgame.lock against the packages-index and list");
            #line 2521 "./src/add_cmd.am"
            Console_WriteError("installed deps that have a newer tag whose required-amalgame");
            #line 2522 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat("is satisfied by your amc ", Amalgame_Compiler_PackageRegistry_AmcVersion())), "."));
            #line 2523 "./src/add_cmd.am"
            Console_WriteError("");
            #line 2524 "./src/add_cmd.am"
            Console_WriteError("--refresh  force re-download of the index (cache TTL 30 min).");
            #line 2525 "./src/add_cmd.am"
            return 0LL;
        }
        #line 2527 "./src/add_cmd.am"
        if (code_string_equals(a, "--refresh")) {
            #line 2528 "./src/add_cmd.am"
            refresh = 1;
        }
        #line 2530 "./src/add_cmd.am"
        i = (i + 1LL);
    }
    #line 2532 "./src/add_cmd.am"
    Amalgame_Compiler_PackageRegistry* reg = Amalgame_Compiler_PackageRegistry_Load();
    #line 2533 "./src/add_cmd.am"
    i64 np = AmalgameList_count(reg->Packages);
    #line 2534 "./src/add_cmd.am"
    if (np == 0LL) {
        #line 2535 "./src/add_cmd.am"
        Console_WriteLine("No packages installed in this project.");
        #line 2536 "./src/add_cmd.am"
        return 0LL;
    }
    #line 2538 "./src/add_cmd.am"
    if (refresh) {
        #line 2539 "./src/add_cmd.am"
        code_string cachePath = Amalgame_Compiler_AddCommand_IndexCachePath();
        #line 2540 "./src/add_cmd.am"
        if (File_Exists(cachePath)) {
            #line 2541 "./src/add_cmd.am"
            code_bool _rm = File_Delete(cachePath);
        }
    }
    #line 2544 "./src/add_cmd.am"
    code_string indexSrc = Amalgame_Compiler_AddCommand_FetchIndex();
    #line 2545 "./src/add_cmd.am"
    if (String_Length(indexSrc) == 0LL) {
        #line 2546 "./src/add_cmd.am"
        Console_WriteError("could not fetch packages-index");
        #line 2547 "./src/add_cmd.am"
        return 1LL;
    }
    #line 2549 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(indexSrc);
    #line 2550 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsNull(doc)) {
        #line 2551 "./src/add_cmd.am"
        Console_WriteError("packages-index parse error");
        #line 2552 "./src/add_cmd.am"
        return 1LL;
    }
    #line 2554 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* pkgArr = Amalgame_Compiler_TomlValue_Get(doc, "package");
    #line 2555 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* verArr = Amalgame_Compiler_TomlValue_Get(doc, "version");
    #line 2556 "./src/add_cmd.am"
    code_string amcVer = Amalgame_Compiler_PackageRegistry_AmcVersion();
    #line 2561 "./src/add_cmd.am"
    AmalgameList* outNames = AmalgameList_new();
    #line 2562 "./src/add_cmd.am"
    AmalgameList* outCurrent = AmalgameList_new();
    #line 2563 "./src/add_cmd.am"
    AmalgameList* outLatest = AmalgameList_new();
    #line 2564 "./src/add_cmd.am"
    AmalgameList* outReq = AmalgameList_new();
    #line 2565 "./src/add_cmd.am"
    i64 unindexed = 0LL;
    #line 2567 "./src/add_cmd.am"
    for (i64 k = 0LL; k < np; k++) {
        #line 2568 "./src/add_cmd.am"
        Amalgame_Compiler_LoadedPackage* lp = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(reg->Packages, k);
        #line 2569 "./src/add_cmd.am"
        code_string slug = lp->Name;
        #line 2571 "./src/add_cmd.am"
        code_string shortname = "";
        #line 2572 "./src/add_cmd.am"
        if (Amalgame_Compiler_TomlValue_IsArray(pkgArr)) {
            #line 2573 "./src/add_cmd.am"
            i64 pn = Amalgame_Compiler_TomlValue_Count(pkgArr);
            #line 2574 "./src/add_cmd.am"
            for (i64 j = 0LL; j < pn; j++) {
                #line 2575 "./src/add_cmd.am"
                Amalgame_Compiler_TomlValue* p = Amalgame_Compiler_TomlValue_At(pkgArr, j);
                #line 2576 "./src/add_cmd.am"
                code_string u = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(p, "url"));
                #line 2577 "./src/add_cmd.am"
                if (code_string_equals(Amalgame_Compiler_AddCommand_LastUrlSegment(u), slug)) {
                    #line 2578 "./src/add_cmd.am"
                    shortname = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(p, "name"));
                }
            }
        }
        #line 2582 "./src/add_cmd.am"
        if (String_Length(shortname) == 0LL) {
            #line 2583 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat((code_string_concat("  skipped (unindexed): ", slug)), " @ ")), lp->Tag));
            #line 2584 "./src/add_cmd.am"
            unindexed = (unindexed + 1LL);
            #line 2585 "./src/add_cmd.am"
            continue;
        }
        #line 2590 "./src/add_cmd.am"
        code_string latestCompat = "";
        #line 2591 "./src/add_cmd.am"
        code_string latestCompatReq = "";
        #line 2592 "./src/add_cmd.am"
        if (Amalgame_Compiler_TomlValue_IsArray(verArr)) {
            #line 2593 "./src/add_cmd.am"
            i64 vn = Amalgame_Compiler_TomlValue_Count(verArr);
            #line 2594 "./src/add_cmd.am"
            for (i64 j = 0LL; j < vn; j++) {
                #line 2595 "./src/add_cmd.am"
                Amalgame_Compiler_TomlValue* v = Amalgame_Compiler_TomlValue_At(verArr, j);
                #line 2596 "./src/add_cmd.am"
                if (!code_string_equals(Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(v, "package")), shortname)) {
                    continue;
                }
                #line 2597 "./src/add_cmd.am"
                code_string tag = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(v, "tag"));
                #line 2598 "./src/add_cmd.am"
                code_string req = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(v, "required-amalgame"));
                #line 2599 "./src/add_cmd.am"
                if (Amalgame_Compiler_PackageRegistry_VersionSatisfies(amcVer, req)) {
                    #line 2600 "./src/add_cmd.am"
                    latestCompat = tag;
                    #line 2601 "./src/add_cmd.am"
                    latestCompatReq = req;
                }
            }
        }
        #line 2605 "./src/add_cmd.am"
        if (String_Length(latestCompat) == 0LL) {
            continue;
        }
        #line 2610 "./src/add_cmd.am"
        if (Amalgame_Compiler_PackageRegistry_CompareCmp(latestCompat, lp->Tag) <= 0LL) {
            continue;
        }
        #line 2611 "./src/add_cmd.am"
        AmalgameList_add(outNames, (void*)(intptr_t)(shortname));
        #line 2612 "./src/add_cmd.am"
        AmalgameList_add(outCurrent, (void*)(intptr_t)(lp->Tag));
        #line 2613 "./src/add_cmd.am"
        AmalgameList_add(outLatest, (void*)(intptr_t)(latestCompat));
        #line 2614 "./src/add_cmd.am"
        AmalgameList_add(outReq, (void*)(intptr_t)(latestCompatReq));
    }
    #line 2617 "./src/add_cmd.am"
    i64 updates = AmalgameList_count(outNames);
    #line 2618 "./src/add_cmd.am"
    if (updates == 0LL) {
        #line 2619 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat("All ", String_FromInt(np))), " installed package(s) are up to date."));
        #line 2620 "./src/add_cmd.am"
        return 0LL;
    }
    #line 2622 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat((code_string_concat(String_FromInt(updates), " of ")), String_FromInt(np))), " installed package(s) have updates available:"));
    #line 2623 "./src/add_cmd.am"
    Console_WriteLine("");
    #line 2625 "./src/add_cmd.am"
    i64 maxName = 0LL;
    #line 2626 "./src/add_cmd.am"
    for (i64 k = 0LL; k < updates; k++) {
        #line 2627 "./src/add_cmd.am"
        i64 n = String_Length((code_string)AmalgameList_get(outNames, k));
        #line 2628 "./src/add_cmd.am"
        if (n > maxName) {
            maxName = n;
        }
    }
    #line 2630 "./src/add_cmd.am"
    for (i64 k = 0LL; k < updates; k++) {
        #line 2631 "./src/add_cmd.am"
        code_string name = (code_string)AmalgameList_get(outNames, k);
        #line 2632 "./src/add_cmd.am"
        code_string pad = "";
        #line 2633 "./src/add_cmd.am"
        i64 padN = maxName - String_Length(name);
        #line 2634 "./src/add_cmd.am"
        i64 p = 0LL;
        #line 2635 "./src/add_cmd.am"
        while (p < padN) {
            #line 2636 "./src/add_cmd.am"
            pad = (code_string_concat(pad, " "));
            #line 2637 "./src/add_cmd.am"
            p = (p + 1LL);
        }
        #line 2639 "./src/add_cmd.am"
        code_string line = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("  ", name)), pad)), "  ")), (code_string)AmalgameList_get(outCurrent, k))), " → ")), (code_string)AmalgameList_get(outLatest, k));
        #line 2640 "./src/add_cmd.am"
        code_string req = (code_string)AmalgameList_get(outReq, k);
        #line 2641 "./src/add_cmd.am"
        if (String_Length(req) > 0LL) {
            #line 2642 "./src/add_cmd.am"
            line = (code_string_concat((code_string_concat((code_string_concat(line, "  (needs amc ")), req)), ")"));
        }
        #line 2644 "./src/add_cmd.am"
        Console_WriteLine(line);
    }
    #line 2646 "./src/add_cmd.am"
    Console_WriteLine("");
    #line 2647 "./src/add_cmd.am"
    Console_WriteLine("Run `amc package update @` to bump.");
    #line 2648 "./src/add_cmd.am"
    return 0LL;
}

i64 Amalgame_Compiler_AddCommand_RunCheck(i64 argc, i64 startIdx) {
    #line 2676 "./src/add_cmd.am"
    code_bool frozen = 0;
    #line 2677 "./src/add_cmd.am"
    i64 i = startIdx;
    #line 2678 "./src/add_cmd.am"
    while (i < argc) {
        #line 2679 "./src/add_cmd.am"
        code_string a = Args_Get(i);
        #line 2680 "./src/add_cmd.am"
        if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) {
            #line 2681 "./src/add_cmd.am"
            Console_WriteError("Usage: amc package check [--frozen]");
            #line 2682 "./src/add_cmd.am"
            Console_WriteError("");
            #line 2683 "./src/add_cmd.am"
            Console_WriteError("Verify amalgame.lock matches the installed package cache.");
            #line 2684 "./src/add_cmd.am"
            Console_WriteError("Reports any [[package]] entry whose cache dir is missing.");
            #line 2685 "./src/add_cmd.am"
            Console_WriteError("");
            #line 2686 "./src/add_cmd.am"
            Console_WriteError("--frozen   exit 1 on mismatch (for CI fail-fast). Without it,");
            #line 2687 "./src/add_cmd.am"
            Console_WriteError("           the verb is informational and always exits 0.");
            #line 2688 "./src/add_cmd.am"
            return 0LL;
        }
        #line 2690 "./src/add_cmd.am"
        if (code_string_equals(a, "--frozen")) {
            #line 2691 "./src/add_cmd.am"
            frozen = 1;
        } else if (String_StartsWith(a, "-")) {
            #line 2693 "./src/add_cmd.am"
            Console_WriteError(code_string_concat("unknown flag: ", a));
            #line 2694 "./src/add_cmd.am"
            return 2LL;
        }
        #line 2696 "./src/add_cmd.am"
        i = (i + 1LL);
    }
    #line 2698 "./src/add_cmd.am"
    code_string lockPath = "amalgame.lock";
    #line 2699 "./src/add_cmd.am"
    if (!File_Exists(lockPath)) {
        #line 2700 "./src/add_cmd.am"
        Console_WriteLine("No amalgame.lock in cwd — nothing to check.");
        #line 2701 "./src/add_cmd.am"
        return 0LL;
    }
    #line 2703 "./src/add_cmd.am"
    code_string lockSrc = File_ReadAll(lockPath);
    #line 2704 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* lockDoc = Amalgame_Compiler_Toml_Parse(lockSrc);
    #line 2705 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsNull(lockDoc)) {
        #line 2706 "./src/add_cmd.am"
        Console_WriteError("amalgame.lock parse error");
        #line 2707 "./src/add_cmd.am"
        return 1LL;
    }
    #line 2709 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* pkgs = Amalgame_Compiler_TomlValue_Get(lockDoc, "package");
    #line 2710 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsArray(pkgs)) {
        #line 2711 "./src/add_cmd.am"
        Console_WriteLine("amalgame.lock has no [[package]] entries — nothing to check.");
        #line 2712 "./src/add_cmd.am"
        return 0LL;
    }
    #line 2714 "./src/add_cmd.am"
    code_string cacheRoot = Amalgame_Compiler_AddCommand_CacheRoot();
    #line 2715 "./src/add_cmd.am"
    i64 n = Amalgame_Compiler_TomlValue_Count(pkgs);
    #line 2716 "./src/add_cmd.am"
    i64 ok = 0LL;
    #line 2717 "./src/add_cmd.am"
    i64 missing = 0LL;
    #line 2718 "./src/add_cmd.am"
    for (i64 k = 0LL; k < n; k++) {
        #line 2719 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(pkgs, k);
        #line 2720 "./src/add_cmd.am"
        code_string gitS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "git"));
        #line 2721 "./src/add_cmd.am"
        code_string tagS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "tag"));
        #line 2722 "./src/add_cmd.am"
        code_string revS = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "rev"));
        #line 2723 "./src/add_cmd.am"
        if ((String_Length(gitS) == 0LL) || (String_Length(tagS) == 0LL)) {
            continue;
        }
        #line 2724 "./src/add_cmd.am"
        if (String_Length(revS) < 8LL) {
            continue;
        }
        #line 2725 "./src/add_cmd.am"
        code_string shortSha = String_Substring(revS, 0LL, 8LL);
        #line 2726 "./src/add_cmd.am"
        code_string pkgDir = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(cacheRoot, "/")), gitS)), "/")), tagS)), "_")), shortSha);
        #line 2727 "./src/add_cmd.am"
        code_string manifest = code_string_concat(pkgDir, "/amalgame.toml");
        #line 2728 "./src/add_cmd.am"
        if (File_Exists(manifest)) {
            #line 2729 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("  ✓ ", gitS)), " @ ")), tagS)), " (sha ")), shortSha)), ")"));
            #line 2730 "./src/add_cmd.am"
            ok = (ok + 1LL);
        } else {
            #line 2732 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat("  ✗ ", gitS)), " @ ")), tagS)), " — cache dir missing"));
            #line 2733 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat((code_string_concat("       expected: ", pkgDir)), "/"));
            #line 2734 "./src/add_cmd.am"
            missing = (missing + 1LL);
        }
    }
    #line 2737 "./src/add_cmd.am"
    Console_WriteLine("");
    #line 2738 "./src/add_cmd.am"
    if (missing == 0LL) {
        #line 2739 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat((code_string_concat((code_string_concat(String_FromInt(ok), " of ")), String_FromInt(ok))), " package(s) match amalgame.lock."));
        #line 2740 "./src/add_cmd.am"
        return 0LL;
    }
    #line 2742 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat((code_string_concat(String_FromInt(missing), " of ")), String_FromInt(ok + missing))), " installed package(s) failed integrity check."));
    #line 2743 "./src/add_cmd.am"
    Console_WriteLine("Run `amc package add @` (or `amc test` for auto-repair) to re-install.");
    #line 2744 "./src/add_cmd.am"
    if (frozen) {
        #line 2745 "./src/add_cmd.am"
        return 1LL;
    }
    #line 2747 "./src/add_cmd.am"
    return 0LL;
}

i64 Amalgame_Compiler_AddCommand_RunNotice(i64 argc, i64 startIdx) {
    #line 2764 "./src/add_cmd.am"
    i64 i = startIdx;
    #line 2765 "./src/add_cmd.am"
    while (i < argc) {
        #line 2766 "./src/add_cmd.am"
        code_string a = Args_Get(i);
        #line 2767 "./src/add_cmd.am"
        if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) {
            #line 2768 "./src/add_cmd.am"
            Console_WriteError("Usage: amc package notice");
            #line 2769 "./src/add_cmd.am"
            Console_WriteError("");
            #line 2770 "./src/add_cmd.am"
            Console_WriteError("Aggregate licence + authorship of every package referenced");
            #line 2771 "./src/add_cmd.am"
            Console_WriteError("from amalgame.lock. Output is plain text on stdout, ready to");
            #line 2772 "./src/add_cmd.am"
            Console_WriteError("redirect into NOTICE_DEPS.md for downstream redistribution.");
            #line 2773 "./src/add_cmd.am"
            Console_WriteError("");
            #line 2774 "./src/add_cmd.am"
            Console_WriteError("For each package, the matching upstream LICENSE / NOTICE files");
            #line 2775 "./src/add_cmd.am"
            Console_WriteError("at / contain the full licence text — this verb only");
            #line 2776 "./src/add_cmd.am"
            Console_WriteError("aggregates the metadata, it does not embed the licence bodies.");
            #line 2777 "./src/add_cmd.am"
            return 0LL;
        }
        #line 2779 "./src/add_cmd.am"
        if (String_StartsWith(a, "-")) {
            #line 2780 "./src/add_cmd.am"
            Console_WriteError(code_string_concat("unknown flag: ", a));
            #line 2781 "./src/add_cmd.am"
            return 2LL;
        }
        #line 2783 "./src/add_cmd.am"
        i = (i + 1LL);
    }
    #line 2785 "./src/add_cmd.am"
    Amalgame_Compiler_PackageRegistry* reg = Amalgame_Compiler_PackageRegistry_Load();
    #line 2786 "./src/add_cmd.am"
    i64 np = AmalgameList_count(reg->Packages);
    #line 2787 "./src/add_cmd.am"
    if (np == 0LL) {
        #line 2788 "./src/add_cmd.am"
        Console_WriteError("No packages installed in this project.");
        #line 2789 "./src/add_cmd.am"
        return 0LL;
    }
    #line 2791 "./src/add_cmd.am"
    Console_WriteLine("# Third-party Amalgame packages referenced by this project");
    #line 2792 "./src/add_cmd.am"
    Console_WriteLine("#");
    #line 2793 "./src/add_cmd.am"
    Console_WriteLine("# Generated by `amc package notice` from amalgame.lock + each");
    #line 2794 "./src/add_cmd.am"
    Console_WriteLine("# package's amalgame.toml. For the full licence text, consult");
    #line 2795 "./src/add_cmd.am"
    Console_WriteLine("# the upstream LICENSE / NOTICE files in each repository.");
    #line 2796 "./src/add_cmd.am"
    Console_WriteLine("");
    #line 2798 "./src/add_cmd.am"
    AmalgameList* licenses = AmalgameList_new();
    #line 2799 "./src/add_cmd.am"
    for (i64 k = 0LL; k < np; k++) {
        #line 2800 "./src/add_cmd.am"
        Amalgame_Compiler_LoadedPackage* lp = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(reg->Packages, k);
        #line 2801 "./src/add_cmd.am"
        code_string manifestPath = code_string_concat(lp->PkgDir, "/amalgame.toml");
        #line 2802 "./src/add_cmd.am"
        if (!File_Exists(manifestPath)) {
            #line 2803 "./src/add_cmd.am"
            Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("warning: missing manifest for ", lp->Name)), " — run `amc package add ")), lp->Name)), "@")), lp->Tag)), "` to repair."));
            #line 2804 "./src/add_cmd.am"
            continue;
        }
        #line 2806 "./src/add_cmd.am"
        code_string src = File_ReadAll(manifestPath);
        #line 2807 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(src);
        #line 2808 "./src/add_cmd.am"
        if (Amalgame_Compiler_TomlValue_IsNull(doc)) {
            #line 2809 "./src/add_cmd.am"
            Console_WriteError(code_string_concat("warning: unparseable manifest at ", manifestPath));
            #line 2810 "./src/add_cmd.am"
            continue;
        }
        #line 2812 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* pkgTable = Amalgame_Compiler_TomlValue_Get(doc, "package");
        #line 2813 "./src/add_cmd.am"
        if (!Amalgame_Compiler_TomlValue_IsTable(pkgTable)) {
            continue;
        }
        #line 2814 "./src/add_cmd.am"
        code_string manifestName = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(pkgTable, "name"));
        #line 2815 "./src/add_cmd.am"
        code_string manifestVersion = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(pkgTable, "version"));
        #line 2816 "./src/add_cmd.am"
        code_string manifestLicense = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(pkgTable, "license"));
        #line 2817 "./src/add_cmd.am"
        code_string manifestDesc = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(pkgTable, "description"));
        #line 2821 "./src/add_cmd.am"
        code_string authorsJoined = "";
        #line 2822 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* authorsArr = Amalgame_Compiler_TomlValue_Get(pkgTable, "authors");
        #line 2823 "./src/add_cmd.am"
        if (Amalgame_Compiler_TomlValue_IsArray(authorsArr)) {
            #line 2824 "./src/add_cmd.am"
            i64 an = Amalgame_Compiler_TomlValue_Count(authorsArr);
            #line 2825 "./src/add_cmd.am"
            for (i64 j = 0LL; j < an; j++) {
                #line 2826 "./src/add_cmd.am"
                code_string nameEntry = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_At(authorsArr, j));
                #line 2827 "./src/add_cmd.am"
                if (String_Length(nameEntry) == 0LL) {
                    continue;
                }
                #line 2828 "./src/add_cmd.am"
                if (String_Length(authorsJoined) > 0LL) {
                    #line 2829 "./src/add_cmd.am"
                    authorsJoined = (code_string_concat(authorsJoined, " · "));
                }
                #line 2831 "./src/add_cmd.am"
                authorsJoined = (code_string_concat(authorsJoined, nameEntry));
            }
        }
        #line 2837 "./src/add_cmd.am"
        code_string headline = code_string_concat((code_string_concat((code_string_concat("## ", manifestName)), " ")), lp->Tag);
        #line 2838 "./src/add_cmd.am"
        if ((String_Length(manifestVersion) > 0LL) && (!code_string_equals(manifestVersion, String_Substring(lp->Tag, 1LL, String_Length(lp->Tag) - 1LL)))) {
            #line 2841 "./src/add_cmd.am"
            headline = (code_string_concat((code_string_concat((code_string_concat(headline, " (manifest version ")), manifestVersion)), ")"));
        }
        #line 2843 "./src/add_cmd.am"
        Console_WriteLine(headline);
        #line 2844 "./src/add_cmd.am"
        Console_WriteLine(code_string_concat("Source:    ", lp->Name));
        #line 2845 "./src/add_cmd.am"
        if (String_Length(manifestLicense) > 0LL) {
            #line 2846 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat("Licence:   ", manifestLicense));
            #line 2848 "./src/add_cmd.am"
            code_bool seen = 0;
            #line 2849 "./src/add_cmd.am"
            i64 ln = AmalgameList_count(licenses);
            #line 2850 "./src/add_cmd.am"
            for (i64 j = 0LL; j < ln; j++) {
                #line 2851 "./src/add_cmd.am"
                if (code_string_equals((code_string)AmalgameList_get(licenses, j), manifestLicense)) {
                    seen = 1;
                }
            }
            #line 2853 "./src/add_cmd.am"
            if (!seen) {
                AmalgameList_add(licenses, (void*)(intptr_t)(manifestLicense));
            }
        } else {
            #line 2855 "./src/add_cmd.am"
            Console_WriteLine("Licence:   (not declared — review upstream)");
        }
        #line 2857 "./src/add_cmd.am"
        if (String_Length(authorsJoined) > 0LL) {
            #line 2858 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat("Authors:   ", authorsJoined));
        }
        #line 2860 "./src/add_cmd.am"
        if (String_Length(manifestDesc) > 0LL) {
            #line 2861 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat("Summary:   ", manifestDesc));
        }
        #line 2863 "./src/add_cmd.am"
        Console_WriteLine("");
    }
    #line 2867 "./src/add_cmd.am"
    i64 lc = AmalgameList_count(licenses);
    #line 2868 "./src/add_cmd.am"
    code_string summary = code_string_concat((code_string_concat("# ", String_FromInt(np))), " package(s)");
    #line 2869 "./src/add_cmd.am"
    if (lc == 1LL) {
        #line 2870 "./src/add_cmd.am"
        summary = (code_string_concat((code_string_concat(summary, "; 1 distinct licence: ")), (code_string)AmalgameList_get(licenses, 0LL)));
    } else if (lc > 1LL) {
        #line 2872 "./src/add_cmd.am"
        summary = (code_string_concat((code_string_concat((code_string_concat(summary, "; ")), String_FromInt(lc))), " distinct licences: "));
        #line 2873 "./src/add_cmd.am"
        for (i64 j = 0LL; j < lc; j++) {
            #line 2874 "./src/add_cmd.am"
            if (j > 0LL) {
                summary = (code_string_concat(summary, ", "));
            }
            #line 2875 "./src/add_cmd.am"
            summary = (code_string_concat(summary, (code_string)AmalgameList_get(licenses, j)));
        }
    }
    #line 2878 "./src/add_cmd.am"
    Console_WriteLine(summary);
    #line 2879 "./src/add_cmd.am"
    return 0LL;
}

code_string Amalgame_Compiler_AddCommand_LastUrlSegment(code_string url) {
    #line 2888 "./src/add_cmd.am"
    i64 n = String_Length(url);
    #line 2889 "./src/add_cmd.am"
    if (n == 0LL) {
        return "";
    }
    #line 2890 "./src/add_cmd.am"
    i64 idx = String_LastIndexOf(url, "/");
    #line 2891 "./src/add_cmd.am"
    if (idx < 0LL) {
        return url;
    }
    #line 2892 "./src/add_cmd.am"
    return String_Substring(url, idx + 1LL, (n - idx) - 1LL);
}

code_string Amalgame_Compiler_AddCommand_ResolveLatestCompatible(code_string shortname) {
    #line 2902 "./src/add_cmd.am"
    code_string indexSrc = Amalgame_Compiler_AddCommand_FetchIndex();
    #line 2903 "./src/add_cmd.am"
    if (String_Length(indexSrc) == 0LL) {
        #line 2904 "./src/add_cmd.am"
        Console_WriteError("could not fetch packages-index — auto-resolve needs the index.");
        #line 2905 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("       Specify an explicit @ or run `amc package search ", shortname)), " --refresh`."));
        #line 2906 "./src/add_cmd.am"
        return "";
    }
    #line 2908 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(indexSrc);
    #line 2909 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsNull(doc)) {
        #line 2910 "./src/add_cmd.am"
        Console_WriteError("packages-index parse error");
        #line 2911 "./src/add_cmd.am"
        return "";
    }
    #line 2913 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* verArr = Amalgame_Compiler_TomlValue_Get(doc, "version");
    #line 2914 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsArray(verArr)) {
        #line 2915 "./src/add_cmd.am"
        Console_WriteError("packages-index has no [[version]] entries — auto-resolve impossible.");
        #line 2916 "./src/add_cmd.am"
        Console_WriteError("       Specify an explicit @ or ask the package maintainer to update the index.");
        #line 2917 "./src/add_cmd.am"
        return "";
    }
    #line 2919 "./src/add_cmd.am"
    code_string amcVer = Amalgame_Compiler_PackageRegistry_AmcVersion();
    #line 2920 "./src/add_cmd.am"
    i64 n = Amalgame_Compiler_TomlValue_Count(verArr);
    #line 2924 "./src/add_cmd.am"
    code_string latestCompat = "";
    #line 2925 "./src/add_cmd.am"
    code_bool anyForShortname = 0;
    #line 2926 "./src/add_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 2927 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(verArr, i);
        #line 2928 "./src/add_cmd.am"
        if (!code_string_equals(Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "package")), shortname)) {
            continue;
        }
        #line 2929 "./src/add_cmd.am"
        anyForShortname = 1;
        #line 2930 "./src/add_cmd.am"
        code_string tag = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "tag"));
        #line 2931 "./src/add_cmd.am"
        code_string req = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "required-amalgame"));
        #line 2932 "./src/add_cmd.am"
        if (Amalgame_Compiler_PackageRegistry_VersionSatisfies(amcVer, req)) {
            #line 2933 "./src/add_cmd.am"
            latestCompat = tag;
        }
    }
    #line 2936 "./src/add_cmd.am"
    if (!anyForShortname) {
        #line 2937 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("'", shortname)), "' not found in packages-index."));
        #line 2938 "./src/add_cmd.am"
        Console_WriteError("       For unindexed packages, use the full URL form:");
        #line 2939 "./src/add_cmd.am"
        Console_WriteError("       `amc package add github.com//@`");
        #line 2940 "./src/add_cmd.am"
        return "";
    }
    #line 2942 "./src/add_cmd.am"
    if (String_Length(latestCompat) == 0LL) {
        #line 2943 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat("No version of '", shortname)), "' is compatible with your amc ")), amcVer)), "."));
        #line 2944 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("       Run `amc package versions ", shortname)), "` to see all tags + their constraints."));
        #line 2945 "./src/add_cmd.am"
        return "";
    }
    #line 2947 "./src/add_cmd.am"
    return latestCompat;
}

code_string Amalgame_Compiler_AddCommand_ResolveShortname(code_string spec) {
    #line 2956 "./src/add_cmd.am"
    i64 atIdx = String_LastIndexOf(spec, "@");
    #line 2957 "./src/add_cmd.am"
    if (atIdx <= 0LL) {
        return spec;
    }
    #line 2958 "./src/add_cmd.am"
    i64 n = String_Length(spec);
    #line 2959 "./src/add_cmd.am"
    code_string lhs = String_Substring(spec, 0LL, atIdx);
    #line 2960 "./src/add_cmd.am"
    code_string rhs = String_Substring(spec, atIdx + 1LL, (n - atIdx) - 1LL);
    #line 2961 "./src/add_cmd.am"
    if (!Amalgame_Compiler_AddCommand_IsShortname(lhs)) {
        return spec;
    }
    #line 2963 "./src/add_cmd.am"
    Console_WriteLine(code_string_concat((code_string_concat("Resolving shortname '", lhs)), "' via amalgame-lang/packages-index..."));
    #line 2964 "./src/add_cmd.am"
    code_string indexSrc = Amalgame_Compiler_AddCommand_FetchIndex();
    #line 2965 "./src/add_cmd.am"
    if (String_Length(indexSrc) == 0LL) {
        #line 2966 "./src/add_cmd.am"
        Console_WriteError(code_string_concat((code_string_concat("warning: could not fetch packages-index — passing '", lhs)), "' through as URL"));
        #line 2967 "./src/add_cmd.am"
        return spec;
    }
    #line 2969 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(indexSrc);
    #line 2970 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsNull(doc)) {
        #line 2971 "./src/add_cmd.am"
        Console_WriteError("warning: packages-index could not be parsed — passing through");
        #line 2972 "./src/add_cmd.am"
        return spec;
    }
    #line 2974 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* pkgArr = Amalgame_Compiler_TomlValue_Get(doc, "package");
    #line 2975 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsArray(pkgArr)) {
        return spec;
    }
    #line 2976 "./src/add_cmd.am"
    i64 pkgN = Amalgame_Compiler_TomlValue_Count(pkgArr);
    #line 2977 "./src/add_cmd.am"
    for (i64 i = 0LL; i < pkgN; i++) {
        #line 2978 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(pkgArr, i);
        #line 2979 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entryName = Amalgame_Compiler_TomlValue_Get(entry, "name");
        #line 2980 "./src/add_cmd.am"
        if (code_string_equals(Amalgame_Compiler_TomlValue_AsString(entryName), lhs)) {
            #line 2981 "./src/add_cmd.am"
            Amalgame_Compiler_TomlValue* entryUrl = Amalgame_Compiler_TomlValue_Get(entry, "url");
            #line 2982 "./src/add_cmd.am"
            Amalgame_Compiler_TomlValue* entryTier = Amalgame_Compiler_TomlValue_Get(entry, "tier");
            #line 2983 "./src/add_cmd.am"
            code_string urlStr = Amalgame_Compiler_TomlValue_AsString(entryUrl);
            #line 2984 "./src/add_cmd.am"
            code_string tierStr = Amalgame_Compiler_TomlValue_AsString(entryTier);
            #line 2985 "./src/add_cmd.am"
            Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat("  → ", urlStr)), " (")), tierStr)), ")"));
            #line 2986 "./src/add_cmd.am"
            return code_string_concat((code_string_concat(urlStr, "@")), rhs);
        }
    }
    #line 2989 "./src/add_cmd.am"
    Console_WriteError(code_string_concat((code_string_concat("'", lhs)), "' not found in packages-index — passing through as URL"));
    #line 2990 "./src/add_cmd.am"
    return spec;
}

AmalgameList* Amalgame_Compiler_AddCommand_AllCachedRuntimeDirs() {
    #line 2998 "./src/add_cmd.am"
    AmalgameList* out = AmalgameList_new();
    #line 2999 "./src/add_cmd.am"
    code_string cacheRoot = Amalgame_Compiler_AddCommand_CacheRoot();
    #line 3000 "./src/add_cmd.am"
    code_string orgRoot = code_string_concat(cacheRoot, "/github.com/amalgame-lang");
    #line 3001 "./src/add_cmd.am"
    if (!File_Exists(orgRoot)) {
        return out;
    }
    #line 3003 "./src/add_cmd.am"
    AmalgameList* lines = String_Split(Amalgame_Compiler_AddCommand_ListDir(orgRoot), "\n");
    #line 3004 "./src/add_cmd.am"
    i64 n = AmalgameList_count(lines);
    #line 3005 "./src/add_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 3006 "./src/add_cmd.am"
        code_string repo = String_Trim((code_string)AmalgameList_get(lines, i));
        #line 3007 "./src/add_cmd.am"
        if (String_Length(repo) == 0LL) {
            continue;
        }
        #line 3008 "./src/add_cmd.am"
        code_string dir = Amalgame_Compiler_AddCommand_LatestCacheRuntimeDir(repo);
        #line 3009 "./src/add_cmd.am"
        if (String_Length(dir) > 0LL) {
            #line 3010 "./src/add_cmd.am"
            AmalgameList_add(out, (void*)(intptr_t)(dir));
        }
    }
    #line 3013 "./src/add_cmd.am"
    return out;
}

code_string Amalgame_Compiler_AddCommand_LatestCacheRuntimeDir(code_string depKey) {
    #line 3035 "./src/add_cmd.am"
    if (!String_StartsWith(depKey, "amalgame-")) {
        #line 3036 "./src/add_cmd.am"
        return "";
    }
    #line 3038 "./src/add_cmd.am"
    code_string cacheRoot = Amalgame_Compiler_AddCommand_CacheRoot();
    #line 3039 "./src/add_cmd.am"
    code_string pkgCacheParent = code_string_concat((code_string_concat(cacheRoot, "/github.com/amalgame-lang/")), depKey);
    #line 3040 "./src/add_cmd.am"
    if (!File_Exists(pkgCacheParent)) {
        #line 3041 "./src/add_cmd.am"
        return "";
    }
    #line 3048 "./src/add_cmd.am"
    AmalgameList* entries = String_Split(Amalgame_Compiler_AddCommand_ListDir(pkgCacheParent), "\n");
    #line 3049 "./src/add_cmd.am"
    code_string entry = "";
    #line 3050 "./src/add_cmd.am"
    code_string bestTag = "";
    #line 3051 "./src/add_cmd.am"
    i64 ne = AmalgameList_count(entries);
    #line 3052 "./src/add_cmd.am"
    for (i64 i = 0LL; i < ne; i++) {
        #line 3053 "./src/add_cmd.am"
        code_string cand = String_Trim((code_string)AmalgameList_get(entries, i));
        #line 3054 "./src/add_cmd.am"
        if (String_Length(cand) == 0LL) {
            continue;
        }
        #line 3055 "./src/add_cmd.am"
        AmalgameList* candParts = String_Split(cand, "_");
        #line 3056 "./src/add_cmd.am"
        code_string candTag = (code_string)AmalgameList_get(candParts, 0LL);
        #line 3057 "./src/add_cmd.am"
        if ((String_Length(entry) == 0LL) || (Amalgame_Compiler_PackageRegistry_CompareCmp(candTag, bestTag) > 0LL)) {
            #line 3058 "./src/add_cmd.am"
            entry = cand;
            #line 3059 "./src/add_cmd.am"
            bestTag = candTag;
        }
    }
    #line 3062 "./src/add_cmd.am"
    if (String_Length(entry) == 0LL) {
        return "";
    }
    #line 3063 "./src/add_cmd.am"
    code_string runtimeDir = code_string_concat((code_string_concat((code_string_concat(pkgCacheParent, "/")), entry)), "/runtime");
    #line 3064 "./src/add_cmd.am"
    if (!File_Exists(runtimeDir)) {
        return "";
    }
    #line 3065 "./src/add_cmd.am"
    return runtimeDir;
}

code_string Amalgame_Compiler_AddCommand_ShortnameFromDepKey(code_string depKey) {
    #line 3085 "./src/add_cmd.am"
    if (!String_StartsWith(depKey, "amalgame-")) {
        #line 3086 "./src/add_cmd.am"
        return depKey;
    }
    #line 3088 "./src/add_cmd.am"
    code_string indexSrc = Amalgame_Compiler_AddCommand_FetchIndex();
    #line 3089 "./src/add_cmd.am"
    if (String_Length(indexSrc) == 0LL) {
        #line 3090 "./src/add_cmd.am"
        return Amalgame_Compiler_AddCommand_DepNameFromSlug(depKey);
    }
    #line 3092 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* doc = Amalgame_Compiler_Toml_Parse(indexSrc);
    #line 3093 "./src/add_cmd.am"
    if (Amalgame_Compiler_TomlValue_IsNull(doc)) {
        #line 3094 "./src/add_cmd.am"
        return Amalgame_Compiler_AddCommand_DepNameFromSlug(depKey);
    }
    #line 3096 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* pkgArr = Amalgame_Compiler_TomlValue_Get(doc, "package");
    #line 3097 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsArray(pkgArr)) {
        #line 3098 "./src/add_cmd.am"
        return Amalgame_Compiler_AddCommand_DepNameFromSlug(depKey);
    }
    #line 3100 "./src/add_cmd.am"
    code_string urlSuffix = code_string_concat("/", depKey);
    #line 3101 "./src/add_cmd.am"
    i64 n = Amalgame_Compiler_TomlValue_Count(pkgArr);
    #line 3102 "./src/add_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 3103 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_At(pkgArr, i);
        #line 3104 "./src/add_cmd.am"
        code_string url = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "url"));
        #line 3105 "./src/add_cmd.am"
        if (String_EndsWith(url, urlSuffix)) {
            #line 3106 "./src/add_cmd.am"
            code_string name = Amalgame_Compiler_TomlValue_AsString(Amalgame_Compiler_TomlValue_Get(entry, "name"));
            #line 3107 "./src/add_cmd.am"
            if (String_Length(name) > 0LL) {
                #line 3108 "./src/add_cmd.am"
                return name;
            }
        }
    }
    #line 3114 "./src/add_cmd.am"
    return Amalgame_Compiler_AddCommand_DepNameFromSlug(depKey);
}

code_string Amalgame_Compiler_AddCommand_FindExistingForTag(code_string baseDir, code_string tag) {
    #line 3120 "./src/add_cmd.am"
    code_string prefix = code_string_concat(tag, "_");
    #line 3123 "./src/add_cmd.am"
    AmalgameList* lines = String_Split(Amalgame_Compiler_AddCommand_ListDir(baseDir), "\n");
    #line 3124 "./src/add_cmd.am"
    i64 n = AmalgameList_count(lines);
    #line 3125 "./src/add_cmd.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 3126 "./src/add_cmd.am"
        code_string line = (code_string)AmalgameList_get(lines, i);
        #line 3127 "./src/add_cmd.am"
        if (String_StartsWith(line, prefix)) {
            #line 3128 "./src/add_cmd.am"
            return code_string_concat((code_string_concat(baseDir, "/")), line);
        }
    }
    #line 3131 "./src/add_cmd.am"
    return "";
}

code_string Amalgame_Compiler_AddCommand_ExtractRevFromDirName(code_string dir) {
    #line 3135 "./src/add_cmd.am"
    i64 slash = String_LastIndexOf(dir, "/");
    #line 3136 "./src/add_cmd.am"
    code_string leaf = String_Substring(dir, slash + 1LL, (String_Length(dir) - slash) - 1LL);
    #line 3137 "./src/add_cmd.am"
    i64 under = String_LastIndexOf(leaf, "_");
    #line 3138 "./src/add_cmd.am"
    if (under < 0LL) {
        return "";
    }
    #line 3139 "./src/add_cmd.am"
    return String_Substring(leaf, under + 1LL, (String_Length(leaf) - under) - 1LL);
}

code_bool Amalgame_Compiler_AddCommand_UpdateProjectManifest(code_string depName, code_string url, code_string tag) {
    #line 3148 "./src/add_cmd.am"
    code_string path = "amalgame.toml";
    #line 3149 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* doc = NULL;
    #line 3150 "./src/add_cmd.am"
    if (File_Exists(path)) {
        #line 3151 "./src/add_cmd.am"
        code_string src = File_ReadAll(path);
        #line 3152 "./src/add_cmd.am"
        doc = Amalgame_Compiler_Toml_Parse(src);
        #line 3153 "./src/add_cmd.am"
        if (Amalgame_Compiler_TomlValue_IsNull(doc)) {
            #line 3154 "./src/add_cmd.am"
            Console_WriteError("could not parse existing amalgame.toml");
            #line 3155 "./src/add_cmd.am"
            return 0;
        }
    } else {
        #line 3158 "./src/add_cmd.am"
        doc = Amalgame_Compiler_TomlValue_new();
        #line 3159 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue_BecomeTable(doc);
    }
    #line 3163 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* deps = Amalgame_Compiler_TomlValue_Get(doc, "dependencies");
    #line 3164 "./src/add_cmd.am"
    if (!Amalgame_Compiler_TomlValue_IsTable(deps)) {
        #line 3165 "./src/add_cmd.am"
        deps = Amalgame_Compiler_TomlValue_new();
        #line 3166 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue_BecomeTable(deps);
        #line 3167 "./src/add_cmd.am"
        Amalgame_Compiler_TomlValue_SetEntry(doc, "dependencies", deps);
    }
    #line 3171 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* entry = Amalgame_Compiler_TomlValue_new();
    #line 3172 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue_BecomeTable(entry);
    #line 3173 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* gitVal = Amalgame_Compiler_TomlValue_new();
    #line 3174 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue_SetString(gitVal, url);
    #line 3175 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue* tagVal = Amalgame_Compiler_TomlValue_new();
    #line 3176 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue_SetString(tagVal, tag);
    #line 3177 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue_SetEntry(entry, "git", gitVal);
    #line 3178 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue_SetEntry(entry, "tag", tagVal);
    #line 3179 "./src/add_cmd.am"
    Amalgame_Compiler_TomlValue_SetEntry(deps, depName, entry);
    #line 3181 "./src/add_cmd.am"
    code_string out = Amalgame_Compiler_Toml_Serialize(doc);
    #line 3182 "./src/add_cmd.am"
    code_bool ok = File_WriteAll(path, out);
    #line 3183 "./src/add_cmd.am"
    return ok;
}

code_bool Amalgame_Compiler_AddCommand_UpdateLockFile(code_string depName, code_string url, code_string tag, code_string rev) {
    #line 3190 "./src/add_cmd.am"
    code_string path = "amalgame.lock";
    #line 3195 "./src/add_cmd.am"
    code_string out = "# amalgame.lock — auto-generated, commit me\n";
    #line 3196 "./src/add_cmd.am"
    out = (code_string_concat(out, "\n"));
    #line 3197 "./src/add_cmd.am"
    out = (code_string_concat(out, "[[package]]\n"));
    #line 3198 "./src/add_cmd.am"
    out = (code_string_concat((code_string_concat((code_string_concat(out, "name = \"")), depName)), "\"\n"));
    #line 3199 "./src/add_cmd.am"
    out = (code_string_concat((code_string_concat((code_string_concat(out, "git  = \"")), url)), "\"\n"));
    #line 3200 "./src/add_cmd.am"
    out = (code_string_concat((code_string_concat((code_string_concat(out, "tag  = \"")), tag)), "\"\n"));
    #line 3201 "./src/add_cmd.am"
    out = (code_string_concat((code_string_concat((code_string_concat(out, "rev  = \"")), rev)), "\"\n"));
    #line 3202 "./src/add_cmd.am"
    code_bool ok = File_WriteAll(path, out);
    #line 3203 "./src/add_cmd.am"
    return ok;
}

struct _Amalgame_Compiler_MonoTimer {
    i64 startNs;
};

code_string Amalgame_Compiler_MonoTimer_Reset(Amalgame_Compiler_MonoTimer* self);
static i64 Amalgame_Compiler_MonoTimer_NowNs();
static code_string Amalgame_Compiler_MonoTimer_Format(i64 nanos);
static code_string Amalgame_Compiler_MonoTimer_Pad3(i64 n);

Amalgame_Compiler_MonoTimer* Amalgame_Compiler_MonoTimer_new() {
    Amalgame_Compiler_MonoTimer* self = (Amalgame_Compiler_MonoTimer*) GC_MALLOC(sizeof(Amalgame_Compiler_MonoTimer));
    #line 38 "./src/main.am"
    self->startNs = Amalgame_Compiler_MonoTimer_NowNs();
    return self;
}

code_string Amalgame_Compiler_MonoTimer_Reset(Amalgame_Compiler_MonoTimer* self) {
    #line 45 "./src/main.am"
    i64 now = Amalgame_Compiler_MonoTimer_NowNs();
    #line 46 "./src/main.am"
    i64 diff = now - self->startNs;
    #line 47 "./src/main.am"
    self->startNs = now;
    #line 48 "./src/main.am"
    return Amalgame_Compiler_MonoTimer_Format(diff);
}

static i64 Amalgame_Compiler_MonoTimer_NowNs() {
    #line 52 "./src/main.am"
    { /* inline-C */
        
                #ifdef _WIN32
                    LARGE_INTEGER counter, freq;
                    QueryPerformanceFrequency(&freq);
                    QueryPerformanceCounter(&counter);
                    return (i64)((counter.QuadPart * 1000000000LL) / freq.QuadPart);
                #else
                    struct timespec ts;
                    if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) return 0;
                    return (i64)((int64_t) ts.tv_sec * 1000000000LL + (int64_t) ts.tv_nsec);
                #endif
                
    }
}

static code_string Amalgame_Compiler_MonoTimer_Format(i64 nanos) {
    #line 67 "./src/main.am"
    if (nanos < 1000LL) {
        #line 68 "./src/main.am"
        return code_string_concat(String_FromInt(nanos), "ns");
    }
    #line 70 "./src/main.am"
    if (nanos < 1000000LL) {
        #line 71 "./src/main.am"
        return code_string_concat(String_FromInt(nanos / 1000LL), "us");
    }
    #line 73 "./src/main.am"
    if (nanos < 1000000000LL) {
        #line 74 "./src/main.am"
        return code_string_concat(String_FromInt(nanos / 1000000LL), "ms");
    }
    #line 76 "./src/main.am"
    i64 s = nanos / 1000000000LL;
    #line 77 "./src/main.am"
    i64 ms = (nanos % 1000000000LL) / 1000000LL;
    #line 78 "./src/main.am"
    return code_string_concat((code_string_concat((code_string_concat(String_FromInt(s), ".")), Amalgame_Compiler_MonoTimer_Pad3(ms))), "s");
}

static code_string Amalgame_Compiler_MonoTimer_Pad3(i64 n) {
    #line 82 "./src/main.am"
    if (n < 10LL) {
        return code_string_concat("00", String_FromInt(n));
    }
    #line 83 "./src/main.am"
    if (n < 100LL) {
        return code_string_concat("0", String_FromInt(n));
    }
    #line 84 "./src/main.am"
    return String_FromInt(n);
}

struct _Amalgame_Compiler_AmalgameCompiler {
    Amalgame_Compiler_DiagnosticFormatter* Diag;
    code_bool IsLib;
    code_bool CheckOnly;
    code_bool LintMode;
    code_bool Verbose;
    i64 ExitCode;
    AmalgameList* ExternalFiles;
    code_string Target;
};

void Amalgame_Compiler_AmalgameCompiler_SetLib(Amalgame_Compiler_AmalgameCompiler* self, code_bool v);
void Amalgame_Compiler_AmalgameCompiler_SetCheckOnly(Amalgame_Compiler_AmalgameCompiler* self, code_bool v);
void Amalgame_Compiler_AmalgameCompiler_SetLintMode(Amalgame_Compiler_AmalgameCompiler* self, code_bool v);
void Amalgame_Compiler_AmalgameCompiler_SetVerbose(Amalgame_Compiler_AmalgameCompiler* self, code_bool v);
void Amalgame_Compiler_AmalgameCompiler_SetColor(Amalgame_Compiler_AmalgameCompiler* self, code_bool v);
void Amalgame_Compiler_AmalgameCompiler_SetExternalFiles(Amalgame_Compiler_AmalgameCompiler* self, AmalgameList* files);
void Amalgame_Compiler_AmalgameCompiler_SetTarget(Amalgame_Compiler_AmalgameCompiler* self, code_string t);
code_bool Amalgame_Compiler_AmalgameCompiler_IsEmbedded(Amalgame_Compiler_AmalgameCompiler* self);
i64 Amalgame_Compiler_AmalgameCompiler_GetExitCode(Amalgame_Compiler_AmalgameCompiler* self);
void Amalgame_Compiler_AmalgameCompiler_Run(Amalgame_Compiler_AmalgameCompiler* self, AmalgameList* inputFiles, code_string outputName);
void Amalgame_Compiler_AmalgameCompiler_ScanImportsInto(AmalgameList* files, AmalgameList* out);
code_bool Amalgame_Compiler_AmalgameCompiler_NamespaceCoveredBy(AmalgameList* nsList, code_string target);

Amalgame_Compiler_AmalgameCompiler* Amalgame_Compiler_AmalgameCompiler_new() {
    Amalgame_Compiler_AmalgameCompiler* self = (Amalgame_Compiler_AmalgameCompiler*) GC_MALLOC(sizeof(Amalgame_Compiler_AmalgameCompiler));
    #line 104 "./src/main.am"
    self->Diag = Amalgame_Compiler_DiagnosticFormatter_new();
    #line 105 "./src/main.am"
    self->IsLib = 0;
    #line 106 "./src/main.am"
    self->CheckOnly = 0;
    #line 107 "./src/main.am"
    self->LintMode = 0;
    #line 108 "./src/main.am"
    self->Verbose = 0;
    #line 109 "./src/main.am"
    self->ExitCode = 0LL;
    #line 110 "./src/main.am"
    self->ExternalFiles = AmalgameList_new();
    #line 111 "./src/main.am"
    self->Target = "";
    return self;
}

void Amalgame_Compiler_AmalgameCompiler_SetLib(Amalgame_Compiler_AmalgameCompiler* self, code_bool v) {
    #line 114 "./src/main.am"
    self->IsLib = v;
}

void Amalgame_Compiler_AmalgameCompiler_SetCheckOnly(Amalgame_Compiler_AmalgameCompiler* self, code_bool v) {
    #line 115 "./src/main.am"
    self->CheckOnly = v;
}

void Amalgame_Compiler_AmalgameCompiler_SetLintMode(Amalgame_Compiler_AmalgameCompiler* self, code_bool v) {
    #line 116 "./src/main.am"
    self->LintMode = v;
}

void Amalgame_Compiler_AmalgameCompiler_SetVerbose(Amalgame_Compiler_AmalgameCompiler* self, code_bool v) {
    #line 117 "./src/main.am"
    self->Verbose = v;
}

void Amalgame_Compiler_AmalgameCompiler_SetColor(Amalgame_Compiler_AmalgameCompiler* self, code_bool v) {
    #line 118 "./src/main.am"
    Amalgame_Compiler_DiagnosticFormatter_EnableColor(self->Diag, v);
}

void Amalgame_Compiler_AmalgameCompiler_SetExternalFiles(Amalgame_Compiler_AmalgameCompiler* self, AmalgameList* files) {
    #line 119 "./src/main.am"
    self->ExternalFiles = files;
}

void Amalgame_Compiler_AmalgameCompiler_SetTarget(Amalgame_Compiler_AmalgameCompiler* self, code_string t) {
    #line 120 "./src/main.am"
    self->Target = t;
}

code_bool Amalgame_Compiler_AmalgameCompiler_IsEmbedded(Amalgame_Compiler_AmalgameCompiler* self) {
    #line 121 "./src/main.am"
    return String_Length(self->Target) > 0LL;
}

i64 Amalgame_Compiler_AmalgameCompiler_GetExitCode(Amalgame_Compiler_AmalgameCompiler* self) {
    #line 122 "./src/main.am"
    return self->ExitCode;
}

void Amalgame_Compiler_AmalgameCompiler_Run(Amalgame_Compiler_AmalgameCompiler* self, AmalgameList* inputFiles, code_string outputName) {
    #line 127 "./src/main.am"
    i64 inputCount = AmalgameList_count(inputFiles);
    #line 128 "./src/main.am"
    if (inputCount == 0LL) {
        #line 129 "./src/main.am"
        Console_WriteError("amc: no input .am files");
        #line 130 "./src/main.am"
        self->ExitCode = 1LL;
        #line 131 "./src/main.am"
        return;
    }
    #line 134 "./src/main.am"
    if (self->Verbose) {
        #line 135 "./src/main.am"
        Console_WriteLine(code_string_concat((code_string_concat("Compiling: ", String_FromInt(inputCount))), " file(s)"));
    }
    #line 142 "./src/main.am"
    Amalgame_Compiler_MonoTimer* phaseSw = Amalgame_Compiler_MonoTimer_new();
    #line 155 "./src/main.am"
    code_string firstPath = (code_string)AmalgameList_get(inputFiles, 0LL);
    #line 156 "./src/main.am"
    code_string firstSrc = File_ReadAll(firstPath);
    #line 157 "./src/main.am"
    code_string nsPrefix = "App";
    #line 158 "./src/main.am"
    AmalgameList* nsLines = String_Split(firstSrc, "\n");
    #line 159 "./src/main.am"
    i64 nsLineCount = AmalgameList_count(nsLines);
    #line 160 "./src/main.am"
    i64 nsi = 0LL;
    #line 161 "./src/main.am"
    while (nsi < nsLineCount) {
        #line 162 "./src/main.am"
        code_string nsLine = (code_string)AmalgameList_get(nsLines, nsi);
        #line 163 "./src/main.am"
        code_string nsTrim = String_TrimStart(nsLine);
        #line 164 "./src/main.am"
        if (!String_StartsWith(nsTrim, "//")) {
            #line 165 "./src/main.am"
            if (String_StartsWith(nsTrim, "namespace ")) {
                #line 166 "./src/main.am"
                code_string nsAfter = String_From(nsTrim, 10LL);
                #line 167 "./src/main.am"
                nsPrefix = String_Replace(String_Trim(nsAfter), ".", "_");
                #line 168 "./src/main.am"
                nsi = nsLineCount;
            }
        }
        #line 171 "./src/main.am"
        nsi = (nsi + 1LL);
    }
    #line 179 "./src/main.am"
    Amalgame_Compiler_PackageRegistry* pkgReg = Amalgame_Compiler_PackageRegistry_Load();
    #line 197 "./src/main.am"
    i64 pkgCount = AmalgameList_count(pkgReg->Packages);
    #line 215 "./src/main.am"
    AmalgameList* requiredNs = AmalgameList_new();
    #line 216 "./src/main.am"
    Amalgame_Compiler_AmalgameCompiler_ScanImportsInto(inputFiles, requiredNs);
    #line 217 "./src/main.am"
    AmalgameList* pkgAttached = AmalgameList_new();
    #line 218 "./src/main.am"
    for (i64 pi0 = 0LL; pi0 < pkgCount; pi0++) {
        AmalgameList_add(pkgAttached, (void*)(intptr_t)(0));
    }
    #line 219 "./src/main.am"
    code_bool attachChanged = 1;
    #line 220 "./src/main.am"
    while (attachChanged) {
        #line 221 "./src/main.am"
        attachChanged = 0;
        #line 222 "./src/main.am"
        for (i64 pi = 0LL; pi < pkgCount; pi++) {
            #line 223 "./src/main.am"
            if ((code_bool)(intptr_t)AmalgameList_get(pkgAttached, pi)) {
                continue;
            }
            #line 224 "./src/main.am"
            Amalgame_Compiler_LoadedPackage* lp = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(pkgReg->Packages, pi);
            #line 225 "./src/main.am"
            code_bool isSelf = 0;
            #line 226 "./src/main.am"
            if (self->IsLib) {
                #line 227 "./src/main.am"
                code_string lpPrefix = String_Replace(lp->Ns, ".", "_");
                #line 228 "./src/main.am"
                if (code_string_equals(lpPrefix, nsPrefix)) {
                    #line 229 "./src/main.am"
                    isSelf = 1;
                }
            }
            #line 232 "./src/main.am"
            if (isSelf) {
                #line 233 "./src/main.am"
                AmalgameList_set(pkgAttached, pi, (void*)(intptr_t)(1));
                #line 234 "./src/main.am"
                continue;
            }
            #line 236 "./src/main.am"
            if (!Amalgame_Compiler_AmalgameCompiler_NamespaceCoveredBy(requiredNs, lp->Ns)) {
                #line 237 "./src/main.am"
                continue;
            }
            #line 243 "./src/main.am"
            if (String_Length(lp->Facade) > 0LL) {
                #line 244 "./src/main.am"
                AmalgameList_add(self->ExternalFiles, (void*)(intptr_t)(lp->Facade));
            }
            #line 246 "./src/main.am"
            i64 lpSrcCount = AmalgameList_count(lp->Sources);
            #line 247 "./src/main.am"
            AmalgameList* pkgScanList = AmalgameList_new();
            #line 248 "./src/main.am"
            if (String_Length(lp->Facade) > 0LL) {
                #line 249 "./src/main.am"
                AmalgameList_add(pkgScanList, (void*)(intptr_t)(lp->Facade));
            }
            #line 251 "./src/main.am"
            for (i64 si = 0LL; si < lpSrcCount; si++) {
                #line 252 "./src/main.am"
                code_string srcPath = (code_string)AmalgameList_get(lp->Sources, si);
                #line 253 "./src/main.am"
                if (String_EndsWith(srcPath, ".am")) {
                    #line 254 "./src/main.am"
                    AmalgameList_add(self->ExternalFiles, (void*)(intptr_t)(srcPath));
                    #line 255 "./src/main.am"
                    AmalgameList_add(pkgScanList, (void*)(intptr_t)(srcPath));
                }
            }
            #line 258 "./src/main.am"
            Amalgame_Compiler_AmalgameCompiler_ScanImportsInto(pkgScanList, requiredNs);
            #line 259 "./src/main.am"
            AmalgameList_set(pkgAttached, pi, (void*)(intptr_t)(1));
            #line 260 "./src/main.am"
            attachChanged = 1;
        }
    }
    #line 287 "./src/main.am"
    AmalgameList* importedNs = AmalgameList_new();
    #line 288 "./src/main.am"
    code_string amcPathForStdlib = Amalgame_Compiler_Program_ResolveSelfPath();
    #line 289 "./src/main.am"
    code_string stdlibDir = Amalgame_Compiler_Program_ResolveStdlibSrcDir(amcPathForStdlib);
    #line 295 "./src/main.am"
    if (!Amalgame_Compiler_AmalgameCompiler_IsEmbedded(self) && (String_Length(stdlibDir) > 0LL)) {
        #line 306 "./src/main.am"
        AmalgameList* stdlibEntries = AmalgameList_new();
        #line 307 "./src/main.am"
        AmalgameList_add(stdlibEntries, (void*)(intptr_t)("Amalgame.Path|path.am"));
        #line 308 "./src/main.am"
        AmalgameList_add(stdlibEntries, (void*)(intptr_t)("Amalgame.Math|math.am"));
        #line 309 "./src/main.am"
        AmalgameList_add(stdlibEntries, (void*)(intptr_t)("Amalgame.Math.Vec|math_vec.am"));
        #line 310 "./src/main.am"
        AmalgameList_add(stdlibEntries, (void*)(intptr_t)("Amalgame.Formats.Json|json.am"));
        #line 311 "./src/main.am"
        AmalgameList_add(stdlibEntries, (void*)(intptr_t)("Amalgame.Json|json.am"));
        #line 312 "./src/main.am"
        AmalgameList_add(stdlibEntries, (void*)(intptr_t)("Amalgame.Formats.Toml|toml.am"));
        #line 313 "./src/main.am"
        AmalgameList_add(stdlibEntries, (void*)(intptr_t)("Amalgame.Toml|toml.am"));
        #line 314 "./src/main.am"
        AmalgameList_add(stdlibEntries, (void*)(intptr_t)("Amalgame.Formats.MsgPack|msgpack.am"));
        #line 315 "./src/main.am"
        AmalgameList_add(stdlibEntries, (void*)(intptr_t)("Amalgame.MsgPack|msgpack.am"));
        #line 316 "./src/main.am"
        AmalgameList_add(stdlibEntries, (void*)(intptr_t)("Amalgame.Compiler|amc_buildinfo.am"));
        #line 317 "./src/main.am"
        i64 sec = AmalgameList_count(stdlibEntries);
        #line 330 "./src/main.am"
        AmalgameList* inputNs = AmalgameList_new();
        #line 331 "./src/main.am"
        AmalgameList* inputLeafs = AmalgameList_new();
        #line 340 "./src/main.am"
        AmalgameList* scanFiles = AmalgameList_new();
        #line 341 "./src/main.am"
        for (i64 ifs = 0LL; ifs < inputCount; ifs++) {
            #line 342 "./src/main.am"
            AmalgameList_add(scanFiles, (void*)(intptr_t)((code_string)AmalgameList_get(inputFiles, ifs)));
        }
        #line 344 "./src/main.am"
        i64 pkgScanStart = AmalgameList_count(scanFiles);
        #line 345 "./src/main.am"
        for (i64 psi = 0LL; psi < pkgCount; psi++) {
            #line 346 "./src/main.am"
            Amalgame_Compiler_LoadedPackage* plp = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(pkgReg->Packages, psi);
            #line 347 "./src/main.am"
            if (String_Length(plp->Facade) > 0LL) {
                #line 348 "./src/main.am"
                AmalgameList_add(scanFiles, (void*)(intptr_t)(plp->Facade));
            }
            #line 350 "./src/main.am"
            i64 pln = AmalgameList_count(plp->Sources);
            #line 351 "./src/main.am"
            for (i64 psj = 0LL; psj < pln; psj++) {
                #line 352 "./src/main.am"
                AmalgameList_add(scanFiles, (void*)(intptr_t)((code_string)AmalgameList_get(plp->Sources, psj)));
            }
        }
        #line 355 "./src/main.am"
        i64 scanCount = AmalgameList_count(scanFiles);
        #line 356 "./src/main.am"
        for (i64 ifn = 0LL; ifn < scanCount; ifn++) {
            #line 357 "./src/main.am"
            code_string ipath = (code_string)AmalgameList_get(scanFiles, ifn);
            #line 358 "./src/main.am"
            code_bool isUserInput = ifn < pkgScanStart;
            #line 363 "./src/main.am"
            if (isUserInput) {
                #line 364 "./src/main.am"
                i64 lastSlash = String_LastIndexOf(ipath, "/");
                #line 365 "./src/main.am"
                if (lastSlash >= 0LL) {
                    #line 366 "./src/main.am"
                    AmalgameList_add(inputLeafs, (void*)(intptr_t)(String_Substring(ipath, lastSlash + 1LL, (String_Length(ipath) - lastSlash) - 1LL)));
                } else {
                    #line 368 "./src/main.am"
                    AmalgameList_add(inputLeafs, (void*)(intptr_t)(ipath));
                }
            }
            #line 371 "./src/main.am"
            code_string isrc = File_ReadAll(ipath);
            #line 372 "./src/main.am"
            AmalgameList* ilines = String_Split(isrc, "\n");
            #line 373 "./src/main.am"
            i64 iln = AmalgameList_count(ilines);
            #line 374 "./src/main.am"
            i64 idx = 0LL;
            #line 375 "./src/main.am"
            while (idx < iln) {
                #line 376 "./src/main.am"
                code_string raw = (code_string)AmalgameList_get(ilines, idx);
                #line 377 "./src/main.am"
                code_string trimmed = String_TrimStart(raw);
                #line 378 "./src/main.am"
                if (String_StartsWith(trimmed, "//")) {
                    #line 379 "./src/main.am"
                    idx = (idx + 1LL);
                    #line 380 "./src/main.am"
                    continue;
                }
                #line 382 "./src/main.am"
                if (String_StartsWith(trimmed, "import ")) {
                    #line 383 "./src/main.am"
                    code_string after = String_From(trimmed, 7LL);
                    #line 388 "./src/main.am"
                    code_string body = after;
                    #line 389 "./src/main.am"
                    i64 cmt = String_IndexOf(after, "//");
                    #line 390 "./src/main.am"
                    if (cmt >= 0LL) {
                        #line 391 "./src/main.am"
                        body = String_Substring(after, 0LL, cmt);
                    }
                    #line 393 "./src/main.am"
                    code_string imp = String_Trim(body);
                    #line 394 "./src/main.am"
                    if (String_Length(imp) > 0LL) {
                        #line 395 "./src/main.am"
                        AmalgameList_add(importedNs, (void*)(intptr_t)(imp));
                    }
                }
                #line 398 "./src/main.am"
                if (String_StartsWith(trimmed, "namespace ")) {
                    #line 399 "./src/main.am"
                    code_string nsAfter = String_From(trimmed, 10LL);
                    #line 400 "./src/main.am"
                    code_string nsBody = nsAfter;
                    #line 401 "./src/main.am"
                    i64 nsCmt = String_IndexOf(nsAfter, "//");
                    #line 402 "./src/main.am"
                    if (nsCmt >= 0LL) {
                        #line 403 "./src/main.am"
                        nsBody = String_Substring(nsAfter, 0LL, nsCmt);
                    }
                    #line 405 "./src/main.am"
                    code_string nsName = String_Trim(nsBody);
                    #line 410 "./src/main.am"
                    if (isUserInput && (String_Length(nsName) > 0LL)) {
                        #line 411 "./src/main.am"
                        AmalgameList_add(inputNs, (void*)(intptr_t)(nsName));
                    }
                }
                #line 414 "./src/main.am"
                idx = (idx + 1LL);
            }
        }
        #line 423 "./src/main.am"
        for (i64 ei = 0LL; ei < sec; ei++) {
            #line 424 "./src/main.am"
            code_string entry = (code_string)AmalgameList_get(stdlibEntries, ei);
            #line 425 "./src/main.am"
            i64 sepIdx = String_IndexOf(entry, "|");
            #line 426 "./src/main.am"
            if (sepIdx <= 0LL) {
                continue;
            }
            #line 427 "./src/main.am"
            code_string ns = String_Substring(entry, 0LL, sepIdx);
            #line 428 "./src/main.am"
            code_string leaf = String_Substring(entry, sepIdx + 1LL, (String_Length(entry) - sepIdx) - 1LL);
            #line 429 "./src/main.am"
            code_string nsPrefixCand = String_Replace(ns, ".", "_");
            #line 430 "./src/main.am"
            if (code_string_equals(nsPrefixCand, nsPrefix)) {
                continue;
            }
            #line 431 "./src/main.am"
            code_bool declaredByInput = 0;
            #line 432 "./src/main.am"
            i64 nic = AmalgameList_count(inputNs);
            #line 433 "./src/main.am"
            for (i64 nii = 0LL; nii < nic; nii++) {
                #line 434 "./src/main.am"
                if (code_string_equals((code_string)AmalgameList_get(inputNs, nii), ns)) {
                    declaredByInput = 1;
                }
            }
            #line 436 "./src/main.am"
            if (declaredByInput) {
                continue;
            }
            #line 437 "./src/main.am"
            code_bool requested = 0;
            #line 438 "./src/main.am"
            i64 ni = AmalgameList_count(importedNs);
            #line 439 "./src/main.am"
            for (i64 ii = 0LL; ii < ni; ii++) {
                #line 440 "./src/main.am"
                if (code_string_equals((code_string)AmalgameList_get(importedNs, ii), ns)) {
                    requested = 1;
                }
            }
            #line 442 "./src/main.am"
            if (!requested) {
                continue;
            }
            #line 443 "./src/main.am"
            code_string candidate = code_string_concat((code_string_concat(stdlibDir, "/")), leaf);
            #line 444 "./src/main.am"
            if (!File_Exists(candidate)) {
                continue;
            }
            #line 449 "./src/main.am"
            code_bool dup = 0;
            #line 450 "./src/main.am"
            i64 ilc = AmalgameList_count(inputLeafs);
            #line 451 "./src/main.am"
            for (i64 ilf = 0LL; ilf < ilc; ilf++) {
                #line 452 "./src/main.am"
                if (code_string_equals((code_string)AmalgameList_get(inputLeafs, ilf), leaf)) {
                    dup = 1;
                }
            }
            #line 454 "./src/main.am"
            i64 ecc = AmalgameList_count(self->ExternalFiles);
            #line 455 "./src/main.am"
            for (i64 ec = 0LL; ec < ecc; ec++) {
                #line 456 "./src/main.am"
                code_string extPath = (code_string)AmalgameList_get(self->ExternalFiles, ec);
                #line 457 "./src/main.am"
                if (code_string_equals(extPath, candidate)) {
                    dup = 1;
                }
                #line 458 "./src/main.am"
                i64 extSlash = String_LastIndexOf(extPath, "/");
                #line 459 "./src/main.am"
                if (extSlash >= 0LL) {
                    #line 460 "./src/main.am"
                    code_string extLeaf = String_Substring(extPath, extSlash + 1LL, (String_Length(extPath) - extSlash) - 1LL);
                    #line 461 "./src/main.am"
                    if (code_string_equals(extLeaf, leaf)) {
                        dup = 1;
                    }
                }
            }
            #line 464 "./src/main.am"
            if (!dup) {
                #line 465 "./src/main.am"
                AmalgameList_add(self->ExternalFiles, (void*)(intptr_t)(candidate));
            }
        }
    }
    #line 471 "./src/main.am"
    Amalgame_Compiler_CGen* gen = Amalgame_Compiler_CGen_new();
    #line 472 "./src/main.am"
    Amalgame_Compiler_CGen_RegisterPackages(gen, pkgReg);
    #line 475 "./src/main.am"
    Amalgame_Compiler_CGen_SetEmbedded(gen, Amalgame_Compiler_AmalgameCompiler_IsEmbedded(self));
    #line 482 "./src/main.am"
    Amalgame_Compiler_CGen_SetImportedNamespaces(gen, requiredNs);
    #line 488 "./src/main.am"
    AmalgameList* externalProgs = AmalgameList_new();
    #line 489 "./src/main.am"
    i64 externalCount = AmalgameList_count(self->ExternalFiles);
    #line 490 "./src/main.am"
    code_bool parseOk = 1;
    #line 491 "./src/main.am"
    for (i64 ei = 0LL; ei < externalCount; ei++) {
        #line 492 "./src/main.am"
        code_string epath = (code_string)AmalgameList_get(self->ExternalFiles, ei);
        #line 493 "./src/main.am"
        code_string esrc = File_ReadAll(epath);
        #line 494 "./src/main.am"
        Amalgame_Compiler_DiagnosticFormatter_LoadSource(self->Diag, epath, esrc);
        #line 495 "./src/main.am"
        Amalgame_Compiler_Lexer* elex = Amalgame_Compiler_Lexer_new(esrc, epath);
        #line 496 "./src/main.am"
        AmalgameList* etoks = Amalgame_Compiler_Lexer_Tokenize(elex);
        #line 497 "./src/main.am"
        Amalgame_Compiler_Parser* epar = Amalgame_Compiler_Parser_new(etoks);
        #line 498 "./src/main.am"
        Amalgame_Compiler_AstNode* eprog = Amalgame_Compiler_Parser_Parse(epar);
        #line 499 "./src/main.am"
        AmalgameList_add(externalProgs, (void*)(intptr_t)(eprog));
        #line 500 "./src/main.am"
        Amalgame_Compiler_CGen_PreNoteInterfaces(gen, eprog);
        #line 501 "./src/main.am"
        if (Amalgame_Compiler_Parser_HasErrors(epar)) {
            #line 502 "./src/main.am"
            Console_WriteError(code_string_concat("amc: parse errors in external ", epath));
            #line 503 "./src/main.am"
            Console_WriteError(Amalgame_Compiler_Parser_GetErrors(epar));
            #line 504 "./src/main.am"
            self->ExitCode = 1LL;
            #line 505 "./src/main.am"
            parseOk = 0;
        }
    }
    #line 509 "./src/main.am"
    Amalgame_Compiler_CGen_BeginMulti(gen, nsPrefix);
    #line 512 "./src/main.am"
    AmalgameList* progs = AmalgameList_new();
    #line 513 "./src/main.am"
    for (i64 i = 0LL; i < inputCount; i++) {
        #line 514 "./src/main.am"
        code_string path = (code_string)AmalgameList_get(inputFiles, i);
        #line 515 "./src/main.am"
        code_string src = File_ReadAll(path);
        #line 516 "./src/main.am"
        Amalgame_Compiler_DiagnosticFormatter_LoadSource(self->Diag, path, src);
        #line 517 "./src/main.am"
        Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(src, path);
        #line 518 "./src/main.am"
        AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex);
        #line 519 "./src/main.am"
        Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks);
        #line 520 "./src/main.am"
        Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par);
        #line 521 "./src/main.am"
        AmalgameList_add(progs, (void*)(intptr_t)(prog));
        #line 522 "./src/main.am"
        if (Amalgame_Compiler_Parser_HasErrors(par)) {
            #line 523 "./src/main.am"
            Console_WriteError(code_string_concat("amc: parse errors in ", path));
            #line 524 "./src/main.am"
            Console_WriteError(Amalgame_Compiler_Parser_GetErrors(par));
            #line 525 "./src/main.am"
            self->ExitCode = 1LL;
            #line 526 "./src/main.am"
            parseOk = 0;
        }
        #line 528 "./src/main.am"
        Amalgame_Compiler_CGen_AddFilePass1(gen, prog);
    }
    #line 545 "./src/main.am"
    for (i64 ei3 = 0LL; ei3 < externalCount; ei3++) {
        #line 546 "./src/main.am"
        Amalgame_Compiler_CGen_RegisterExternalProgPass1(gen, (Amalgame_Compiler_AstNode*)AmalgameList_get(externalProgs, ei3));
    }
    #line 548 "./src/main.am"
    for (i64 ei4 = 0LL; ei4 < externalCount; ei4++) {
        #line 549 "./src/main.am"
        Amalgame_Compiler_CGen_RegisterExternalProgPass2(gen, (Amalgame_Compiler_AstNode*)AmalgameList_get(externalProgs, ei4));
    }
    #line 555 "./src/main.am"
    if (!parseOk) {
        #line 556 "./src/main.am"
        return;
    }
    #line 558 "./src/main.am"
    if (self->Verbose) {
        #line 559 "./src/main.am"
        Console_WriteError(code_string_concat("  parse:     ", Amalgame_Compiler_MonoTimer_Reset(phaseSw)));
    }
    #line 563 "./src/main.am"
    Amalgame_Compiler_FullResolver* resolver = Amalgame_Compiler_FullResolver_new();
    #line 564 "./src/main.am"
    resolver->Sources = self->Diag->Sources;
    #line 567 "./src/main.am"
    Amalgame_Compiler_FullResolver_RegisterPackages(resolver, pkgReg);
    #line 568 "./src/main.am"
    i64 progCount = AmalgameList_count(progs);
    #line 569 "./src/main.am"
    for (i64 ri = 0LL; ri < progCount; ri++) {
        #line 570 "./src/main.am"
        AmalgameList_add(resolver->Programs, (void*)(intptr_t)((Amalgame_Compiler_AstNode*)AmalgameList_get(progs, ri)));
    }
    #line 575 "./src/main.am"
    i64 extCount = AmalgameList_count(externalProgs);
    #line 576 "./src/main.am"
    for (i64 ei2 = 0LL; ei2 < extCount; ei2++) {
        #line 577 "./src/main.am"
        AmalgameList_add(resolver->Programs, (void*)(intptr_t)((Amalgame_Compiler_AstNode*)AmalgameList_get(externalProgs, ei2)));
    }
    #line 579 "./src/main.am"
    Amalgame_Compiler_FullResolver_CollectAll(resolver);
    #line 580 "./src/main.am"
    if (self->Verbose) {
        #line 581 "./src/main.am"
        Console_WriteError(code_string_concat("  collect:   ", Amalgame_Compiler_MonoTimer_Reset(phaseSw)));
    }
    #line 583 "./src/main.am"
    Amalgame_Compiler_FullResolver_ResolveAll(resolver);
    #line 584 "./src/main.am"
    if (Amalgame_Compiler_FullResolver_HasErrors(resolver)) {
        #line 585 "./src/main.am"
        Console_WriteError(Amalgame_Compiler_FullResolver_GetErrors(resolver));
        #line 586 "./src/main.am"
        self->ExitCode = 1LL;
        #line 587 "./src/main.am"
        if (!self->CheckOnly) {
        }
    }
    #line 591 "./src/main.am"
    if (self->Verbose) {
        #line 592 "./src/main.am"
        Console_WriteError(code_string_concat("  resolve:   ", Amalgame_Compiler_MonoTimer_Reset(phaseSw)));
    }
    #line 600 "./src/main.am"
    Amalgame_Compiler_TypeChecker* tc = Amalgame_Compiler_TypeChecker_new(resolver, firstPath);
    #line 601 "./src/main.am"
    tc->Sources = self->Diag->Sources;
    #line 602 "./src/main.am"
    tc->Embedded = Amalgame_Compiler_AmalgameCompiler_IsEmbedded(self);
    #line 603 "./src/main.am"
    for (i64 ti = 0LL; ti < progCount; ti++) {
        #line 604 "./src/main.am"
        Amalgame_Compiler_TypeChecker_Check(tc, (Amalgame_Compiler_AstNode*)AmalgameList_get(progs, ti));
    }
    #line 609 "./src/main.am"
    for (i64 ti2 = 0LL; ti2 < extCount; ti2++) {
        #line 610 "./src/main.am"
        Amalgame_Compiler_TypeChecker_Check(tc, (Amalgame_Compiler_AstNode*)AmalgameList_get(externalProgs, ti2));
    }
    #line 612 "./src/main.am"
    if (Amalgame_Compiler_TypeChecker_HasErrors(tc)) {
        #line 613 "./src/main.am"
        Console_WriteError(Amalgame_Compiler_TypeChecker_FormatErrors(tc));
        #line 614 "./src/main.am"
        self->ExitCode = 1LL;
    }
    #line 616 "./src/main.am"
    if (self->Verbose) {
        #line 617 "./src/main.am"
        Console_WriteError(code_string_concat("  typecheck: ", Amalgame_Compiler_MonoTimer_Reset(phaseSw)));
    }
    #line 624 "./src/main.am"
    if (self->LintMode) {
        #line 625 "./src/main.am"
        Amalgame_Compiler_Linter* linter = Amalgame_Compiler_Linter_new();
        #line 626 "./src/main.am"
        for (i64 li = 0LL; li < progCount; li++) {
            #line 627 "./src/main.am"
            Amalgame_Compiler_Linter_Lint(linter, (Amalgame_Compiler_AstNode*)AmalgameList_get(progs, li));
        }
        #line 629 "./src/main.am"
        if (Amalgame_Compiler_Linter_HasWarnings(linter)) {
            #line 630 "./src/main.am"
            Console_WriteError(Amalgame_Compiler_Linter_FormatWarnings(linter));
        }
    }
    #line 635 "./src/main.am"
    if (self->CheckOnly) {
        #line 636 "./src/main.am"
        if (self->ExitCode == 0LL) {
            #line 637 "./src/main.am"
            Amalgame_Compiler_DiagnosticFormatter_PrintPhaseOk(self->Diag, "Check");
        }
        #line 639 "./src/main.am"
        return;
    }
    #line 652 "./src/main.am"
    if (self->ExitCode != 0LL) {
        #line 653 "./src/main.am"
        return;
    }
    #line 657 "./src/main.am"
    Amalgame_Compiler_CGen_EmitSeparator(gen);
    #line 663 "./src/main.am"
    for (i64 jf = 0LL; jf < inputCount; jf++) {
        #line 664 "./src/main.am"
        Amalgame_Compiler_CGen_AddFilePass2Forwards(gen, (Amalgame_Compiler_AstNode*)AmalgameList_get(progs, jf));
    }
    #line 666 "./src/main.am"
    for (i64 j = 0LL; j < inputCount; j++) {
        #line 671 "./src/main.am"
        Amalgame_Compiler_CGen_AddFilePass2Bodies(gen, (Amalgame_Compiler_AstNode*)AmalgameList_get(progs, j), (code_string)AmalgameList_get(inputFiles, j));
    }
    #line 675 "./src/main.am"
    AmalgameList* lines = Amalgame_Compiler_CGen_GetLines(gen);
    #line 676 "./src/main.am"
    i64 lineCount = AmalgameList_count(lines);
    #line 677 "./src/main.am"
    code_string outC = code_string_concat(outputName, ".c");
    #line 678 "./src/main.am"
    File_WriteAll(outC, "");
    #line 679 "./src/main.am"
    for (i64 k = 0LL; k < lineCount; k++) {
        #line 680 "./src/main.am"
        File_AppendAll(outC, code_string_concat((code_string)AmalgameList_get(lines, k), "\n"));
    }
    #line 684 "./src/main.am"
    code_string mainFunc = code_string_concat(nsPrefix, "_Program_Main");
    #line 685 "./src/main.am"
    code_string genSrc = File_ReadAll(outC);
    #line 686 "./src/main.am"
    code_bool hasMain = String_Contains(genSrc, mainFunc);
    #line 687 "./src/main.am"
    code_bool isLibrary = self->IsLib || !hasMain;
    #line 688 "./src/main.am"
    if (!isLibrary && Amalgame_Compiler_AmalgameCompiler_IsEmbedded(self)) {
        #line 695 "./src/main.am"
        File_AppendAll(outC, "\nint amc_main(void) {\n");
        #line 696 "./src/main.am"
        File_AppendAll(outC, code_string_concat((code_string_concat("    ", mainFunc)), "();\n"));
        #line 697 "./src/main.am"
        File_AppendAll(outC, "    return 0;\n");
        #line 698 "./src/main.am"
        File_AppendAll(outC, "}\n");
    } else if (!isLibrary) {
        #line 709 "./src/main.am"
        code_string argsExpr = "";
        #line 710 "./src/main.am"
        if (String_Contains(genSrc, code_string_concat(mainFunc, "(AmalgameList*"))) {
            #line 711 "./src/main.am"
            argsExpr = "code_runtime_args_list()";
        } else if (String_Contains(genSrc, code_string_concat(mainFunc, "(code_string*"))) {
            #line 713 "./src/main.am"
            argsExpr = "(code_string*)argv";
        }
        #line 715 "./src/main.am"
        File_AppendAll(outC, "\nint main(int argc, char** argv) {\n");
        #line 716 "./src/main.am"
        File_AppendAll(outC, "    GC_INIT();\n");
        #line 717 "./src/main.am"
        File_AppendAll(outC, "    code_runtime_init_args(argc, argv);\n");
        #line 718 "./src/main.am"
        File_AppendAll(outC, code_string_concat((code_string_concat((code_string_concat((code_string_concat("    ", mainFunc)), "(")), argsExpr)), ");\n"));
        #line 719 "./src/main.am"
        File_AppendAll(outC, "    return code_exit_code;\n");
        #line 720 "./src/main.am"
        File_AppendAll(outC, "}\n");
    } else {
        #line 722 "./src/main.am"
        File_AppendAll(outC, "\n/* Library — no entry point */\n");
    }
    #line 725 "./src/main.am"
    code_string mode = (isLibrary ? "Library" : "Executable");
    #line 726 "./src/main.am"
    Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("Generated: ", outC)), " (")), String_FromInt(lineCount))), " lines) [")), mode)), "]"));
    #line 727 "./src/main.am"
    if (self->Verbose) {
        #line 728 "./src/main.am"
        Console_WriteError(code_string_concat("  cgen:      ", Amalgame_Compiler_MonoTimer_Reset(phaseSw)));
    }
    #line 730 "./src/main.am"
    Amalgame_Compiler_DiagnosticFormatter_PrintCompileOk(self->Diag, "Build");
}

void Amalgame_Compiler_AmalgameCompiler_ScanImportsInto(AmalgameList* files, AmalgameList* out) {
    #line 740 "./src/main.am"
    i64 n = AmalgameList_count(files);
    #line 741 "./src/main.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 742 "./src/main.am"
        code_string path = (code_string)AmalgameList_get(files, i);
        #line 743 "./src/main.am"
        code_string src = File_ReadAll(path);
        #line 744 "./src/main.am"
        AmalgameList* lines = String_Split(src, "\n");
        #line 745 "./src/main.am"
        i64 ln = AmalgameList_count(lines);
        #line 746 "./src/main.am"
        i64 idx = 0LL;
        #line 747 "./src/main.am"
        while (idx < ln) {
            #line 748 "./src/main.am"
            code_string raw = (code_string)AmalgameList_get(lines, idx);
            #line 749 "./src/main.am"
            code_string trimmed = String_TrimStart(raw);
            #line 750 "./src/main.am"
            if (String_StartsWith(trimmed, "//")) {
                #line 751 "./src/main.am"
                idx = (idx + 1LL);
                #line 752 "./src/main.am"
                continue;
            }
            #line 754 "./src/main.am"
            if (String_StartsWith(trimmed, "import ")) {
                #line 755 "./src/main.am"
                code_string after = String_From(trimmed, 7LL);
                #line 756 "./src/main.am"
                code_string body = after;
                #line 757 "./src/main.am"
                i64 cmt = String_IndexOf(after, "//");
                #line 758 "./src/main.am"
                if (cmt >= 0LL) {
                    #line 759 "./src/main.am"
                    body = String_Substring(after, 0LL, cmt);
                }
                #line 761 "./src/main.am"
                code_string imp = String_Trim(body);
                #line 762 "./src/main.am"
                if (String_Length(imp) > 0LL) {
                    #line 763 "./src/main.am"
                    AmalgameList_add(out, (void*)(intptr_t)(imp));
                }
            }
            #line 766 "./src/main.am"
            idx = (idx + 1LL);
        }
    }
}

code_bool Amalgame_Compiler_AmalgameCompiler_NamespaceCoveredBy(AmalgameList* nsList, code_string target) {
    #line 778 "./src/main.am"
    i64 tgtLen = String_Length(target);
    #line 779 "./src/main.am"
    i64 n = AmalgameList_count(nsList);
    #line 780 "./src/main.am"
    for (i64 i = 0LL; i < n; i++) {
        #line 781 "./src/main.am"
        code_string entry = (code_string)AmalgameList_get(nsList, i);
        #line 782 "./src/main.am"
        if (code_string_equals(entry, target)) {
            return 1;
        }
        #line 783 "./src/main.am"
        i64 entryLen = String_Length(entry);
        #line 784 "./src/main.am"
        if (entryLen > tgtLen) {
            #line 785 "./src/main.am"
            if (String_StartsWith(entry, code_string_concat(target, "."))) {
                return 1;
            }
        } else {
            #line 787 "./src/main.am"
            if (String_StartsWith(target, code_string_concat(entry, "."))) {
                return 1;
            }
        }
    }
    #line 790 "./src/main.am"
    return 0;
}

struct _Amalgame_Compiler_Telemetry {
};

static code_bool Amalgame_Compiler_Telemetry_optedOut();
static code_bool Amalgame_Compiler_Telemetry_commandExists(code_string tool);
static code_string Amalgame_Compiler_Telemetry_throttlePath();
static code_bool Amalgame_Compiler_Telemetry_throttled(i64 now);
void Amalgame_Compiler_Telemetry_Ping();

Amalgame_Compiler_Telemetry* Amalgame_Compiler_Telemetry_new() {
    Amalgame_Compiler_Telemetry* self = (Amalgame_Compiler_Telemetry*) GC_MALLOC(sizeof(Amalgame_Compiler_Telemetry));
    return self;
}

static code_bool Amalgame_Compiler_Telemetry_optedOut() {
    #line 808 "./src/main.am"
    if (String_Length(Env_Get("AMALGAME_NO_TELEMETRY")) > 0LL) {
        return 1;
    }
    #line 809 "./src/main.am"
    if (String_Length(Env_Get("DO_NOT_TRACK")) > 0LL) {
        return 1;
    }
    #line 810 "./src/main.am"
    return 0;
}

static code_bool Amalgame_Compiler_Telemetry_commandExists(code_string tool) {
    #line 817 "./src/main.am"
    AmalgameProcessResult* rr = Process_RunCapture(code_string_concat((code_string_concat("command -v ", tool)), " >/dev/null 2>&1"));
    #line 818 "./src/main.am"
    return rr->Exit == 0LL;
}

static code_string Amalgame_Compiler_Telemetry_throttlePath() {
    #line 822 "./src/main.am"
    code_string dir = Amalgame_Compiler_PackageRegistry_AmalgameStateDir();
    #line 823 "./src/main.am"
    if (String_Length(dir) == 0LL) {
        return "";
    }
    #line 824 "./src/main.am"
    return Path_Combine(dir, ".tel_last");
}

static code_bool Amalgame_Compiler_Telemetry_throttled(i64 now) {
    #line 829 "./src/main.am"
    code_string path = Amalgame_Compiler_Telemetry_throttlePath();
    #line 830 "./src/main.am"
    if (String_Length(path) == 0LL) {
        return 1;
    }
    #line 831 "./src/main.am"
    if (!File_Exists(path)) {
        return 0;
    }
    #line 832 "./src/main.am"
    i64 last = String_ToInt(String_Trim(File_ReadAll(path)));
    #line 833 "./src/main.am"
    return (now - last) < 86400LL;
}

void Amalgame_Compiler_Telemetry_Ping() {
    #line 838 "./src/main.am"
    if (Amalgame_Compiler_Telemetry_optedOut()) {
        return;
    }
    #line 839 "./src/main.am"
    i64 now = Amalgame_Compiler_AddCommand_NowSeconds();
    #line 840 "./src/main.am"
    if (now <= 0LL) {
        return;
    }
    #line 841 "./src/main.am"
    if (Amalgame_Compiler_Telemetry_throttled(now)) {
        return;
    }
    #line 844 "./src/main.am"
    code_string plat = Amalgame_Compiler_PackageRegistry_PlatformTag();
    #line 845 "./src/main.am"
    code_string os = plat;
    #line 846 "./src/main.am"
    code_string arch = "unknown";
    #line 847 "./src/main.am"
    i64 dash = String_IndexOf(plat, "-");
    #line 848 "./src/main.am"
    if (dash > 0LL) {
        #line 849 "./src/main.am"
        os = String_Substring(plat, 0LL, dash);
        #line 850 "./src/main.am"
        arch = String_Substring(plat, dash + 1LL, (String_Length(plat) - dash) - 1LL);
    }
    #line 852 "./src/main.am"
    code_string version = Amalgame_Compiler_PackageRegistry_AmcVersion();
    #line 856 "./src/main.am"
    code_string body = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("{\"kind\":\"amc\",\"version\":\"", version)), "\",\"os\":\"")), os)), "\",\"arch\":\"")), arch)), "\"}");
    #line 864 "./src/main.am"
    code_string cmd = "";
    #line 865 "./src/main.am"
    if (Amalgame_Compiler_Telemetry_commandExists("curl")) {
        #line 866 "./src/main.am"
        cmd = (code_string_concat((code_string_concat((code_string_concat((code_string_concat("curl -sS -X POST -H 'Content-Type: application/json'", " --max-time 3 --data '")), body)), "'")), " https://tel.amalgame.me/ping >/dev/null 2>&1 &"));
    } else if (Amalgame_Compiler_Telemetry_commandExists("wget")) {
        #line 870 "./src/main.am"
        cmd = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("wget -q -O /dev/null --timeout=3 --tries=1", " --header='Content-Type: application/json'")), " --post-data='")), body)), "'")), " https://tel.amalgame.me/ping >/dev/null 2>&1 &"));
    }
    #line 875 "./src/main.am"
    if (String_Length(cmd) > 0LL) {
        #line 877 "./src/main.am"
        Process_RunCapture(cmd);
    }
    #line 883 "./src/main.am"
    code_string path = Amalgame_Compiler_Telemetry_throttlePath();
    #line 884 "./src/main.am"
    if (String_Length(path) > 0LL) {
        File_WriteAll(path, String_FromInt(now));
    }
}

struct _Amalgame_Compiler_Program {
};

code_bool Amalgame_Compiler_Program_IsWindows();
code_bool Amalgame_Compiler_Program_IsKnownTarget(code_string name);
code_string Amalgame_Compiler_Program_KnownTargets();
code_bool Amalgame_Compiler_Program_TargetIsXtensa(code_string name);
code_string Amalgame_Compiler_Program_TargetCC(code_string name);
code_string Amalgame_Compiler_Program_TargetObjcopy(code_string name);
code_string Amalgame_Compiler_Program_TargetSize(code_string name);
code_string Amalgame_Compiler_Program_TargetCpuFlags(code_string name);
code_string Amalgame_Compiler_Program_ResolveSelfPath();
code_string Amalgame_Compiler_Program_ResolveRuntimeDir(code_string amcPath);
code_string Amalgame_Compiler_Program_ResolveLibAmalgameA(code_string amcPath);
code_string Amalgame_Compiler_Program_ResolveStdlibSrcDir(code_string amcPath);
void Amalgame_Compiler_Program_PrintUsage();
i64 Amalgame_Compiler_Program_RunTest(i64 argc);
AmalgameList* Amalgame_Compiler_Program_PreCompilePackageSources(Amalgame_Compiler_PackageRegistry* reg, code_string amcRuntime);
void Amalgame_Compiler_Program_PrintPackageSuggestionsForOutput(code_string output, code_string amcPath);
static code_string Amalgame_Compiler_Program_TomlRawValue(AmalgameList* lines, code_string key);
static code_string Amalgame_Compiler_Program_TomlScalar(AmalgameList* lines, code_string key);
static AmalgameList* Amalgame_Compiler_Program_TomlArray(AmalgameList* lines, code_string key);
static code_string Amalgame_Compiler_Program_EnvDirFlags(code_string envName, code_string flag);
i64 Amalgame_Compiler_Program_LinkEmbedded(code_string target, code_string outC, code_string outBin, code_string amcRuntime, code_string boardPath, code_bool verbose, code_bool debug);
code_bool Amalgame_Compiler_Program_RequireTool(code_string tool, code_string hint);
i64 Amalgame_Compiler_Program_FlashEmbedded(code_string boardPath, code_string outBin);
i64 Amalgame_Compiler_Program_RunMonitor(i64 argc);
i64 Amalgame_Compiler_Program_BuildOneBinary(code_string amcPath, code_string entryAm, code_string outBin, code_string amcRuntime, code_string libamalgameA, AmalgameList* pkgObjs, AmalgameList* facadeArs, AmalgameList* pkgLibs, code_bool hasCxx, code_bool verbose, code_bool debug, code_string target, code_string board);
i64 Amalgame_Compiler_Program_BuildEntry(code_string entryAm, code_string outBin, code_bool verbose, code_bool debug, code_string target, code_string board);
i64 Amalgame_Compiler_Program_RunBuild(i64 argc);
i64 Amalgame_Compiler_Program_RunRun(i64 argc);
i64 Amalgame_Compiler_Program_RunWatch(i64 argc);
static i64 Amalgame_Compiler_Program_BuildAndMaybeRun(code_string entryAm, code_string outBin, code_bool verbose, code_bool runAfter);
static i64 Amalgame_Compiler_Program_FileMtimeNs(code_string path);
static void Amalgame_Compiler_Program_SleepMs(i64 ms);
i64 Amalgame_Compiler_Program_RunFmt(i64 argc);
void Amalgame_Compiler_Program_Main(code_string* args);

Amalgame_Compiler_Program* Amalgame_Compiler_Program_new() {
    Amalgame_Compiler_Program* self = (Amalgame_Compiler_Program*) GC_MALLOC(sizeof(Amalgame_Compiler_Program));
    return self;
}

code_bool Amalgame_Compiler_Program_IsWindows() {
    #line 894 "./src/main.am"
    { /* inline-C */
        
                #ifdef _WIN32
                    return 1;
                #else
                    return 0;
                #endif
                
    }
}

code_bool Amalgame_Compiler_Program_IsKnownTarget(code_string name) {
    #line 911 "./src/main.am"
    return (((code_string_equals(name, "cortex-m3")) || (code_string_equals(name, "cortex-m4"))) || (code_string_equals(name, "cortex-m7"))) || (code_string_equals(name, "esp32s3"));
}

code_string Amalgame_Compiler_Program_KnownTargets() {
    #line 917 "./src/main.am"
    return "cortex-m3, cortex-m4, cortex-m7, esp32s3";
}

code_bool Amalgame_Compiler_Program_TargetIsXtensa(code_string name) {
    #line 924 "./src/main.am"
    return code_string_equals(name, "esp32s3");
}

code_string Amalgame_Compiler_Program_TargetCC(code_string name) {
    #line 929 "./src/main.am"
    if (Amalgame_Compiler_Program_TargetIsXtensa(name)) {
        return "xtensa-esp32s3-elf-gcc";
    }
    #line 930 "./src/main.am"
    return "arm-none-eabi-gcc";
}

code_string Amalgame_Compiler_Program_TargetObjcopy(code_string name) {
    #line 936 "./src/main.am"
    if (Amalgame_Compiler_Program_TargetIsXtensa(name)) {
        return "xtensa-esp32s3-elf-objcopy";
    }
    #line 937 "./src/main.am"
    return "arm-none-eabi-objcopy";
}

code_string Amalgame_Compiler_Program_TargetSize(code_string name) {
    #line 940 "./src/main.am"
    if (Amalgame_Compiler_Program_TargetIsXtensa(name)) {
        return "xtensa-esp32s3-elf-size";
    }
    #line 941 "./src/main.am"
    return "arm-none-eabi-size";
}

code_string Amalgame_Compiler_Program_TargetCpuFlags(code_string name) {
    #line 948 "./src/main.am"
    if (code_string_equals(name, "cortex-m3")) {
        return "-mcpu=cortex-m3 -mthumb";
    }
    #line 949 "./src/main.am"
    if (code_string_equals(name, "cortex-m4")) {
        return "-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16";
    }
    #line 950 "./src/main.am"
    if (code_string_equals(name, "cortex-m7")) {
        return "-mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16";
    }
    #line 951 "./src/main.am"
    if (code_string_equals(name, "esp32s3")) {
        return "-mlongcalls";
    }
    #line 952 "./src/main.am"
    return "-mthumb";
}

code_string Amalgame_Compiler_Program_ResolveSelfPath() {
    #line 963 "./src/main.am"
    { /* inline-C */
        
                    #ifdef _WIN32
                        char buf[4096];
                        DWORD n = GetModuleFileNameA(NULL, buf, sizeof(buf));
                        if (n == 0 || n >= sizeof(buf)) { return (code_string) ""; }
                        /* Normalise backslashes so dirname / Substring split work. */
                        for (DWORD i = 0; i < n; i++) { if (buf[i] == '\\') buf[i] = '/'; }
                        char* out = (char*) GC_MALLOC((size_t)(n + 1));
                        memcpy(out, buf, (size_t)(n + 1));
                        return (code_string) out;
                    #elif defined(__APPLE__)
                        /* `#include ` + `` moved to the
                         * file-scope @c block at the top of main.am — clang
                         * rejects the byte_order.h inline functions when those
                         * headers are pulled in inside a function body. */
                        char raw[4096];
                        uint32_t size = sizeof(raw);
                        if (_NSGetExecutablePath(raw, &size) != 0) { return (code_string) ""; }
                        /* realpath collapses any /./, /../, or symlink in the path
                         * — Homebrew installs amc as a symlink in /usr/local/bin
                         * pointing at the versioned cellar; we want the cellar
                         * path so the runtime/ sibling search succeeds. */
                        char resolved[4096];
                        char* p = realpath(raw, resolved);
                        const char* src = p ? (const char*)resolved : (const char*)raw;
                        size_t n = strlen(src);
                        char* out = (char*) GC_MALLOC(n + 1);
                        memcpy(out, src, n + 1);
                        return (code_string) out;
                    #else
                        char buf[4096];
                        ssize_t n = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
                        if (n <= 0) { return (code_string) ""; }
                        buf[n] = '\0';
                        char* out = (char*) GC_MALLOC((size_t)(n + 1));
                        memcpy(out, buf, (size_t)(n + 1));
                        return (code_string) out;
                    #endif
                
    }
}

code_string Amalgame_Compiler_Program_ResolveRuntimeDir(code_string amcPath) {
    #line 1013 "./src/main.am"
    code_string envDir = Env_Get("AMC_RUNTIME");
    #line 1014 "./src/main.am"
    if ((String_Length(envDir) > 0LL) && File_Exists(code_string_concat(envDir, "/_runtime.h"))) {
        #line 1015 "./src/main.am"
        return envDir;
    }
    #line 1017 "./src/main.am"
    i64 slashIdx = String_LastIndexOf(amcPath, "/");
    #line 1018 "./src/main.am"
    if (slashIdx < 0LL) {
        return "";
    }
    #line 1019 "./src/main.am"
    code_string binDir = String_Substring(amcPath, 0LL, slashIdx);
    #line 1020 "./src/main.am"
    code_string xdg = code_string_concat(binDir, "/../share/amalgame/runtime");
    #line 1021 "./src/main.am"
    if (File_Exists(code_string_concat(xdg, "/_runtime.h"))) {
        return xdg;
    }
    #line 1022 "./src/main.am"
    code_string legacy = code_string_concat(binDir, "/runtime");
    #line 1023 "./src/main.am"
    if (File_Exists(code_string_concat(legacy, "/_runtime.h"))) {
        return legacy;
    }
    #line 1024 "./src/main.am"
    return "";
}

code_string Amalgame_Compiler_Program_ResolveLibAmalgameA(code_string amcPath) {
    #line 1033 "./src/main.am"
    code_string envDir = Env_Get("AMC_LIB");
    #line 1034 "./src/main.am"
    if ((String_Length(envDir) > 0LL) && File_Exists(code_string_concat(envDir, "/libamalgame.a"))) {
        #line 1035 "./src/main.am"
        return code_string_concat(envDir, "/libamalgame.a");
    }
    #line 1037 "./src/main.am"
    i64 slashIdx = String_LastIndexOf(amcPath, "/");
    #line 1038 "./src/main.am"
    if (slashIdx < 0LL) {
        return "";
    }
    #line 1039 "./src/main.am"
    code_string binDir = String_Substring(amcPath, 0LL, slashIdx);
    #line 1040 "./src/main.am"
    code_string xdg = code_string_concat(binDir, "/../share/amalgame/lib/libamalgame.a");
    #line 1041 "./src/main.am"
    if (File_Exists(xdg)) {
        return xdg;
    }
    #line 1042 "./src/main.am"
    code_string legacy = code_string_concat(binDir, "/lib/libamalgame.a");
    #line 1043 "./src/main.am"
    if (File_Exists(legacy)) {
        return legacy;
    }
    #line 1044 "./src/main.am"
    return "";
}

code_string Amalgame_Compiler_Program_ResolveStdlibSrcDir(code_string amcPath) {
    #line 1063 "./src/main.am"
    code_string envDir = Env_Get("AMC_STDLIB_SRC");
    #line 1064 "./src/main.am"
    if ((String_Length(envDir) > 0LL) && File_Exists(code_string_concat(envDir, "/json.am"))) {
        #line 1065 "./src/main.am"
        return envDir;
    }
    #line 1067 "./src/main.am"
    i64 slashIdx = String_LastIndexOf(amcPath, "/");
    #line 1068 "./src/main.am"
    if (slashIdx < 0LL) {
        return "";
    }
    #line 1069 "./src/main.am"
    code_string binDir = String_Substring(amcPath, 0LL, slashIdx);
    #line 1070 "./src/main.am"
    code_string xdg = code_string_concat(binDir, "/../share/amalgame/stdlib");
    #line 1071 "./src/main.am"
    if (File_Exists(code_string_concat(xdg, "/json.am"))) {
        return xdg;
    }
    #line 1072 "./src/main.am"
    code_string dev = code_string_concat(binDir, "/src/stdlib");
    #line 1073 "./src/main.am"
    if (File_Exists(code_string_concat(dev, "/json.am"))) {
        return dev;
    }
    #line 1074 "./src/main.am"
    return "";
}

void Amalgame_Compiler_Program_PrintUsage() {
    #line 1078 "./src/main.am"
    Console_WriteError("Usage: amc [options] file1.am [file2.am ...] -o ");
    #line 1079 "./src/main.am"
    Console_WriteError("       amc fmt [-w] file.am [file.am ...]");
    #line 1080 "./src/main.am"
    Console_WriteError("");
    #line 1081 "./src/main.am"
    Console_WriteError("Options:");
    #line 1082 "./src/main.am"
    Console_WriteError("  -o    Output file (default: a.out)");
    #line 1083 "./src/main.am"
    Console_WriteError("  --lib         Compile as library (no main() emitted)");
    #line 1084 "./src/main.am"
    Console_WriteError("  --check       Type-check only, no code generation");
    #line 1085 "./src/main.am"
    Console_WriteError("  --lint        Run static-analysis warnings (in addition to compile)");
    #line 1086 "./src/main.am"
    Console_WriteError("  --color       Force ANSI color output");
    #line 1087 "./src/main.am"
    Console_WriteError("  --no-color    Disable ANSI color output");
    #line 1088 "./src/main.am"
    Console_WriteError("  --quiet       Suppress progress messages");
    #line 1089 "./src/main.am"
    Console_WriteError("  --verbose     Print extra build info");
    #line 1090 "./src/main.am"
    Console_WriteError("  --version     Print version and exit");
    #line 1091 "./src/main.am"
    Console_WriteError("  --help        Print this help");
    #line 1092 "./src/main.am"
    Console_WriteError("");
    #line 1093 "./src/main.am"
    Console_WriteError("Subcommands:");
    #line 1094 "./src/main.am"
    Console_WriteError("  build   Compile + link a runnable binary in one step.");
    #line 1095 "./src/main.am"
    Console_WriteError("                Default output is the entry's stem (foo.am → ./foo).");
    #line 1096 "./src/main.am"
    Console_WriteError("                Flags: -o , --verbose. See `amc build --help`.");
    #line 1097 "./src/main.am"
    Console_WriteError("  run     Build, then exec the resulting binary. Args after `--`");
    #line 1098 "./src/main.am"
    Console_WriteError("                are forwarded to the user binary's argv.");
    #line 1099 "./src/main.am"
    Console_WriteError("                See `amc run --help`.");
    #line 1100 "./src/main.am"
    Console_WriteError("  watch   Build now, then poll the entry's mtime every 500 ms");
    #line 1101 "./src/main.am"
    Console_WriteError("                and rebuild on change. With --run, re-exec after each");
    #line 1102 "./src/main.am"
    Console_WriteError("                rebuild. See `amc watch --help`.");
    #line 1103 "./src/main.am"
    Console_WriteError("  fmt           Format Amalgame source. Default: print to stdout.");
    #line 1104 "./src/main.am"
    Console_WriteError("                With -w, rewrite files in place.");
    #line 1105 "./src/main.am"
    Console_WriteError("  test []  Discover *_test.am, compile + run each, aggregate");
    #line 1106 "./src/main.am"
    Console_WriteError("                [PASS]/[FAIL]/[SKIP] lines from their stdout.");
    #line 1107 "./src/main.am"
    Console_WriteError("  lsp           Run a minimal LSP server (stdio JSON-RPC).");
    #line 1108 "./src/main.am"
    Console_WriteError("                v1 publishes diagnostics on didOpen/didChange.");
    #line 1109 "./src/main.am"
    Console_WriteError("  dap           Run a DAP proxy over stdio (forwards to lldb-dap / gdb --dap).");
    #line 1110 "./src/main.am"
    Console_WriteError("                Use `amc build -g entry.am` first to embed DWARF info.");
    #line 1111 "./src/main.am"
    Console_WriteError("  migrate    Migrate a source file or directory to Amalgame via LLM.");
    #line 1112 "./src/main.am"
    Console_WriteError("                Auto-uses claude-api when ANTHROPIC_API_KEY is set, else");
    #line 1113 "./src/main.am"
    Console_WriteError("                shells out to the local `claude` CLI. See `amc migrate --help`.");
    #line 1114 "./src/main.am"
    Console_WriteError("  generate 

Generate an Amalgame program from a natural-language prompt."); #line 1115 "./src/main.am" Console_WriteError(" Same provider auto-selection as migrate. See `amc generate --help`."); #line 1116 "./src/main.am" Console_WriteError(" explain Read an Amalgame file and emit a natural-language explanation."); #line 1117 "./src/main.am" Console_WriteError(" See `amc explain --help`."); #line 1118 "./src/main.am" Console_WriteError(" new Scaffold a new Amalgame project (exe / lib / test / service / forms)."); #line 1119 "./src/main.am" Console_WriteError(" Wires .vscode/launch.json + settings.json by default so F5 ="); #line 1120 "./src/main.am" Console_WriteError(" `amc dap` debug; pass --no-vscode to skip. See `amc new --help`."); #line 1121 "./src/main.am" Console_WriteError(" package Package manager (alias `pkg`). Verbs: add / remove / list /"); #line 1122 "./src/main.am" Console_WriteError(" search / versions / info / outdated / notice / check /"); #line 1123 "./src/main.am" Console_WriteError(" update / cache. See `amc package --help`."); } i64 Amalgame_Compiler_Program_RunTest(i64 argc) { #line 1136 "./src/main.am" code_string dir = "."; #line 1137 "./src/main.am" code_string filterPat = ""; #line 1138 "./src/main.am" code_bool ciMode = 0; #line 1139 "./src/main.am" code_bool listOnly = 0; #line 1140 "./src/main.am" i64 i = 2LL; #line 1141 "./src/main.am" while (i < argc) { #line 1142 "./src/main.am" code_string a = Args_Get(i); #line 1143 "./src/main.am" if ((code_string_equals(a, "--filter")) && ((i + 1LL) < argc)) { #line 1148 "./src/main.am" i = (i + 1LL); #line 1149 "./src/main.am" filterPat = Args_Get(i); } else if (code_string_equals(a, "--ci")) { #line 1154 "./src/main.am" ciMode = 1; } else if (code_string_equals(a, "--list")) { #line 1159 "./src/main.am" listOnly = 1; } else if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) { #line 1161 "./src/main.am" Console_WriteLine("Usage: amc test [

] [options]"); #line 1162 "./src/main.am" Console_WriteLine(" Root to discover *_test.am under (default: .)"); #line 1163 "./src/main.am" Console_WriteLine("Options:"); #line 1164 "./src/main.am" Console_WriteLine(" --filter Only run tests whose path contains "); #line 1165 "./src/main.am" Console_WriteLine(" --ci Terse output (drop PASS/SKIP, keep FAIL + tally)"); #line 1166 "./src/main.am" Console_WriteLine(" --list Print discovered paths and exit (no compile, no run)"); #line 1167 "./src/main.am" return 0LL; } else if (String_StartsWith(a, "-")) { #line 1169 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat("amc test: unknown option '", a)), "'")); #line 1170 "./src/main.am" return 1LL; } else { #line 1172 "./src/main.am" dir = a; } #line 1174 "./src/main.am" i = (i + 1LL); } #line 1182 "./src/main.am" i64 installed = Amalgame_Compiler_AddCommand_EnsureInstalled(); #line 1183 "./src/main.am" if (installed < 0LL) { #line 1184 "./src/main.am" Console_WriteError("amc test: package install failed; aborting"); #line 1185 "./src/main.am" return 1LL; } #line 1187 "./src/main.am" if (installed > 0LL) { #line 1188 "./src/main.am" Console_WriteLine(code_string_concat((code_string_concat("amc test: installed ", String_FromInt(installed))), " missing dep(s)")); } #line 1200 "./src/main.am" code_string amcPathForRt = Amalgame_Compiler_Program_ResolveSelfPath(); #line 1201 "./src/main.am" if (String_Length(amcPathForRt) == 0LL) { #line 1202 "./src/main.am" amcPathForRt = Args_Get(0LL); } #line 1204 "./src/main.am" code_string amcRuntime = Amalgame_Compiler_Program_ResolveRuntimeDir(amcPathForRt); #line 1205 "./src/main.am" Amalgame_Compiler_PackageRegistry* registry = Amalgame_Compiler_PackageRegistry_Load(); #line 1206 "./src/main.am" AmalgameList* pkgObjs = Amalgame_Compiler_Program_PreCompilePackageSources(registry, amcRuntime); #line 1207 "./src/main.am" code_bool hasCxx = Amalgame_Compiler_PackageRegistry_HasCxxSources(registry); #line 1208 "./src/main.am" AmalgameList* pkgLibs = Amalgame_Compiler_PackageRegistry_CollectLibs(registry); #line 1214 "./src/main.am" AmalgameList* facadeArs = Amalgame_Compiler_PackageRegistry_CollectFacadeArchives(registry); #line 1224 "./src/main.am" code_string findCmd = code_string_concat((code_string_concat("find ", dir)), " -name fixtures -prune -o -name '*_test.am' -type f -print"); #line 1225 "./src/main.am" AmalgameProcessResult* discovered = Process_RunCapture(findCmd); #line 1226 "./src/main.am" if (discovered->Exit != 0LL) { #line 1227 "./src/main.am" Console_WriteError(code_string_concat("amc test: failed to enumerate tests in ", dir)); #line 1228 "./src/main.am" Console_WriteError(discovered->Stdout); #line 1229 "./src/main.am" return 1LL; } #line 1231 "./src/main.am" AmalgameList* raw = String_Split(String_Trim(discovered->Stdout), "\n"); #line 1236 "./src/main.am" AmalgameList* lines = AmalgameList_new(); #line 1237 "./src/main.am" i64 rawN = AmalgameList_count(raw); #line 1238 "./src/main.am" for (i64 ri = 0LL; ri < rawN; ri++) { #line 1239 "./src/main.am" code_string r = String_Trim((code_string)AmalgameList_get(raw, ri)); #line 1240 "./src/main.am" if (String_Length(r) == 0LL) { continue; } #line 1241 "./src/main.am" if ((String_Length(filterPat) > 0LL) && !String_Contains(r, filterPat)) { continue; } #line 1242 "./src/main.am" AmalgameList_add(lines, (void*)(intptr_t)(r)); } #line 1244 "./src/main.am" i64 nLines = AmalgameList_count(lines); #line 1245 "./src/main.am" if (nLines == 0LL) { #line 1246 "./src/main.am" if (String_Length(filterPat) > 0LL) { #line 1247 "./src/main.am" Console_WriteLine(code_string_concat((code_string_concat((code_string_concat("No *_test.am files matched filter '", filterPat)), "' under ")), dir)); } else { #line 1249 "./src/main.am" Console_WriteLine(code_string_concat("No *_test.am files found under ", dir)); } #line 1251 "./src/main.am" return 0LL; } #line 1254 "./src/main.am" if (listOnly) { #line 1255 "./src/main.am" for (i64 li = 0LL; li < nLines; li++) { #line 1256 "./src/main.am" Console_WriteLine((code_string)AmalgameList_get(lines, li)); } #line 1258 "./src/main.am" return 0LL; } #line 1261 "./src/main.am" code_string amcPath = Amalgame_Compiler_Program_ResolveSelfPath(); #line 1262 "./src/main.am" if (String_Length(amcPath) == 0LL) { #line 1263 "./src/main.am" amcPath = Args_Get(0LL); } #line 1265 "./src/main.am" i64 pass = 0LL; #line 1266 "./src/main.am" i64 fail = 0LL; #line 1267 "./src/main.am" i64 skip = 0LL; #line 1268 "./src/main.am" i64 compileFail = 0LL; #line 1270 "./src/main.am" for (i64 li = 0LL; li < nLines; li++) { #line 1271 "./src/main.am" code_string path = String_Trim((code_string)AmalgameList_get(lines, li)); #line 1272 "./src/main.am" if (String_Length(path) == 0LL) { continue; } #line 1273 "./src/main.am" if (!ciMode) { Console_WriteLine(code_string_concat("── ", path)); } #line 1276 "./src/main.am" code_string outBin = code_string_concat("/tmp/amc_test_", String_FromInt(li)); #line 1277 "./src/main.am" code_string outC = code_string_concat(outBin, ".c"); #line 1278 "./src/main.am" code_string amcCmd = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(amcPath, " ")), path)), " -o ")), outBin)), " --quiet"); #line 1279 "./src/main.am" AmalgameProcessResult* cr = Process_RunCapture(amcCmd); #line 1280 "./src/main.am" if (cr->Exit != 0LL) { #line 1281 "./src/main.am" if (ciMode) { Console_WriteLine(code_string_concat(" [COMPILE-FAIL] in ", path)); } else { #line 1282 "./src/main.am" Console_WriteLine(" [COMPILE-FAIL]"); } #line 1283 "./src/main.am" Console_Write(cr->Stdout); #line 1284 "./src/main.am" compileFail = (compileFail + 1LL); #line 1285 "./src/main.am" continue; } #line 1307 "./src/main.am" AmalgameList* pkgIncDirs = Amalgame_Compiler_AddCommand_AllCachedRuntimeDirs(); #line 1308 "./src/main.am" i64 pkgIncN = AmalgameList_count(pkgIncDirs); #line 1309 "./src/main.am" code_string pkgIncFlags = ""; #line 1310 "./src/main.am" for (i64 pii = 0LL; pii < pkgIncN; pii++) { #line 1311 "./src/main.am" pkgIncFlags = (code_string_concat((code_string_concat((code_string_concat(pkgIncFlags, " -I\"")), (code_string)AmalgameList_get(pkgIncDirs, pii))), "\"")); } #line 1313 "./src/main.am" code_string gccCmd = ""; #line 1314 "./src/main.am" if (hasCxx) { #line 1316 "./src/main.am" code_string compileCmd = "gcc -O2 -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Iruntime"; #line 1317 "./src/main.am" if (String_Length(amcRuntime) > 0LL) { #line 1318 "./src/main.am" compileCmd = (code_string_concat((code_string_concat((code_string_concat(compileCmd, " -I\"")), amcRuntime)), "\"")); } #line 1320 "./src/main.am" compileCmd = (code_string_concat(compileCmd, pkgIncFlags)); #line 1321 "./src/main.am" code_string objOut = code_string_concat(outBin, ".o"); #line 1322 "./src/main.am" compileCmd = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(compileCmd, " -c ")), outC)), " -o ")), objOut)), " 2>&1")); #line 1323 "./src/main.am" AmalgameProcessResult* stageA = Process_RunCapture(compileCmd); #line 1324 "./src/main.am" if (stageA->Exit != 0LL) { #line 1325 "./src/main.am" if (ciMode) { Console_WriteLine(code_string_concat(" [LINK-FAIL] in ", path)); } else { #line 1326 "./src/main.am" Console_WriteLine(" [LINK-FAIL]"); } #line 1327 "./src/main.am" Console_Write(stageA->Stdout); #line 1328 "./src/main.am" compileFail = (compileFail + 1LL); #line 1329 "./src/main.am" continue; } #line 1332 "./src/main.am" gccCmd = (code_string_concat("g++ -O2 ", objOut)); } else { #line 1334 "./src/main.am" gccCmd = "gcc -O2 -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Iruntime"; #line 1335 "./src/main.am" if (String_Length(amcRuntime) > 0LL) { #line 1336 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, " -I\"")), amcRuntime)), "\"")); } #line 1338 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, pkgIncFlags)), " ")), outC)); } #line 1340 "./src/main.am" i64 nObjs = AmalgameList_count(pkgObjs); #line 1341 "./src/main.am" for (i64 poi = 0LL; poi < nObjs; poi++) { #line 1342 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, " \"")), (code_string)AmalgameList_get(pkgObjs, poi))), "\"")); } #line 1349 "./src/main.am" i64 nFAr = AmalgameList_count(facadeArs); #line 1350 "./src/main.am" for (i64 fai = 0LL; fai < nFAr; fai++) { #line 1351 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, " \"")), (code_string)AmalgameList_get(facadeArs, fai))), "\"")); } #line 1359 "./src/main.am" code_string libATest = Amalgame_Compiler_Program_ResolveLibAmalgameA(Amalgame_Compiler_AddCommand_ResolveSelfPath()); #line 1360 "./src/main.am" if (String_Length(libATest) > 0LL) { #line 1361 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, " \"")), libATest)), "\"")); } #line 1363 "./src/main.am" gccCmd = (code_string_concat(gccCmd, " -lgc -lm -lz -lpthread")); #line 1364 "./src/main.am" if (!Amalgame_Compiler_Program_IsWindows()) { gccCmd = (code_string_concat(gccCmd, " -ldl")); } #line 1368 "./src/main.am" i64 nLibs = AmalgameList_count(pkgLibs); #line 1369 "./src/main.am" for (i64 plj = 0LL; plj < nLibs; plj++) { #line 1370 "./src/main.am" gccCmd = (code_string_concat((code_string_concat(gccCmd, " -l")), (code_string)AmalgameList_get(pkgLibs, plj))); } #line 1372 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, " -o ")), outBin)), " 2>&1")); #line 1373 "./src/main.am" AmalgameProcessResult* gcc = Process_RunCapture(gccCmd); #line 1374 "./src/main.am" if (gcc->Exit != 0LL) { #line 1375 "./src/main.am" if (ciMode) { Console_WriteLine(code_string_concat(" [LINK-FAIL] in ", path)); } else { #line 1376 "./src/main.am" Console_WriteLine(" [LINK-FAIL]"); } #line 1377 "./src/main.am" Console_Write(gcc->Stdout); #line 1378 "./src/main.am" compileFail = (compileFail + 1LL); #line 1379 "./src/main.am" continue; } #line 1384 "./src/main.am" AmalgameProcessResult* rr = Process_RunCapture(outBin); #line 1385 "./src/main.am" AmalgameList* outLines = String_Split(rr->Stdout, "\n"); #line 1386 "./src/main.am" i64 on = AmalgameList_count(outLines); #line 1387 "./src/main.am" for (i64 ln = 0LL; ln < on; ln++) { #line 1388 "./src/main.am" code_string lineStr = (code_string)AmalgameList_get(outLines, ln); #line 1389 "./src/main.am" if (String_StartsWith(lineStr, "[PASS]")) { #line 1390 "./src/main.am" if (!ciMode) { Console_WriteLine(code_string_concat(" ", lineStr)); } #line 1391 "./src/main.am" pass = (pass + 1LL); } else if (String_StartsWith(lineStr, "[FAIL]")) { #line 1396 "./src/main.am" if (ciMode) { Console_WriteLine(code_string_concat(" [FAIL] in ", path)); } #line 1397 "./src/main.am" Console_WriteLine(code_string_concat(" ", lineStr)); #line 1398 "./src/main.am" fail = (fail + 1LL); } else if (String_StartsWith(lineStr, "[SKIP]")) { #line 1400 "./src/main.am" if (!ciMode) { Console_WriteLine(code_string_concat(" ", lineStr)); } #line 1401 "./src/main.am" skip = (skip + 1LL); } } #line 1406 "./src/main.am" if ((((rr->Exit != 0LL) && (pass == 0LL)) && (fail == 0LL)) && (skip == 0LL)) { #line 1407 "./src/main.am" if (ciMode) { Console_WriteLine(code_string_concat((code_string_concat((code_string_concat(" [FAIL] in ", path)), " exit=")), String_FromInt(rr->Exit))); } else { #line 1408 "./src/main.am" Console_WriteLine(code_string_concat(" [FAIL] exit=", String_FromInt(rr->Exit))); } #line 1409 "./src/main.am" fail = (fail + 1LL); } } #line 1413 "./src/main.am" Console_WriteLine(""); #line 1414 "./src/main.am" Console_WriteLine("──────────────────────────────────"); #line 1415 "./src/main.am" Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("PASS: ", String_FromInt(pass))), " FAIL: ")), String_FromInt(fail))), " SKIP: ")), String_FromInt(skip))); #line 1416 "./src/main.am" if (compileFail > 0LL) { #line 1417 "./src/main.am" Console_WriteLine(code_string_concat("COMPILE-FAIL: ", String_FromInt(compileFail))); #line 1418 "./src/main.am" return 1LL; } #line 1420 "./src/main.am" if (fail > 0LL) { return 1LL; } #line 1421 "./src/main.am" return 0LL; } AmalgameList* Amalgame_Compiler_Program_PreCompilePackageSources(Amalgame_Compiler_PackageRegistry* reg, code_string amcRuntime) { #line 1443 "./src/main.am" AmalgameList* out = AmalgameList_new(); #line 1444 "./src/main.am" i64 n = AmalgameList_count(reg->Packages); #line 1445 "./src/main.am" for (i64 i = 0LL; i < n; i++) { #line 1446 "./src/main.am" Amalgame_Compiler_LoadedPackage* p = (Amalgame_Compiler_LoadedPackage*)AmalgameList_get(reg->Packages, i); #line 1452 "./src/main.am" AmalgameList* sources = AmalgameList_new(); #line 1453 "./src/main.am" if (String_Length(p->Facade) > 0LL) { #line 1454 "./src/main.am" AmalgameList_add(sources, (void*)(intptr_t)(p->Facade)); } #line 1456 "./src/main.am" i64 extraSrc = AmalgameList_count(p->Sources); #line 1457 "./src/main.am" for (i64 esi = 0LL; esi < extraSrc; esi++) { #line 1458 "./src/main.am" AmalgameList_add(sources, (void*)(intptr_t)((code_string)AmalgameList_get(p->Sources, esi))); } #line 1460 "./src/main.am" i64 sn = AmalgameList_count(sources); #line 1461 "./src/main.am" if (sn == 0LL) { continue; } #line 1465 "./src/main.am" code_string persistentDir = Amalgame_Compiler_PackageRegistry_PrecompileCacheDir(p->PkgDir); #line 1472 "./src/main.am" AmalgameList* amSources = AmalgameList_new(); #line 1473 "./src/main.am" AmalgameList* nativeSources = AmalgameList_new(); #line 1474 "./src/main.am" for (i64 j = 0LL; j < sn; j++) { #line 1475 "./src/main.am" code_string sp = (code_string)AmalgameList_get(sources, j); #line 1476 "./src/main.am" if (String_Length(sp) == 0LL) { continue; } #line 1477 "./src/main.am" if (String_EndsWith(sp, ".am")) { #line 1478 "./src/main.am" AmalgameList_add(amSources, (void*)(intptr_t)(sp)); } else { #line 1480 "./src/main.am" AmalgameList_add(nativeSources, (void*)(intptr_t)(sp)); } } #line 1485 "./src/main.am" if (AmalgameList_count(amSources) > 0LL) { #line 1486 "./src/main.am" code_string amObj = code_string_concat((code_string_concat("/tmp/amc-pkg-", p->ClassName)), ".o"); #line 1487 "./src/main.am" code_string amCacheObj = code_string_concat((code_string_concat((code_string_concat(persistentDir, "/")), p->ClassName)), ".o"); #line 1488 "./src/main.am" code_bool skipAm = 0; #line 1489 "./src/main.am" if (File_Exists(amCacheObj)) { #line 1490 "./src/main.am" AmalgameList_add(out, (void*)(intptr_t)(amCacheObj)); skipAm = 1; } else if (File_Exists(amObj)) { #line 1492 "./src/main.am" AmalgameList_add(out, (void*)(intptr_t)(amObj)); skipAm = 1; } #line 1494 "./src/main.am" if (!skipAm) { #line 1495 "./src/main.am" code_string amCsrc = code_string_concat(amObj, ".c"); #line 1496 "./src/main.am" code_string amcSelf = Amalgame_Compiler_Program_ResolveSelfPath(); #line 1497 "./src/main.am" code_string amcCmd = code_string_concat((code_string_concat((code_string_concat((code_string_concat("\"", amcSelf)), "\" --lib --quiet -o \"")), amObj)), "\""); #line 1498 "./src/main.am" i64 amCount = AmalgameList_count(amSources); #line 1499 "./src/main.am" for (i64 ai = 0LL; ai < amCount; ai++) { #line 1500 "./src/main.am" amcCmd = (code_string_concat((code_string_concat((code_string_concat(amcCmd, " \"")), (code_string)AmalgameList_get(amSources, ai))), "\"")); } #line 1502 "./src/main.am" AmalgameProcessResult* amcRes = Process_RunCapture(amcCmd); #line 1503 "./src/main.am" if (amcRes->Exit != 0LL) { #line 1504 "./src/main.am" Console_WriteError(code_string_concat("amc precompile: amc --lib failed for ", p->ClassName)); #line 1505 "./src/main.am" Console_WriteError(amcRes->Stdout); } else { #line 1507 "./src/main.am" code_string cmd = "gcc -O2"; #line 1508 "./src/main.am" if (String_Length(amcRuntime) > 0LL) { #line 1509 "./src/main.am" cmd = (code_string_concat((code_string_concat((code_string_concat(cmd, " -I\"")), amcRuntime)), "\"")); } #line 1517 "./src/main.am" code_string pkgRuntime = code_string_concat(p->PkgDir, "/runtime"); #line 1518 "./src/main.am" cmd = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(cmd, " -I\"")), pkgRuntime)), "\" -I\"")), p->PkgDir)), "\"")); #line 1527 "./src/main.am" AmalgameList* allCachedDirs = Amalgame_Compiler_AddCommand_AllCachedRuntimeDirs(); #line 1528 "./src/main.am" i64 acn = AmalgameList_count(allCachedDirs); #line 1529 "./src/main.am" for (i64 aci = 0LL; aci < acn; aci++) { #line 1530 "./src/main.am" cmd = (code_string_concat((code_string_concat((code_string_concat(cmd, " -I\"")), (code_string)AmalgameList_get(allCachedDirs, aci))), "\"")); } #line 1532 "./src/main.am" if (String_Length(p->CFlags) > 0LL) { #line 1533 "./src/main.am" cmd = (code_string_concat((code_string_concat(cmd, " ")), p->CFlags)); } #line 1535 "./src/main.am" cmd = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(cmd, " -w -c \"")), amCsrc)), "\" -o \"")), amObj)), "\"")); #line 1536 "./src/main.am" AmalgameProcessResult* gccRes = Process_RunCapture(cmd); #line 1537 "./src/main.am" if (gccRes->Exit != 0LL) { #line 1538 "./src/main.am" Console_WriteError(code_string_concat("amc precompile: gcc failed for ", p->ClassName)); #line 1539 "./src/main.am" Console_WriteError(gccRes->Stdout); } else { #line 1541 "./src/main.am" Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat("Pre-compiled ", p->ClassName)), " (")), String_FromInt(amCount))), " AM sources)")); #line 1542 "./src/main.am" AmalgameList_add(out, (void*)(intptr_t)(amObj)); } } } } #line 1549 "./src/main.am" i64 nn = AmalgameList_count(nativeSources); #line 1550 "./src/main.am" for (i64 j = 0LL; j < nn; j++) { #line 1551 "./src/main.am" code_string srcPath = (code_string)AmalgameList_get(nativeSources, j); #line 1552 "./src/main.am" i64 lastSlash = String_LastIndexOf(srcPath, "/"); #line 1553 "./src/main.am" code_string srcLeaf = srcPath; #line 1554 "./src/main.am" if (lastSlash >= 0LL) { #line 1555 "./src/main.am" srcLeaf = String_Substring(srcPath, lastSlash + 1LL, (String_Length(srcPath) - lastSlash) - 1LL); } #line 1557 "./src/main.am" code_string persistentObj = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(persistentDir, "/")), p->ClassName)), "-")), srcLeaf)), ".o"); #line 1558 "./src/main.am" if (File_Exists(persistentObj)) { #line 1559 "./src/main.am" AmalgameList_add(out, (void*)(intptr_t)(persistentObj)); #line 1560 "./src/main.am" continue; } #line 1562 "./src/main.am" code_string objPath = code_string_concat((code_string_concat((code_string_concat((code_string_concat("/tmp/amc-pkg-", p->ClassName)), "-")), srcLeaf)), ".o"); #line 1563 "./src/main.am" if (File_Exists(objPath)) { #line 1564 "./src/main.am" AmalgameList_add(out, (void*)(intptr_t)(objPath)); #line 1565 "./src/main.am" continue; } #line 1567 "./src/main.am" code_bool isCxx = Amalgame_Compiler_PackageRegistry_IsCxxSource(srcPath); #line 1568 "./src/main.am" code_string cmd = ""; #line 1569 "./src/main.am" if (isCxx) { #line 1570 "./src/main.am" cmd = "g++ -O2"; } else { #line 1572 "./src/main.am" cmd = "gcc -O2"; } #line 1574 "./src/main.am" if (String_Length(amcRuntime) > 0LL) { #line 1575 "./src/main.am" cmd = (code_string_concat((code_string_concat((code_string_concat(cmd, " -I\"")), amcRuntime)), "\"")); } #line 1579 "./src/main.am" AmalgameList* cachedNativeDirs = Amalgame_Compiler_AddCommand_AllCachedRuntimeDirs(); #line 1580 "./src/main.am" i64 cndN = AmalgameList_count(cachedNativeDirs); #line 1581 "./src/main.am" for (i64 cndI = 0LL; cndI < cndN; cndI++) { #line 1582 "./src/main.am" cmd = (code_string_concat((code_string_concat((code_string_concat(cmd, " -I\"")), (code_string)AmalgameList_get(cachedNativeDirs, cndI))), "\"")); } #line 1584 "./src/main.am" if (isCxx && (String_Length(p->CxxFlags) > 0LL)) { #line 1585 "./src/main.am" cmd = (code_string_concat((code_string_concat(cmd, " ")), p->CxxFlags)); } #line 1587 "./src/main.am" if (!isCxx && (String_Length(p->CFlags) > 0LL)) { #line 1588 "./src/main.am" cmd = (code_string_concat((code_string_concat(cmd, " ")), p->CFlags)); } #line 1590 "./src/main.am" cmd = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(cmd, " -w -c \"")), srcPath)), "\" -o \"")), objPath)), "\"")); #line 1591 "./src/main.am" AmalgameProcessResult* res = Process_RunCapture(cmd); #line 1592 "./src/main.am" if (res->Exit != 0LL) { #line 1593 "./src/main.am" Console_WriteError(code_string_concat("amc test: failed to pre-compile ", srcPath)); #line 1594 "./src/main.am" Console_WriteError(res->Stdout); #line 1595 "./src/main.am" continue; } #line 1597 "./src/main.am" Console_WriteLine(code_string_concat((code_string_concat((code_string_concat("Pre-compiled ", p->ClassName)), " source: ")), srcLeaf)); #line 1598 "./src/main.am" AmalgameList_add(out, (void*)(intptr_t)(objPath)); } } #line 1601 "./src/main.am" return out; } void Amalgame_Compiler_Program_PrintPackageSuggestionsForOutput(code_string output, code_string amcPath) { #line 1631 "./src/main.am" AmalgameList* lines = String_Split(output, "\n"); #line 1632 "./src/main.am" i64 n = AmalgameList_count(lines); #line 1633 "./src/main.am" code_string prefix = "Unknown symbol '"; #line 1634 "./src/main.am" i64 prefLen = String_Length(prefix); #line 1635 "./src/main.am" AmalgameList* seen = AmalgameList_new(); #line 1636 "./src/main.am" code_bool headerPrinted = 0; #line 1637 "./src/main.am" code_string cmd = "amc"; #line 1638 "./src/main.am" if (String_Length(amcPath) > 0LL) { cmd = amcPath; } #line 1639 "./src/main.am" for (i64 li = 0LL; li < n; li++) { #line 1640 "./src/main.am" code_string line = (code_string)AmalgameList_get(lines, li); #line 1641 "./src/main.am" i64 idx = String_IndexOf(line, prefix); #line 1642 "./src/main.am" if (idx < 0LL) { continue; } #line 1643 "./src/main.am" i64 restLen = (String_Length(line) - idx) - prefLen; #line 1644 "./src/main.am" if (restLen <= 0LL) { continue; } #line 1645 "./src/main.am" code_string rest = String_Substring(line, idx + prefLen, restLen); #line 1646 "./src/main.am" i64 endQuote = String_IndexOf(rest, "'"); #line 1647 "./src/main.am" if (endQuote <= 0LL) { continue; } #line 1648 "./src/main.am" code_string symName = String_Substring(rest, 0LL, endQuote); #line 1649 "./src/main.am" if ((code_string_equals(symName, "_")) || (code_string_equals(symName, "_unknown_"))) { continue; } #line 1651 "./src/main.am" i64 ns = AmalgameList_count(seen); #line 1652 "./src/main.am" code_bool dup = 0; #line 1653 "./src/main.am" for (i64 si = 0LL; si < ns; si++) { #line 1654 "./src/main.am" if (code_string_equals((code_string)AmalgameList_get(seen, si), symName)) { dup = 1; } } #line 1656 "./src/main.am" if (dup) { continue; } #line 1657 "./src/main.am" AmalgameList_add(seen, (void*)(intptr_t)(symName)); #line 1658 "./src/main.am" AmalgameProcessResult* result = Process_RunCapture(code_string_concat((code_string_concat(cmd, " package suggest --json ")), symName)); #line 1659 "./src/main.am" if (result->Exit != 0LL) { continue; } #line 1660 "./src/main.am" code_string trimmed = String_Trim(result->Stdout); #line 1661 "./src/main.am" if ((String_Length(trimmed) == 0LL) || (code_string_equals(trimmed, "[]"))) { continue; } #line 1662 "./src/main.am" Amalgame_Compiler_JsonResult* parsed = Amalgame_Compiler_Json_Parse(trimmed); #line 1663 "./src/main.am" if (!parsed->Ok) { continue; } #line 1664 "./src/main.am" Amalgame_Compiler_JsonValue* doc = parsed->Value; #line 1665 "./src/main.am" if (Amalgame_Compiler_JsonValue_IsNull(doc) || !Amalgame_Compiler_JsonValue_IsArray(doc)) { continue; } #line 1666 "./src/main.am" AmalgameList* arr = Amalgame_Compiler_JsonValue_AsArray(doc); #line 1667 "./src/main.am" i64 nr = AmalgameList_count(arr); #line 1668 "./src/main.am" if (nr == 0LL) { continue; } #line 1669 "./src/main.am" if (!headerPrinted) { #line 1670 "./src/main.am" Console_WriteLine(""); #line 1671 "./src/main.am" Console_WriteLine("hint: unresolved symbols match curated packages — install via:"); #line 1672 "./src/main.am" headerPrinted = 1; } #line 1674 "./src/main.am" Console_WriteLine(code_string_concat((code_string_concat(" '", symName)), "':")); #line 1675 "./src/main.am" for (i64 ri = 0LL; ri < nr; ri++) { #line 1676 "./src/main.am" Amalgame_Compiler_JsonValue* entry = (Amalgame_Compiler_JsonValue*)AmalgameList_get(arr, ri); #line 1677 "./src/main.am" code_string pn = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(entry, "name")); #line 1678 "./src/main.am" code_string pt = Amalgame_Compiler_JsonValue_AsString(Amalgame_Compiler_JsonValue_Get(entry, "latest_compatible_tag")); #line 1679 "./src/main.am" code_string hintLine = code_string_concat(" amc package add ", pn); #line 1680 "./src/main.am" if (String_Length(pt) > 0LL) { hintLine = (code_string_concat((code_string_concat(hintLine, "@")), pt)); } #line 1681 "./src/main.am" Console_WriteLine(hintLine); } } } static code_string Amalgame_Compiler_Program_TomlRawValue(AmalgameList* lines, code_string key) { #line 1689 "./src/main.am" i64 n = AmalgameList_count(lines); #line 1690 "./src/main.am" for (i64 i = 0LL; i < n; i++) { #line 1691 "./src/main.am" code_string t = String_TrimStart((code_string)AmalgameList_get(lines, i)); #line 1692 "./src/main.am" if (String_StartsWith(t, "#")) { continue; } #line 1693 "./src/main.am" if (String_StartsWith(t, key)) { #line 1694 "./src/main.am" code_string after = String_TrimStart(String_From(t, String_Length(key))); #line 1695 "./src/main.am" if (String_StartsWith(after, "=")) { #line 1696 "./src/main.am" return String_Trim(String_From(after, 1LL)); } } } #line 1700 "./src/main.am" return ""; } static code_string Amalgame_Compiler_Program_TomlScalar(AmalgameList* lines, code_string key) { #line 1705 "./src/main.am" code_string v = Amalgame_Compiler_Program_TomlRawValue(lines, key); #line 1706 "./src/main.am" i64 n = String_Length(v); #line 1707 "./src/main.am" if (((n >= 2LL) && String_StartsWith(v, "\"")) && String_EndsWith(v, "\"")) { #line 1708 "./src/main.am" v = String_Substring(v, 1LL, n - 2LL); } #line 1710 "./src/main.am" return v; } static AmalgameList* Amalgame_Compiler_Program_TomlArray(AmalgameList* lines, code_string key) { #line 1713 "./src/main.am" AmalgameList* out = AmalgameList_new(); #line 1714 "./src/main.am" code_string raw = Amalgame_Compiler_Program_TomlRawValue(lines, key); #line 1715 "./src/main.am" if (String_Length(raw) == 0LL) { return out; } #line 1716 "./src/main.am" raw = String_Replace(raw, "[", ""); #line 1717 "./src/main.am" raw = String_Replace(raw, "]", ""); #line 1718 "./src/main.am" raw = String_Replace(raw, "\"", ""); #line 1719 "./src/main.am" AmalgameList* parts = String_Split(raw, ","); #line 1720 "./src/main.am" i64 pn = AmalgameList_count(parts); #line 1721 "./src/main.am" for (i64 i = 0LL; i < pn; i++) { #line 1722 "./src/main.am" code_string v = String_Trim((code_string)AmalgameList_get(parts, i)); #line 1723 "./src/main.am" if (String_Length(v) > 0LL) { AmalgameList_add(out, (void*)(intptr_t)(v)); } } #line 1725 "./src/main.am" return out; } static code_string Amalgame_Compiler_Program_EnvDirFlags(code_string envName, code_string flag) { #line 1729 "./src/main.am" code_string v = Env_Get(envName); #line 1730 "./src/main.am" if (String_Length(v) == 0LL) { return ""; } #line 1731 "./src/main.am" code_string s = ""; #line 1732 "./src/main.am" AmalgameList* parts = String_Split(v, ":"); #line 1733 "./src/main.am" i64 pn = AmalgameList_count(parts); #line 1734 "./src/main.am" for (i64 i = 0LL; i < pn; i++) { #line 1735 "./src/main.am" code_string d = String_Trim((code_string)AmalgameList_get(parts, i)); #line 1736 "./src/main.am" if (String_Length(d) > 0LL) { s = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(s, " ")), flag)), "\"")), d)), "\"")); } } #line 1738 "./src/main.am" return s; } i64 Amalgame_Compiler_Program_LinkEmbedded(code_string target, code_string outC, code_string outBin, code_string amcRuntime, code_string boardPath, code_bool verbose, code_bool debug) { #line 1755 "./src/main.am" code_string embDir = code_string_concat(amcRuntime, "/embedded"); #line 1756 "./src/main.am" code_string startup = ""; #line 1757 "./src/main.am" code_string ld = ""; #line 1758 "./src/main.am" code_string cpu = Amalgame_Compiler_Program_TargetCpuFlags(target); #line 1759 "./src/main.am" AmalgameList* defines = AmalgameList_new(); #line 1760 "./src/main.am" AmalgameList* libs = AmalgameList_new(); #line 1761 "./src/main.am" code_string incBoard = code_string_concat((code_string_concat(" -I\"", embDir)), "\""); #line 1763 "./src/main.am" if (String_Length(boardPath) > 0LL) { #line 1765 "./src/main.am" code_string manifest = code_string_concat(boardPath, "/amalgame.toml"); #line 1766 "./src/main.am" if (!File_Exists(manifest)) { #line 1767 "./src/main.am" Console_WriteError(code_string_concat("amc build --board: no amalgame.toml at ", boardPath)); #line 1768 "./src/main.am" return 1LL; } #line 1770 "./src/main.am" AmalgameList* mlines = String_Split(File_ReadAll(manifest), "\n"); #line 1771 "./src/main.am" startup = (code_string_concat(boardPath, "/boards/startup.c")); #line 1772 "./src/main.am" code_string linkerRel = Amalgame_Compiler_Program_TomlScalar(mlines, "linker"); #line 1773 "./src/main.am" if (String_Length(linkerRel) == 0LL) { #line 1774 "./src/main.am" Console_WriteError(code_string_concat("amc build --board: [target].linker missing in ", manifest)); #line 1775 "./src/main.am" return 1LL; } #line 1777 "./src/main.am" ld = (code_string_concat((code_string_concat(boardPath, "/")), linkerRel)); #line 1778 "./src/main.am" code_string cf = Amalgame_Compiler_Program_TomlScalar(mlines, "cpu_flags"); #line 1779 "./src/main.am" if (String_Length(cf) > 0LL) { cpu = cf; } #line 1780 "./src/main.am" defines = Amalgame_Compiler_Program_TomlArray(mlines, "defines"); #line 1781 "./src/main.am" libs = Amalgame_Compiler_Program_TomlArray(mlines, "libs"); #line 1782 "./src/main.am" incBoard = (code_string_concat((code_string_concat((code_string_concat(incBoard, " -I\"")), boardPath)), "/runtime\"")); #line 1783 "./src/main.am" code_string embInc = Amalgame_Compiler_Program_EnvDirFlags("AMC_EMBED_INC", "-I"); #line 1784 "./src/main.am" if (String_Length(embInc) == 0LL) { #line 1787 "./src/main.am" code_string home = Env_Get("HOME"); #line 1788 "./src/main.am" if ((String_Length(home) > 0LL) && File_Exists(code_string_concat(home, "/libopencm3/include"))) { #line 1789 "./src/main.am" embInc = (code_string_concat((code_string_concat(" -I\"", home)), "/libopencm3/include\"")); } } #line 1792 "./src/main.am" incBoard = (code_string_concat(incBoard, embInc)); #line 1797 "./src/main.am" code_string hdr = Amalgame_Compiler_Program_TomlScalar(mlines, "header"); #line 1798 "./src/main.am" if (String_Length(hdr) > 0LL) { #line 1799 "./src/main.am" code_string base = hdr; #line 1800 "./src/main.am" i64 sl = String_LastIndexOf(hdr, "/"); #line 1801 "./src/main.am" if (sl >= 0LL) { base = String_Substring(hdr, sl + 1LL, (String_Length(hdr) - sl) - 1LL); } #line 1802 "./src/main.am" incBoard = (code_string_concat((code_string_concat((code_string_concat(incBoard, " -DAMC_BOARD_HEADER='\"")), base)), "\"'")); } } else { #line 1809 "./src/main.am" code_string board = ""; #line 1810 "./src/main.am" if (code_string_equals(target, "cortex-m3")) { board = "qemu-lm3s6965"; } #line 1811 "./src/main.am" if (code_string_equals(target, "esp32s3")) { board = "esp32s3-ramload"; } #line 1812 "./src/main.am" if (String_Length(board) == 0LL) { #line 1813 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat("amc build --target=", target)), ": no bundled board asset.")); #line 1814 "./src/main.am" Console_WriteError(" cortex-m3 ships the QEMU lm3s6965 board; esp32s3 ships a"); #line 1815 "./src/main.am" Console_WriteError(" RAM-loaded board; for other targets pass --board=."); #line 1816 "./src/main.am" return 1LL; } #line 1818 "./src/main.am" code_string boardDir = code_string_concat((code_string_concat(embDir, "/boards/")), board); #line 1819 "./src/main.am" startup = (code_string_concat(boardDir, "/startup.c")); #line 1820 "./src/main.am" ld = (code_string_concat(boardDir, "/board.ld")); } #line 1822 "./src/main.am" if (!File_Exists(startup) || !File_Exists(ld)) { #line 1823 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat("amc build: board startup/linker missing (", startup)), " / ")), ld)), ")")); #line 1824 "./src/main.am" return 1LL; } #line 1831 "./src/main.am" code_string extraSrc = ""; #line 1832 "./src/main.am" i64 sdir = String_LastIndexOf(startup, "/"); #line 1833 "./src/main.am" if (sdir >= 0LL) { #line 1834 "./src/main.am" code_string bdir = String_Substring(startup, 0LL, sdir); #line 1835 "./src/main.am" AmalgameList* cands = AmalgameList_new(); #line 1836 "./src/main.am" AmalgameList_add(cands, (void*)(intptr_t)("vectors.S")); #line 1837 "./src/main.am" AmalgameList_add(cands, (void*)(intptr_t)("interrupts.c")); #line 1838 "./src/main.am" AmalgameList_add(cands, (void*)(intptr_t)("heap.c")); #line 1839 "./src/main.am" i64 cn = AmalgameList_count(cands); #line 1840 "./src/main.am" for (i64 ci = 0LL; ci < cn; ci++) { #line 1841 "./src/main.am" code_string f = code_string_concat((code_string_concat(bdir, "/")), (code_string)AmalgameList_get(cands, ci)); #line 1842 "./src/main.am" if (File_Exists(f)) { extraSrc = (code_string_concat((code_string_concat((code_string_concat(extraSrc, " \"")), f)), "\"")); } } } #line 1846 "./src/main.am" code_string cc = Amalgame_Compiler_Program_TargetCC(target); #line 1847 "./src/main.am" code_string ccHint = "sudo apt install gcc-arm-none-eabi (Debian/Ubuntu)"; #line 1848 "./src/main.am" if (Amalgame_Compiler_Program_TargetIsXtensa(target)) { #line 1849 "./src/main.am" ccHint = "install the ESP-IDF Xtensa toolchain (xtensa-esp32s3-elf-gcc), e.g. via esp-idf or PlatformIO; put its bin/ on PATH"; } #line 1851 "./src/main.am" if (!Amalgame_Compiler_Program_RequireTool(cc, ccHint)) { #line 1852 "./src/main.am" return 1LL; } #line 1854 "./src/main.am" code_string optFlag = "-Os"; #line 1855 "./src/main.am" if (debug) { optFlag = "-O0 -g"; } #line 1856 "./src/main.am" code_string cmd = code_string_concat((code_string_concat((code_string_concat((code_string_concat(cc, " ")), cpu)), " ")), optFlag); #line 1857 "./src/main.am" cmd = (code_string_concat(cmd, " -ffreestanding -nostartfiles -ffunction-sections -fdata-sections -Wl,--gc-sections")); #line 1858 "./src/main.am" i64 dn = AmalgameList_count(defines); #line 1859 "./src/main.am" for (i64 di = 0LL; di < dn; di++) { cmd = (code_string_concat((code_string_concat(cmd, " -D")), (code_string)AmalgameList_get(defines, di))); } #line 1860 "./src/main.am" cmd = (code_string_concat(cmd, incBoard)); #line 1861 "./src/main.am" cmd = (code_string_concat((code_string_concat((code_string_concat(cmd, " -T \"")), ld)), "\"")); #line 1862 "./src/main.am" cmd = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(cmd, " \"")), startup)), "\"")), extraSrc)), " \"")), outC)), "\"")); #line 1863 "./src/main.am" code_string embLib = Amalgame_Compiler_Program_EnvDirFlags("AMC_EMBED_LIB", "-L"); #line 1864 "./src/main.am" if (String_Length(embLib) == 0LL) { #line 1865 "./src/main.am" code_string homeL = Env_Get("HOME"); #line 1866 "./src/main.am" if ((String_Length(homeL) > 0LL) && File_Exists(code_string_concat(homeL, "/libopencm3/lib"))) { #line 1867 "./src/main.am" embLib = (code_string_concat((code_string_concat(" -L\"", homeL)), "/libopencm3/lib\"")); } } #line 1870 "./src/main.am" cmd = (code_string_concat(cmd, embLib)); #line 1871 "./src/main.am" i64 ln = AmalgameList_count(libs); #line 1872 "./src/main.am" for (i64 li = 0LL; li < ln; li++) { cmd = (code_string_concat((code_string_concat(cmd, " -l")), (code_string)AmalgameList_get(libs, li))); } #line 1873 "./src/main.am" cmd = (code_string_concat((code_string_concat((code_string_concat(cmd, " -o \"")), outBin)), "\" 2>&1")); #line 1874 "./src/main.am" if (verbose) { Console_WriteLine(code_string_concat((code_string_concat((code_string_concat(" ", cc)), ": ")), cmd)); } #line 1875 "./src/main.am" AmalgameProcessResult* r = Process_RunCapture(cmd); #line 1876 "./src/main.am" if (r->Exit != 0LL) { #line 1877 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat((code_string_concat(" [LINK-FAIL] ", cc)), " exited ")), String_FromInt(r->Exit))); #line 1878 "./src/main.am" Console_Write(r->Stdout); #line 1879 "./src/main.am" return 1LL; } #line 1886 "./src/main.am" if (Amalgame_Compiler_Program_TargetIsXtensa(target)) { #line 1887 "./src/main.am" if (!Amalgame_Compiler_Program_RequireTool("esptool", "pip install esptool (or use the ESP-IDF / PlatformIO copy)")) { #line 1888 "./src/main.am" return 1LL; } #line 1890 "./src/main.am" code_string img = code_string_concat(outBin, ".bin"); #line 1891 "./src/main.am" AmalgameProcessResult* elf2 = Process_RunCapture(code_string_concat((code_string_concat((code_string_concat((code_string_concat("esptool --chip esp32s3 elf2image --flash_mode dio --flash_freq 80m --flash_size 2MB -o \"", img)), "\" \"")), outBin)), "\" 2>&1")); #line 1894 "./src/main.am" if (elf2->Exit != 0LL) { #line 1895 "./src/main.am" Console_WriteError(code_string_concat(" [IMAGE-FAIL] esptool elf2image exited ", String_FromInt(elf2->Exit))); #line 1896 "./src/main.am" Console_Write(elf2->Stdout); #line 1897 "./src/main.am" return 1LL; } #line 1899 "./src/main.am" if (verbose) { Console_Write(elf2->Stdout); } #line 1900 "./src/main.am" Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat(" image: ", img)), " (flash with: esptool --chip esp32s3 write_flash 0x0 ")), img)), ")")); } else { #line 1903 "./src/main.am" code_string oc = Amalgame_Compiler_Program_TargetObjcopy(target); #line 1904 "./src/main.am" AmalgameProcessResult* cBin = Process_RunCapture(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(oc, " -O binary \"")), outBin)), "\" \"")), outBin)), ".bin\" 2>&1")); #line 1905 "./src/main.am" if (cBin->Exit != 0LL) { Console_Write(cBin->Stdout); } #line 1906 "./src/main.am" AmalgameProcessResult* cHex = Process_RunCapture(code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(oc, " -O ihex \"")), outBin)), "\" \"")), outBin)), ".hex\" 2>&1")); #line 1907 "./src/main.am" if (cHex->Exit != 0LL) { Console_Write(cHex->Stdout); } } #line 1909 "./src/main.am" if (verbose) { #line 1910 "./src/main.am" AmalgameProcessResult* sz = Process_RunCapture(code_string_concat((code_string_concat((code_string_concat(Amalgame_Compiler_Program_TargetSize(target), " \"")), outBin)), "\" 2>&1")); #line 1911 "./src/main.am" Console_Write(sz->Stdout); } #line 1913 "./src/main.am" return 0LL; } code_bool Amalgame_Compiler_Program_RequireTool(code_string tool, code_string hint) { #line 1921 "./src/main.am" AmalgameProcessResult* p = Process_RunCapture(code_string_concat((code_string_concat("command -v '", tool)), "' 2>/dev/null")); #line 1922 "./src/main.am" if ((p->Exit == 0LL) && (String_Length(String_Trim(p->Stdout)) > 0LL)) { return 1; } #line 1923 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat("amc: required tool '", tool)), "' not found on PATH.")); #line 1924 "./src/main.am" Console_WriteError(code_string_concat(" install: ", hint)); #line 1925 "./src/main.am" Console_WriteError(" or run: tools/mcu-setup.sh (installs the full MCU toolchain)"); #line 1926 "./src/main.am" return 0; } i64 Amalgame_Compiler_Program_FlashEmbedded(code_string boardPath, code_string outBin) { #line 1934 "./src/main.am" if (String_Length(boardPath) == 0LL) { #line 1935 "./src/main.am" Console_WriteError("amc build --flash: needs --board= declaring [target].flash_cmd"); #line 1936 "./src/main.am" return 1LL; } #line 1938 "./src/main.am" code_string manifest = code_string_concat(boardPath, "/amalgame.toml"); #line 1939 "./src/main.am" if (!File_Exists(manifest)) { #line 1940 "./src/main.am" Console_WriteError(code_string_concat("amc build --flash: no amalgame.toml at ", boardPath)); #line 1941 "./src/main.am" return 1LL; } #line 1943 "./src/main.am" AmalgameList* lines = String_Split(File_ReadAll(manifest), "\n"); #line 1944 "./src/main.am" code_string cmd = ""; #line 1945 "./src/main.am" code_string tool = Amalgame_Compiler_Program_TomlScalar(lines, "flash_tool"); #line 1946 "./src/main.am" if (code_string_equals(tool, "openocd")) { #line 1947 "./src/main.am" if (!Amalgame_Compiler_Program_RequireTool("openocd", "sudo apt install openocd")) { return 1LL; } #line 1950 "./src/main.am" code_string cfg = Amalgame_Compiler_Program_TomlScalar(lines, "openocd_cfg"); #line 1951 "./src/main.am" code_string addr = Amalgame_Compiler_Program_TomlScalar(lines, "flash_addr"); #line 1952 "./src/main.am" if (String_Length(addr) == 0LL) { addr = "0x08000000"; } #line 1953 "./src/main.am" cmd = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("openocd -f ", cfg)), " -c \"program ")), outBin)), ".bin ")), addr)), " verify reset exit\"")); } else { #line 1958 "./src/main.am" cmd = Amalgame_Compiler_Program_TomlScalar(lines, "flash_cmd"); #line 1959 "./src/main.am" if (String_Length(cmd) == 0LL) { #line 1960 "./src/main.am" Console_WriteError(code_string_concat("amc build --flash: no [target].flash_tool/flash_cmd in ", manifest)); #line 1961 "./src/main.am" return 1LL; } #line 1963 "./src/main.am" cmd = String_Replace(cmd, code_string_concat("{", "bin}"), code_string_concat(outBin, ".bin")); #line 1964 "./src/main.am" cmd = String_Replace(cmd, code_string_concat("{", "elf}"), outBin); #line 1965 "./src/main.am" cmd = String_Replace(cmd, code_string_concat("{", "hex}"), code_string_concat(outBin, ".hex")); } #line 1967 "./src/main.am" Console_WriteLine(code_string_concat(" flash: ", cmd)); #line 1968 "./src/main.am" AmalgameProcessResult* r = Process_RunCapture(code_string_concat(cmd, " 2>&1")); #line 1969 "./src/main.am" Console_Write(r->Stdout); #line 1970 "./src/main.am" if (r->Exit != 0LL) { #line 1971 "./src/main.am" Console_WriteError(code_string_concat(" [FLASH-FAIL] flasher exited ", String_FromInt(r->Exit))); #line 1972 "./src/main.am" return 1LL; } #line 1974 "./src/main.am" Console_WriteLine(code_string_concat((code_string_concat("✓ Flashed ", outBin)), ".bin")); #line 1975 "./src/main.am" return 0LL; } i64 Amalgame_Compiler_Program_RunMonitor(i64 argc) { #line 1984 "./src/main.am" code_string port = "/dev/ttyACM0"; #line 1985 "./src/main.am" code_string baud = "115200"; #line 1986 "./src/main.am" i64 i = 2LL; #line 1987 "./src/main.am" while (i < argc) { #line 1988 "./src/main.am" code_string a = Args_Get(i); #line 1989 "./src/main.am" if (((code_string_equals(a, "--port")) || (code_string_equals(a, "-p"))) && ((i + 1LL) < argc)) { #line 1990 "./src/main.am" i = (i + 1LL); #line 1991 "./src/main.am" port = Args_Get(i); } else if (((code_string_equals(a, "--baud")) || (code_string_equals(a, "-b"))) && ((i + 1LL) < argc)) { #line 1993 "./src/main.am" i = (i + 1LL); #line 1994 "./src/main.am" baud = Args_Get(i); } else if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) { #line 1996 "./src/main.am" Console_WriteError("Usage: amc monitor [--port /dev/ttyACM0] [--baud 115200]"); #line 1997 "./src/main.am" Console_WriteError(" Stream a serial port (board UART / ST-LINK VCP) to the terminal."); #line 1998 "./src/main.am" return 0LL; } #line 2000 "./src/main.am" i = (i + 1LL); } #line 2002 "./src/main.am" if (!File_Exists(port)) { #line 2003 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat("amc monitor: serial port '", port)), "' not found")); #line 2004 "./src/main.am" Console_WriteError(" plug the board in (Nucleo ST-LINK VCP is usually /dev/ttyACM0),"); #line 2005 "./src/main.am" Console_WriteError(" or pass --port . List with: ls /dev/ttyACM* /dev/ttyUSB*"); #line 2006 "./src/main.am" return 1LL; } #line 2008 "./src/main.am" Console_WriteLine(code_string_concat((code_string_concat((code_string_concat((code_string_concat("amc monitor: ", port)), " @ ")), baud)), " baud (Ctrl-C to stop)")); #line 2009 "./src/main.am" code_string cmd = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat("stty -F '", port)), "' ")), baud)), " raw -echo 2>/dev/null; exec cat '")), port)), "'"); #line 2010 "./src/main.am" i64 rc = Process_Run(cmd); #line 2011 "./src/main.am" return rc; } i64 Amalgame_Compiler_Program_BuildOneBinary(code_string amcPath, code_string entryAm, code_string outBin, code_string amcRuntime, code_string libamalgameA, AmalgameList* pkgObjs, AmalgameList* facadeArs, AmalgameList* pkgLibs, code_bool hasCxx, code_bool verbose, code_bool debug, code_string target, code_string board) { #line 2029 "./src/main.am" code_string outC = code_string_concat(outBin, ".c"); #line 2030 "./src/main.am" code_string quietFlag = " --quiet"; #line 2031 "./src/main.am" if (verbose) { quietFlag = " --verbose"; } #line 2034 "./src/main.am" code_string targetFlag = ""; #line 2035 "./src/main.am" if (String_Length(target) > 0LL) { targetFlag = (code_string_concat(" --target=", target)); } #line 2036 "./src/main.am" code_string amcCmd = code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(amcPath, " ")), entryAm)), " -o ")), outBin)), quietFlag)), targetFlag); #line 2037 "./src/main.am" AmalgameProcessResult* cr = Process_RunCapture(amcCmd); #line 2038 "./src/main.am" if (cr->Exit != 0LL) { #line 2039 "./src/main.am" Console_WriteError(code_string_concat(" [COMPILE-FAIL] amc exited ", String_FromInt(cr->Exit))); #line 2040 "./src/main.am" Console_Write(cr->Stdout); #line 2041 "./src/main.am" Amalgame_Compiler_Program_PrintPackageSuggestionsForOutput(cr->Stdout, amcPath); #line 2042 "./src/main.am" return 1LL; } #line 2044 "./src/main.am" if (verbose) { #line 2045 "./src/main.am" Console_WriteLine(code_string_concat(" amc → ", outC)); } #line 2051 "./src/main.am" if (String_Length(target) > 0LL) { #line 2052 "./src/main.am" return Amalgame_Compiler_Program_LinkEmbedded(target, outC, outBin, amcRuntime, board, verbose, debug); } #line 2059 "./src/main.am" code_string optFlag = "-O2"; #line 2060 "./src/main.am" if (debug) { optFlag = "-O0 -g"; } #line 2063 "./src/main.am" AmalgameList* pkgIncDirs2 = Amalgame_Compiler_AddCommand_AllCachedRuntimeDirs(); #line 2064 "./src/main.am" i64 pkgIncN2 = AmalgameList_count(pkgIncDirs2); #line 2065 "./src/main.am" code_string pkgIncFlags2 = ""; #line 2066 "./src/main.am" for (i64 pi2 = 0LL; pi2 < pkgIncN2; pi2++) { #line 2067 "./src/main.am" pkgIncFlags2 = (code_string_concat((code_string_concat((code_string_concat(pkgIncFlags2, " -I\"")), (code_string)AmalgameList_get(pkgIncDirs2, pi2))), "\"")); } #line 2069 "./src/main.am" code_string gccCmd = ""; #line 2070 "./src/main.am" if (hasCxx) { #line 2076 "./src/main.am" code_string compileCmd = code_string_concat((code_string_concat("gcc ", optFlag)), " -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Iruntime"); #line 2077 "./src/main.am" if (String_Length(amcRuntime) > 0LL) { #line 2078 "./src/main.am" compileCmd = (code_string_concat((code_string_concat((code_string_concat(compileCmd, " -I\"")), amcRuntime)), "\"")); } #line 2080 "./src/main.am" compileCmd = (code_string_concat(compileCmd, pkgIncFlags2)); #line 2081 "./src/main.am" code_string objOut = code_string_concat(outBin, ".o"); #line 2082 "./src/main.am" compileCmd = (code_string_concat((code_string_concat((code_string_concat((code_string_concat((code_string_concat(compileCmd, " -c ")), outC)), " -o ")), objOut)), " 2>&1")); #line 2083 "./src/main.am" AmalgameProcessResult* stageA = Process_RunCapture(compileCmd); #line 2084 "./src/main.am" if (stageA->Exit != 0LL) { #line 2085 "./src/main.am" Console_WriteError(code_string_concat(" [LINK-FAIL] gcc -c exited ", String_FromInt(stageA->Exit))); #line 2086 "./src/main.am" Console_Write(stageA->Stdout); #line 2087 "./src/main.am" return 1LL; } #line 2089 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat("g++ ", optFlag)), " ")), objOut)); } else { #line 2091 "./src/main.am" gccCmd = (code_string_concat((code_string_concat("gcc ", optFlag)), " -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Iruntime")); #line 2092 "./src/main.am" if (String_Length(amcRuntime) > 0LL) { #line 2093 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, " -I\"")), amcRuntime)), "\"")); } #line 2095 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, pkgIncFlags2)), " ")), outC)); } #line 2098 "./src/main.am" i64 nObjs = AmalgameList_count(pkgObjs); #line 2099 "./src/main.am" for (i64 poi = 0LL; poi < nObjs; poi++) { #line 2100 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, " \"")), (code_string)AmalgameList_get(pkgObjs, poi))), "\"")); } #line 2103 "./src/main.am" i64 nFAr = AmalgameList_count(facadeArs); #line 2104 "./src/main.am" for (i64 fai = 0LL; fai < nFAr; fai++) { #line 2105 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, " \"")), (code_string)AmalgameList_get(facadeArs, fai))), "\"")); } #line 2113 "./src/main.am" if (String_Length(libamalgameA) > 0LL) { #line 2114 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, " \"")), libamalgameA)), "\"")); } #line 2116 "./src/main.am" gccCmd = (code_string_concat(gccCmd, " -lgc -lm -lz -lpthread")); #line 2117 "./src/main.am" if (!Amalgame_Compiler_Program_IsWindows()) { gccCmd = (code_string_concat(gccCmd, " -ldl")); } #line 2118 "./src/main.am" i64 nLibs = AmalgameList_count(pkgLibs); #line 2119 "./src/main.am" for (i64 plj = 0LL; plj < nLibs; plj++) { #line 2120 "./src/main.am" gccCmd = (code_string_concat((code_string_concat(gccCmd, " -l")), (code_string)AmalgameList_get(pkgLibs, plj))); } #line 2122 "./src/main.am" gccCmd = (code_string_concat((code_string_concat((code_string_concat(gccCmd, " -o ")), outBin)), " 2>&1")); #line 2123 "./src/main.am" if (verbose) { #line 2124 "./src/main.am" Console_WriteLine(code_string_concat(" gcc: ", gccCmd)); } #line 2126 "./src/main.am" AmalgameProcessResult* gcc = Process_RunCapture(gccCmd); #line 2127 "./src/main.am" if (gcc->Exit != 0LL) { #line 2128 "./src/main.am" Console_WriteError(code_string_concat(" [LINK-FAIL] gcc exited ", String_FromInt(gcc->Exit))); #line 2129 "./src/main.am" Console_Write(gcc->Stdout); #line 2130 "./src/main.am" return 1LL; } #line 2132 "./src/main.am" return 0LL; } i64 Amalgame_Compiler_Program_BuildEntry(code_string entryAm, code_string outBin, code_bool verbose, code_bool debug, code_string target, code_string board) { #line 2141 "./src/main.am" if (!File_Exists(entryAm)) { #line 2142 "./src/main.am" Console_WriteError(code_string_concat("amc build: entry file not found: ", entryAm)); #line 2143 "./src/main.am" return 2LL; } #line 2148 "./src/main.am" Amalgame_Compiler_Telemetry_Ping(); #line 2156 "./src/main.am" code_string amcPath = Amalgame_Compiler_Program_ResolveSelfPath(); #line 2157 "./src/main.am" if (String_Length(amcPath) == 0LL) { #line 2158 "./src/main.am" amcPath = Args_Get(0LL); } #line 2160 "./src/main.am" code_string amcRuntime = Amalgame_Compiler_Program_ResolveRuntimeDir(amcPath); #line 2167 "./src/main.am" code_string libamalgameA = ""; #line 2168 "./src/main.am" AmalgameList* pkgObjs = AmalgameList_new(); #line 2169 "./src/main.am" AmalgameList* pkgLibs = AmalgameList_new(); #line 2170 "./src/main.am" AmalgameList* facadeArs = AmalgameList_new(); #line 2171 "./src/main.am" code_bool hasCxx = 0; #line 2172 "./src/main.am" if (String_Length(target) == 0LL) { #line 2174 "./src/main.am" i64 installed = Amalgame_Compiler_AddCommand_EnsureInstalled(); #line 2175 "./src/main.am" if (installed < 0LL) { #line 2176 "./src/main.am" Console_WriteError("amc build: package install failed; aborting"); #line 2177 "./src/main.am" return 1LL; } #line 2179 "./src/main.am" if ((installed > 0LL) && verbose) { #line 2180 "./src/main.am" Console_WriteLine(code_string_concat((code_string_concat("amc build: installed ", String_FromInt(installed))), " missing dep(s)")); } #line 2182 "./src/main.am" libamalgameA = Amalgame_Compiler_Program_ResolveLibAmalgameA(amcPath); #line 2183 "./src/main.am" Amalgame_Compiler_PackageRegistry* registry = Amalgame_Compiler_PackageRegistry_Load(); #line 2184 "./src/main.am" pkgObjs = Amalgame_Compiler_Program_PreCompilePackageSources(registry, amcRuntime); #line 2185 "./src/main.am" hasCxx = Amalgame_Compiler_PackageRegistry_HasCxxSources(registry); #line 2186 "./src/main.am" pkgLibs = Amalgame_Compiler_PackageRegistry_CollectLibs(registry); #line 2187 "./src/main.am" facadeArs = Amalgame_Compiler_PackageRegistry_CollectFacadeArchives(registry); } #line 2190 "./src/main.am" i64 rc = Amalgame_Compiler_Program_BuildOneBinary(amcPath, entryAm, outBin, amcRuntime, libamalgameA, pkgObjs, facadeArs, pkgLibs, hasCxx, verbose, debug, target, board); #line 2194 "./src/main.am" return rc; } i64 Amalgame_Compiler_Program_RunBuild(i64 argc) { #line 2205 "./src/main.am" code_string entryAm = ""; #line 2206 "./src/main.am" code_string outBin = ""; #line 2207 "./src/main.am" code_bool verbose = 0; #line 2208 "./src/main.am" code_bool debug = 0; #line 2209 "./src/main.am" code_string target = ""; #line 2210 "./src/main.am" code_string board = ""; #line 2211 "./src/main.am" code_bool flash = 0; #line 2212 "./src/main.am" i64 i = 2LL; #line 2213 "./src/main.am" while (i < argc) { #line 2214 "./src/main.am" code_string a = Args_Get(i); #line 2215 "./src/main.am" if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) { #line 2216 "./src/main.am" Console_WriteError("Usage: amc build [-o ] [-g|--debug] [--target=] [--verbose] "); #line 2217 "./src/main.am" Console_WriteError(""); #line 2218 "./src/main.am" Console_WriteError("Compile + link a runnable binary in one step."); #line 2219 "./src/main.am" Console_WriteError("Equivalent to `amc -o out entry.am` plus the gcc invocation"); #line 2220 "./src/main.am" Console_WriteError("(runtime headers, libamalgame.a, installed packages, libs)."); #line 2221 "./src/main.am" Console_WriteError(""); #line 2222 "./src/main.am" Console_WriteError(" -g, --debug swap -O2 for -O0 -g (DWARF for amc dap)"); #line 2223 "./src/main.am" Console_WriteError(" --target= cross-compile freestanding for an MCU"); #line 2224 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat(" (", Amalgame_Compiler_Program_KnownTargets())), "); produces .elf + .bin/.hex")); #line 2225 "./src/main.am" Console_WriteError(" --board= board package (amalgame-mcu-) for startup +"); #line 2226 "./src/main.am" Console_WriteError(" linker + libs. cortex-m3 defaults to bundled QEMU board."); #line 2227 "./src/main.am" Console_WriteError(" Native lib paths via env AMC_EMBED_INC / AMC_EMBED_LIB."); #line 2228 "./src/main.am" Console_WriteError(" --flash after building, flash via the board's [target].flash_cmd"); #line 2229 "./src/main.am" return 0LL; } #line 2231 "./src/main.am" if ((code_string_equals(a, "-o")) && ((i + 1LL) < argc)) { #line 2232 "./src/main.am" outBin = Args_Get(i + 1LL); #line 2233 "./src/main.am" i = (i + 2LL); } else if ((code_string_equals(a, "-v")) || (code_string_equals(a, "--verbose"))) { #line 2235 "./src/main.am" verbose = 1; #line 2236 "./src/main.am" i = (i + 1LL); } else if ((code_string_equals(a, "-g")) || (code_string_equals(a, "--debug"))) { #line 2238 "./src/main.am" debug = 1; #line 2239 "./src/main.am" i = (i + 1LL); } else if (String_StartsWith(a, "--target=")) { #line 2241 "./src/main.am" target = String_From(a, 9LL); #line 2242 "./src/main.am" if (!Amalgame_Compiler_Program_IsKnownTarget(target)) { #line 2243 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat("amc build: unknown --target '", target)), "'")); #line 2244 "./src/main.am" Console_WriteError(code_string_concat(" known: ", Amalgame_Compiler_Program_KnownTargets())); #line 2245 "./src/main.am" return 1LL; } #line 2247 "./src/main.am" i = (i + 1LL); } else if (String_StartsWith(a, "--board=")) { #line 2249 "./src/main.am" board = String_From(a, 8LL); #line 2250 "./src/main.am" i = (i + 1LL); } else if (code_string_equals(a, "--flash")) { #line 2252 "./src/main.am" flash = 1; #line 2253 "./src/main.am" i = (i + 1LL); } else if (String_StartsWith(a, "-")) { #line 2255 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat("amc build: unknown option '", a)), "'")); #line 2256 "./src/main.am" return 1LL; } else { #line 2258 "./src/main.am" if (String_Length(entryAm) > 0LL) { #line 2259 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat("amc build: only one entry .am file is supported; got '", entryAm)), "' and '")), a)), "'")); #line 2260 "./src/main.am" return 1LL; } #line 2262 "./src/main.am" entryAm = a; #line 2263 "./src/main.am" i = (i + 1LL); } } #line 2266 "./src/main.am" if (String_Length(entryAm) == 0LL) { #line 2267 "./src/main.am" Console_WriteError("amc build: missing entry .am argument"); #line 2268 "./src/main.am" Console_WriteError("Usage: amc build [-o ] [-g|--debug] [--verbose] "); #line 2269 "./src/main.am" return 2LL; } #line 2272 "./src/main.am" if (String_Length(outBin) == 0LL) { #line 2273 "./src/main.am" outBin = entryAm; #line 2274 "./src/main.am" i64 lastSlash = String_LastIndexOf(outBin, "/"); #line 2275 "./src/main.am" if (lastSlash >= 0LL) { #line 2276 "./src/main.am" outBin = String_Substring(outBin, lastSlash + 1LL, (String_Length(outBin) - lastSlash) - 1LL); } #line 2278 "./src/main.am" if (String_EndsWith(outBin, ".am")) { #line 2279 "./src/main.am" outBin = String_Substring(outBin, 0LL, String_Length(outBin) - 3LL); } #line 2281 "./src/main.am" outBin = (code_string_concat("./", outBin)); } #line 2283 "./src/main.am" i64 rc = Amalgame_Compiler_Program_BuildEntry(entryAm, outBin, verbose, debug, target, board); #line 2284 "./src/main.am" if (rc == 0LL) { #line 2285 "./src/main.am" Console_WriteLine(code_string_concat("✓ Built ", outBin)); #line 2287 "./src/main.am" if (flash && (String_Length(target) > 0LL)) { #line 2288 "./src/main.am" rc = Amalgame_Compiler_Program_FlashEmbedded(board, outBin); } } #line 2291 "./src/main.am" return rc; } i64 Amalgame_Compiler_Program_RunRun(i64 argc) { #line 2301 "./src/main.am" code_string entryAm = ""; #line 2302 "./src/main.am" code_string outBin = ""; #line 2303 "./src/main.am" code_bool verbose = 0; #line 2304 "./src/main.am" code_bool debug = 0; #line 2305 "./src/main.am" AmalgameList* userArgs = AmalgameList_new(); #line 2306 "./src/main.am" code_bool sawSep = 0; #line 2307 "./src/main.am" i64 i = 2LL; #line 2308 "./src/main.am" while (i < argc) { #line 2309 "./src/main.am" code_string a = Args_Get(i); #line 2310 "./src/main.am" if (sawSep) { #line 2311 "./src/main.am" AmalgameList_add(userArgs, (void*)(intptr_t)(a)); #line 2312 "./src/main.am" i = (i + 1LL); #line 2313 "./src/main.am" continue; } #line 2315 "./src/main.am" if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) { #line 2316 "./src/main.am" Console_WriteError("Usage: amc run [-o ] [-g|--debug] [--verbose] [-- args...]"); #line 2317 "./src/main.am" Console_WriteError(""); #line 2318 "./src/main.am" Console_WriteError("Build the binary, then run it. Args after the `--` sentinel"); #line 2319 "./src/main.am" Console_WriteError("are forwarded to the resulting program's argv."); #line 2320 "./src/main.am" return 0LL; } #line 2322 "./src/main.am" if (code_string_equals(a, "--")) { #line 2323 "./src/main.am" sawSep = 1; #line 2324 "./src/main.am" i = (i + 1LL); } else if ((code_string_equals(a, "-o")) && ((i + 1LL) < argc)) { #line 2326 "./src/main.am" outBin = Args_Get(i + 1LL); #line 2327 "./src/main.am" i = (i + 2LL); } else if ((code_string_equals(a, "-v")) || (code_string_equals(a, "--verbose"))) { #line 2329 "./src/main.am" verbose = 1; #line 2330 "./src/main.am" i = (i + 1LL); } else if ((code_string_equals(a, "-g")) || (code_string_equals(a, "--debug"))) { #line 2332 "./src/main.am" debug = 1; #line 2333 "./src/main.am" i = (i + 1LL); } else if (String_StartsWith(a, "-")) { #line 2335 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat("amc run: unknown option '", a)), "'")); #line 2336 "./src/main.am" return 1LL; } else { #line 2338 "./src/main.am" if (String_Length(entryAm) > 0LL) { #line 2339 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat((code_string_concat((code_string_concat("amc run: only one entry .am file is supported; got '", entryAm)), "' and '")), a)), "'")); #line 2340 "./src/main.am" return 1LL; } #line 2342 "./src/main.am" entryAm = a; #line 2343 "./src/main.am" i = (i + 1LL); } } #line 2346 "./src/main.am" if (String_Length(entryAm) == 0LL) { #line 2347 "./src/main.am" Console_WriteError("amc run: missing entry .am argument"); #line 2348 "./src/main.am" Console_WriteError("Usage: amc run [-o ] [--verbose] [-- args...]"); #line 2349 "./src/main.am" return 2LL; } #line 2351 "./src/main.am" if (String_Length(outBin) == 0LL) { #line 2352 "./src/main.am" outBin = entryAm; #line 2353 "./src/main.am" i64 lastSlash = String_LastIndexOf(outBin, "/"); #line 2354 "./src/main.am" if (lastSlash >= 0LL) { #line 2355 "./src/main.am" outBin = String_Substring(outBin, lastSlash + 1LL, (String_Length(outBin) - lastSlash) - 1LL); } #line 2357 "./src/main.am" if (String_EndsWith(outBin, ".am")) { #line 2358 "./src/main.am" outBin = String_Substring(outBin, 0LL, String_Length(outBin) - 3LL); } #line 2360 "./src/main.am" outBin = (code_string_concat("./", outBin)); } #line 2362 "./src/main.am" i64 buildRc = Amalgame_Compiler_Program_BuildEntry(entryAm, outBin, verbose, debug, "", ""); #line 2363 "./src/main.am" if (buildRc != 0LL) { #line 2364 "./src/main.am" return buildRc; } #line 2367 "./src/main.am" code_string runCmd = outBin; #line 2368 "./src/main.am" i64 na = AmalgameList_count(userArgs); #line 2369 "./src/main.am" for (i64 ai = 0LL; ai < na; ai++) { #line 2370 "./src/main.am" code_string ua = (code_string)AmalgameList_get(userArgs, ai); #line 2375 "./src/main.am" runCmd = (code_string_concat((code_string_concat((code_string_concat(runCmd, " \"")), ua)), "\"")); } #line 2377 "./src/main.am" return Process_Run(runCmd); } i64 Amalgame_Compiler_Program_RunWatch(i64 argc) { #line 2389 "./src/main.am" code_string entryAm = ""; #line 2390 "./src/main.am" code_string outBin = ""; #line 2391 "./src/main.am" code_bool verbose = 0; #line 2392 "./src/main.am" code_bool runAfter = 0; #line 2393 "./src/main.am" i64 i = 2LL; #line 2394 "./src/main.am" while (i < argc) { #line 2395 "./src/main.am" code_string a = Args_Get(i); #line 2396 "./src/main.am" if ((code_string_equals(a, "-h")) || (code_string_equals(a, "--help"))) { #line 2397 "./src/main.am" Console_WriteError("Usage: amc watch [-o ] [--run] [--verbose] "); #line 2398 "./src/main.am" Console_WriteError(""); #line 2399 "./src/main.am" Console_WriteError("Build now, then poll 's mtime every 500 ms."); #line 2400 "./src/main.am" Console_WriteError("On change: rebuild (and re-run with --run). Ctrl-C to exit."); #line 2401 "./src/main.am" Console_WriteError("v1 watches only the explicit entry file; transitive imports"); #line 2402 "./src/main.am" Console_WriteError("come post-D when the FileWatcher event-loop lands."); #line 2403 "./src/main.am" return 0LL; } #line 2405 "./src/main.am" if ((code_string_equals(a, "-o")) && ((i + 1LL) < argc)) { #line 2406 "./src/main.am" outBin = Args_Get(i + 1LL); #line 2407 "./src/main.am" i = (i + 2LL); } else if ((code_string_equals(a, "-v")) || (code_string_equals(a, "--verbose"))) { #line 2409 "./src/main.am" verbose = 1; #line 2410 "./src/main.am" i = (i + 1LL); } else if (code_string_equals(a, "--run")) { #line 2412 "./src/main.am" runAfter = 1; #line 2413 "./src/main.am" i = (i + 1LL); } else if (String_StartsWith(a, "-")) { #line 2415 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat("amc watch: unknown option '", a)), "'")); #line 2416 "./src/main.am" return 1LL; } else { #line 2418 "./src/main.am" if (String_Length(entryAm) > 0LL) { #line 2419 "./src/main.am" Console_WriteError("amc watch: only one entry .am file is supported"); #line 2420 "./src/main.am" return 1LL; } #line 2422 "./src/main.am" entryAm = a; #line 2423 "./src/main.am" i = (i + 1LL); } } #line 2426 "./src/main.am" if (String_Length(entryAm) == 0LL) { #line 2427 "./src/main.am" Console_WriteError("amc watch: missing entry .am argument"); #line 2428 "./src/main.am" return 2LL; } #line 2430 "./src/main.am" if (String_Length(outBin) == 0LL) { #line 2431 "./src/main.am" outBin = entryAm; #line 2432 "./src/main.am" i64 lastSlash = String_LastIndexOf(outBin, "/"); #line 2433 "./src/main.am" if (lastSlash >= 0LL) { #line 2434 "./src/main.am" outBin = String_Substring(outBin, lastSlash + 1LL, (String_Length(outBin) - lastSlash) - 1LL); } #line 2436 "./src/main.am" if (String_EndsWith(outBin, ".am")) { #line 2437 "./src/main.am" outBin = String_Substring(outBin, 0LL, String_Length(outBin) - 3LL); } #line 2439 "./src/main.am" outBin = (code_string_concat("./", outBin)); } #line 2442 "./src/main.am" Console_WriteLine(code_string_concat((code_string_concat((code_string_concat("amc watch: ", entryAm)), " → ")), outBin)); #line 2443 "./src/main.am" i64 _rc1 = Amalgame_Compiler_Program_BuildAndMaybeRun(entryAm, outBin, verbose, runAfter); #line 2444 "./src/main.am" i64 lastMtime = Amalgame_Compiler_Program_FileMtimeNs(entryAm); #line 2445 "./src/main.am" Console_WriteLine(" (watching for changes, Ctrl-C to exit)"); #line 2446 "./src/main.am" while (1) { #line 2447 "./src/main.am" Amalgame_Compiler_Program_SleepMs(500LL); #line 2448 "./src/main.am" i64 cur = Amalgame_Compiler_Program_FileMtimeNs(entryAm); #line 2449 "./src/main.am" if ((cur != lastMtime) && (cur > 0LL)) { #line 2450 "./src/main.am" lastMtime = cur; #line 2451 "./src/main.am" Console_WriteLine(""); #line 2452 "./src/main.am" Console_WriteLine("── change detected, rebuilding"); #line 2453 "./src/main.am" i64 _rc2 = Amalgame_Compiler_Program_BuildAndMaybeRun(entryAm, outBin, verbose, runAfter); } } #line 2456 "./src/main.am" return 0LL; } static i64 Amalgame_Compiler_Program_BuildAndMaybeRun(code_string entryAm, code_string outBin, code_bool verbose, code_bool runAfter) { #line 2460 "./src/main.am" i64 rc = Amalgame_Compiler_Program_BuildEntry(entryAm, outBin, verbose, 0, "", ""); #line 2461 "./src/main.am" if (rc != 0LL) { return rc; } #line 2462 "./src/main.am" Console_WriteLine(code_string_concat("✓ Built ", outBin)); #line 2463 "./src/main.am" if (runAfter) { #line 2464 "./src/main.am" Console_WriteLine("── running"); #line 2465 "./src/main.am" return Process_Run(outBin); } #line 2467 "./src/main.am" return 0LL; } static i64 Amalgame_Compiler_Program_FileMtimeNs(code_string path) { #line 2474 "./src/main.am" { /* inline-C */ #ifdef _WIN32 struct _stat64 st; if (_stat64(path, &st) != 0) return 0; return (i64)((int64_t) st.st_mtime * 1000000000LL); #else struct stat st; if (stat(path, &st) != 0) return 0; #ifdef __APPLE__ return (i64)((int64_t) st.st_mtimespec.tv_sec * 1000000000LL + (int64_t) st.st_mtimespec.tv_nsec); #else return (i64)((int64_t) st.st_mtim.tv_sec * 1000000000LL + (int64_t) st.st_mtim.tv_nsec); #endif #endif } } static void Amalgame_Compiler_Program_SleepMs(i64 ms) { #line 2492 "./src/main.am" { /* inline-C */ #ifdef _WIN32 Sleep((DWORD) ms); #else struct timespec ts; ts.tv_sec = (time_t)(ms / 1000); ts.tv_nsec = (long)((ms % 1000) * 1000000L); nanosleep(&ts, NULL); #endif } } i64 Amalgame_Compiler_Program_RunFmt(i64 argc) { #line 2506 "./src/main.am" Amalgame_Compiler_ArgParser* ap = Amalgame_Compiler_ArgParser_new(); #line 2507 "./src/main.am" Amalgame_Compiler_ArgParser_Parse(Amalgame_Compiler_ArgParser_Flag(Amalgame_Compiler_ArgParser_Flag(Amalgame_Compiler_ArgParser_Flag(Amalgame_Compiler_ArgParser_Flag(ap, "-w"), "--write"), "-h"), "--help"), argc, 2LL); #line 2508 "./src/main.am" if (Amalgame_Compiler_ArgParser_HelpRequested(ap)) { #line 2509 "./src/main.am" Console_WriteError("Usage: amc fmt [-w|--write] ..."); #line 2510 "./src/main.am" Console_WriteError(""); #line 2511 "./src/main.am" Console_WriteError("Re-emit canonical formatting of Amalgame source files."); #line 2512 "./src/main.am" Console_WriteError("Default: print to stdout. With -w, rewrite each file in place."); #line 2513 "./src/main.am" return 0LL; } #line 2515 "./src/main.am" if (String_Length(Amalgame_Compiler_ArgParser_GetUnknown(ap)) > 0LL) { #line 2516 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat("amc fmt: unknown argument '", Amalgame_Compiler_ArgParser_GetUnknown(ap))), "'")); #line 2517 "./src/main.am" return 1LL; } #line 2519 "./src/main.am" code_bool write = Amalgame_Compiler_ArgParser_HasFlag(ap, "-w") || Amalgame_Compiler_ArgParser_HasFlag(ap, "--write"); #line 2520 "./src/main.am" AmalgameList* files = Amalgame_Compiler_ArgParser_GetPositionals(ap); #line 2521 "./src/main.am" i64 fn = AmalgameList_count(files); #line 2522 "./src/main.am" for (i64 j = 0LL; j < fn; j++) { #line 2523 "./src/main.am" code_string f = (code_string)AmalgameList_get(files, j); #line 2524 "./src/main.am" if (!String_EndsWith(f, ".am")) { #line 2525 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat("amc fmt: unknown argument '", f)), "'")); #line 2526 "./src/main.am" return 1LL; } } #line 2529 "./src/main.am" if (AmalgameList_count(files) == 0LL) { #line 2530 "./src/main.am" Console_WriteError("amc fmt: no input .am files"); #line 2531 "./src/main.am" return 1LL; } #line 2533 "./src/main.am" i64 n = AmalgameList_count(files); #line 2534 "./src/main.am" for (i64 j = 0LL; j < n; j++) { #line 2535 "./src/main.am" code_string path = (code_string)AmalgameList_get(files, j); #line 2536 "./src/main.am" code_string src = File_ReadAll(path); #line 2537 "./src/main.am" Amalgame_Compiler_Lexer* lex = Amalgame_Compiler_Lexer_new(src, path); #line 2538 "./src/main.am" AmalgameList* toks = Amalgame_Compiler_Lexer_Tokenize(lex); #line 2539 "./src/main.am" Amalgame_Compiler_Parser* par = Amalgame_Compiler_Parser_new(toks); #line 2540 "./src/main.am" Amalgame_Compiler_AstNode* prog = Amalgame_Compiler_Parser_Parse(par); #line 2541 "./src/main.am" if (Amalgame_Compiler_Parser_HasErrors(par)) { #line 2542 "./src/main.am" Console_WriteError(code_string_concat("amc fmt: parse errors in ", path)); #line 2543 "./src/main.am" Console_WriteError(Amalgame_Compiler_Parser_GetErrors(par)); #line 2544 "./src/main.am" return 1LL; } #line 2546 "./src/main.am" Amalgame_Compiler_Formatter* fmt = Amalgame_Compiler_Formatter_new(par->Comments); #line 2547 "./src/main.am" code_string out = Amalgame_Compiler_Formatter_Format(fmt, prog); #line 2548 "./src/main.am" if (write) { #line 2549 "./src/main.am" File_WriteAll(path, out); } else { #line 2551 "./src/main.am" Console_Write(out); } } #line 2554 "./src/main.am" return 0LL; } void Amalgame_Compiler_Program_Main(code_string* args) { #line 2558 "./src/main.am" i64 argc = Args_Count(); #line 2559 "./src/main.am" if (argc < 2LL) { #line 2560 "./src/main.am" Amalgame_Compiler_Program_PrintUsage(); #line 2561 "./src/main.am" Exit_Set(1LL); #line 2562 "./src/main.am" return; } #line 2564 "./src/main.am" if (code_string_equals(Args_Get(1LL), "build")) { #line 2565 "./src/main.am" Exit_Set(Amalgame_Compiler_Program_RunBuild(argc)); #line 2566 "./src/main.am" return; } #line 2568 "./src/main.am" if (code_string_equals(Args_Get(1LL), "run")) { #line 2569 "./src/main.am" Exit_Set(Amalgame_Compiler_Program_RunRun(argc)); #line 2570 "./src/main.am" return; } #line 2572 "./src/main.am" if (code_string_equals(Args_Get(1LL), "watch")) { #line 2573 "./src/main.am" Exit_Set(Amalgame_Compiler_Program_RunWatch(argc)); #line 2574 "./src/main.am" return; } #line 2576 "./src/main.am" if (code_string_equals(Args_Get(1LL), "fmt")) { #line 2577 "./src/main.am" Exit_Set(Amalgame_Compiler_Program_RunFmt(argc)); #line 2578 "./src/main.am" return; } #line 2580 "./src/main.am" if (code_string_equals(Args_Get(1LL), "doc")) { #line 2581 "./src/main.am" Exit_Set(Amalgame_Compiler_DocCommand_Run(argc)); #line 2582 "./src/main.am" return; } #line 2584 "./src/main.am" if (code_string_equals(Args_Get(1LL), "test")) { #line 2585 "./src/main.am" Exit_Set(Amalgame_Compiler_Program_RunTest(argc)); #line 2586 "./src/main.am" return; } #line 2588 "./src/main.am" if (code_string_equals(Args_Get(1LL), "lsp")) { #line 2589 "./src/main.am" Amalgame_Compiler_LspServer* server = Amalgame_Compiler_LspServer_new(); #line 2590 "./src/main.am" Exit_Set(Amalgame_Compiler_LspServer_Run(server)); #line 2591 "./src/main.am" return; } #line 2593 "./src/main.am" if (code_string_equals(Args_Get(1LL), "dap")) { #line 2594 "./src/main.am" Amalgame_Compiler_DapServer* dap = Amalgame_Compiler_DapServer_new(); #line 2595 "./src/main.am" Exit_Set(Amalgame_Compiler_DapServer_Run(dap)); #line 2596 "./src/main.am" return; } #line 2598 "./src/main.am" if (code_string_equals(Args_Get(1LL), "migrate")) { #line 2599 "./src/main.am" Exit_Set(Amalgame_Compiler_MigrateCommand_Run(argc)); #line 2600 "./src/main.am" return; } #line 2602 "./src/main.am" if (code_string_equals(Args_Get(1LL), "generate")) { #line 2603 "./src/main.am" Exit_Set(Amalgame_Compiler_GenerateCommand_Run(argc)); #line 2604 "./src/main.am" return; } #line 2606 "./src/main.am" if (code_string_equals(Args_Get(1LL), "explain")) { #line 2607 "./src/main.am" Exit_Set(Amalgame_Compiler_ExplainCommand_Run(argc)); #line 2608 "./src/main.am" return; } #line 2610 "./src/main.am" if (code_string_equals(Args_Get(1LL), "new")) { #line 2611 "./src/main.am" Exit_Set(Amalgame_Compiler_NewCommand_Run(argc)); #line 2612 "./src/main.am" return; } #line 2614 "./src/main.am" if (code_string_equals(Args_Get(1LL), "monitor")) { #line 2615 "./src/main.am" Exit_Set(Amalgame_Compiler_Program_RunMonitor(argc)); #line 2616 "./src/main.am" return; } #line 2618 "./src/main.am" if (code_string_equals(Args_Get(1LL), "mcu")) { #line 2619 "./src/main.am" Exit_Set(Amalgame_Compiler_McuCommand_Run(argc)); #line 2620 "./src/main.am" return; } #line 2628 "./src/main.am" code_string v1 = Args_Get(1LL); #line 2629 "./src/main.am" if ((code_string_equals(v1, "package")) || (code_string_equals(v1, "pkg"))) { #line 2630 "./src/main.am" Exit_Set(Amalgame_Compiler_AddCommand_RunPackage(argc)); #line 2631 "./src/main.am" return; } #line 2634 "./src/main.am" AmalgameList* inputFiles = AmalgameList_new(); #line 2635 "./src/main.am" AmalgameList* externalFiles = AmalgameList_new(); #line 2636 "./src/main.am" code_string outputName = "a.out"; #line 2637 "./src/main.am" code_bool isLib = 0; #line 2638 "./src/main.am" code_bool checkOnly = 0; #line 2639 "./src/main.am" code_bool lintMode = 0; #line 2640 "./src/main.am" code_bool useColor = 0; #line 2641 "./src/main.am" code_bool verbose = 1; #line 2644 "./src/main.am" code_string target = ""; #line 2646 "./src/main.am" i64 i = 1LL; #line 2647 "./src/main.am" while (i < argc) { #line 2648 "./src/main.am" code_string a = Args_Get(i); #line 2649 "./src/main.am" if ((code_string_equals(a, "-o")) && ((i + 1LL) < argc)) { #line 2650 "./src/main.am" i = (i + 1LL); #line 2651 "./src/main.am" outputName = Args_Get(i); } else if ((code_string_equals(a, "--external")) && ((i + 1LL) < argc)) { #line 2659 "./src/main.am" i = (i + 1LL); #line 2660 "./src/main.am" AmalgameList_add(externalFiles, (void*)(intptr_t)(Args_Get(i))); } else if (code_string_equals(a, "--lib")) { #line 2662 "./src/main.am" isLib = 1; } else if (String_StartsWith(a, "--target=")) { #line 2664 "./src/main.am" target = String_From(a, 9LL); #line 2665 "./src/main.am" if (!Amalgame_Compiler_Program_IsKnownTarget(target)) { #line 2666 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat("amc: unknown --target '", target)), "'")); #line 2667 "./src/main.am" Console_WriteError(code_string_concat(" known: ", Amalgame_Compiler_Program_KnownTargets())); #line 2668 "./src/main.am" Exit_Set(1LL); #line 2669 "./src/main.am" return; } } else if (code_string_equals(a, "--check")) { #line 2672 "./src/main.am" checkOnly = 1; } else if (code_string_equals(a, "--lint")) { #line 2674 "./src/main.am" lintMode = 1; } else if (code_string_equals(a, "--color")) { #line 2676 "./src/main.am" useColor = 1; } else if (code_string_equals(a, "--no-color")) { #line 2678 "./src/main.am" useColor = 0; } else if (code_string_equals(a, "--quiet")) { #line 2680 "./src/main.am" verbose = 0; } else if (code_string_equals(a, "--verbose")) { #line 2682 "./src/main.am" verbose = 1; } else if (code_string_equals(a, "--version")) { #line 2689 "./src/main.am" code_string rev = Amalgame_Compiler_BuildInfo_GitRev(); #line 2690 "./src/main.am" code_string date = Amalgame_Compiler_BuildInfo_BuildDate(); #line 2691 "./src/main.am" code_string head = code_string_concat("amc ", Amalgame_Compiler_PackageRegistry_AmcVersion()); #line 2692 "./src/main.am" code_string prov = ""; #line 2693 "./src/main.am" if ((String_Length(rev) > 0LL) && (String_Length(date) > 0LL)) { #line 2694 "./src/main.am" prov = (code_string_concat((code_string_concat((code_string_concat((code_string_concat(" (commit ", rev)), ", built ")), date)), ")")); } else if (String_Length(rev) > 0LL) { #line 2696 "./src/main.am" prov = (code_string_concat((code_string_concat(" (commit ", rev)), ")")); } else if (String_Length(date) > 0LL) { #line 2698 "./src/main.am" prov = (code_string_concat((code_string_concat(" (built ", date)), ")")); } #line 2700 "./src/main.am" Console_WriteLine(code_string_concat(head, prov)); #line 2701 "./src/main.am" Console_WriteLine("Self-hosted Amalgame compiler."); #line 2702 "./src/main.am" Console_WriteLine("Copyright (c) 2026 Bastien Mouget. License: Apache-2.0."); #line 2703 "./src/main.am" Console_WriteLine("Website: https://amalgame.me"); #line 2704 "./src/main.am" Console_WriteLine("Repository: https://github.com/amalgame-lang/Amalgame"); #line 2705 "./src/main.am" Console_WriteLine("Issues: https://github.com/amalgame-lang/Amalgame/issues"); #line 2706 "./src/main.am" Exit_Set(0LL); #line 2707 "./src/main.am" return; } else if ((code_string_equals(a, "--help")) || (code_string_equals(a, "-h"))) { #line 2709 "./src/main.am" Amalgame_Compiler_Program_PrintUsage(); #line 2710 "./src/main.am" Exit_Set(0LL); #line 2711 "./src/main.am" return; } else if (String_EndsWith(a, ".am")) { #line 2713 "./src/main.am" AmalgameList_add(inputFiles, (void*)(intptr_t)(a)); } else { #line 2715 "./src/main.am" Console_WriteError(code_string_concat((code_string_concat("amc: unknown option '", a)), "'")); #line 2716 "./src/main.am" Amalgame_Compiler_Program_PrintUsage(); #line 2717 "./src/main.am" Exit_Set(1LL); #line 2718 "./src/main.am" return; } #line 2720 "./src/main.am" i = (i + 1LL); } #line 2723 "./src/main.am" if (AmalgameList_count(inputFiles) == 0LL) { #line 2724 "./src/main.am" Console_WriteError("amc: no input .am files"); #line 2725 "./src/main.am" Exit_Set(1LL); #line 2726 "./src/main.am" return; } #line 2729 "./src/main.am" Amalgame_Compiler_AmalgameCompiler* compiler = Amalgame_Compiler_AmalgameCompiler_new(); #line 2730 "./src/main.am" Amalgame_Compiler_AmalgameCompiler_SetLib(compiler, isLib); #line 2731 "./src/main.am" Amalgame_Compiler_AmalgameCompiler_SetCheckOnly(compiler, checkOnly); #line 2732 "./src/main.am" Amalgame_Compiler_AmalgameCompiler_SetLintMode(compiler, lintMode); #line 2733 "./src/main.am" Amalgame_Compiler_AmalgameCompiler_SetColor(compiler, useColor); #line 2734 "./src/main.am" Amalgame_Compiler_AmalgameCompiler_SetVerbose(compiler, verbose); #line 2735 "./src/main.am" Amalgame_Compiler_AmalgameCompiler_SetExternalFiles(compiler, externalFiles); #line 2736 "./src/main.am" Amalgame_Compiler_AmalgameCompiler_SetTarget(compiler, target); #line 2737 "./src/main.am" Amalgame_Compiler_AmalgameCompiler_Run(compiler, inputFiles, outputName); #line 2738 "./src/main.am" Exit_Set(Amalgame_Compiler_AmalgameCompiler_GetExitCode(compiler)); } int main(int argc, char** argv) { GC_INIT(); code_runtime_init_args(argc, argv); Amalgame_Compiler_Program_Main((code_string*)argv); return code_exit_code; }