// The MIT License (MIT) // // Copyright (C) 2026 Scott Duensing // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. // front.h -- DVX BASIC compiler internals shared by the front-end passes // // parse*.c tokens -> syntax tree of one unit (and the declaration pass) // resolve*.c names -> symbols, built-ins, controls; semantic checks // typecheck.c static types and implicit conversions // fold.c constant folding (CONST values, literal subexpressions) // gen*.c tree -> p-code // compiler.c the driver: declaration pass, unit loop, module tables // // Embeddable: no DVX dependencies, pure C. #ifndef DVXBASIC_FRONT_H #define DVXBASIC_FRONT_H #include "compiler.h" #include "ast.h" #include "scope.h" #include "lexer.h" #include "codegen.h" #include "opcodes.h" #include "../runtime/vm.h" #include #include // Error message sizes: the stored message ("Line N, Col M: text") and // the text before the prefix is added. #define BAS_COMPILE_ERROR_LEN 1024 #define BAS_ERROR_TEXT_LEN 512 // Letters DEFINT .. DEFSTR cover (A-Z), and a letter with no DEFxxx. #define BAS_DEFTYPE_LETTERS ('Z' - 'A' + 1) #define BAS_DEFTYPE_NONE 0xFF // Recursion guards: nested expressions and blocks each cost a dozen C // stack frames, and the DOS stack is small. #define BAS_MAX_EXPR_DEPTH 64 #define BAS_MAX_BLOCK_DEPTH 32 // blockDepth while a top-level unit's own statement is parsed (a // procedure must be one: its scope lives in the unit arena). #define BAS_UNIT_BLOCK_DEPTH 1 // Longest TYPE field chain in a store target (a.b.c ...). #define BAS_MAX_FIELD_CHAIN BAS_LAYOUT_MAX_DEPTH // The member class of an object the source names directly (a control or // a form, not an object variable): its methods take their arguments by // value. #define BAS_CLASS_HOST (-3) // BASIC's TRUE as an integer. #define BAS_TRUE_INT (-1) // DEF FN function names start with FN. #define BAS_DEFFN_PREFIX "FN" // Form / PictureBox drawing methods with QBasic statement syntax, and // the form methods a two-part name.Show / name.Hide statement means. #define BAS_METHOD_CIRCLE "Circle" #define BAS_METHOD_LINE "Line" #define BAS_METHOD_PRINT "Print" #define BAS_METHOD_PSET "PSet" #define BAS_METHOD_SCALE "Scale" #define BAS_METHOD_SHOW "Show" #define BAS_METHOD_HIDE "Hide" // A file-private name (Private CONST / ENUM outside class modules) is the // name, this separator (no identifier holds it) and the file's number. #define BAS_FILE_PRIVATE_SEP "|" // basDeclareEnumName's file for a name every file sees. #define BAS_FILE_PUBLIC (-1) // Words the parser reads by their text (identifiers, not reserved). #define BAS_KW_COMPARE "COMPARE" #define BAS_KW_FRIEND "FRIEND" #define BAS_KW_IMPLEMENTS "IMPLEMENTS" #define BAS_KW_TEXT "TEXT" // Built-ins the parser calls by these names (BasBuiltinT.name), which no // identifier can spell: LIKE and ERROR are reserved words, a name holds // no '.'. #define BAS_BUILTIN_LIKE "LIKE" #define BAS_BUILTIN_ERROR "ERROR" #define BAS_BUILTIN_ERR_DESCRIPTION "ERR.DESCRIPTION" #define BAS_BUILTIN_ERR_SOURCE "ERR.SOURCE" // ARRAY(...), which the resolver builds itself (a program's own Array // procedure or variable comes first). #define BAS_ARRAY_FUNC "ARRAY" // Err's members the parser reads by their text. #define BAS_ERR_MEMBER_CLEAR "CLEAR" #define BAS_ERR_MEMBER_DESCRIPTION "DESCRIPTION" #define BAS_ERR_MEMBER_NUMBER "NUMBER" #define BAS_ERR_MEMBER_RAISE "RAISE" #define BAS_ERR_MEMBER_SOURCE "SOURCE" // Arguments of the two-argument statements and built-ins (FILECOPY, // NAME, SETATTR, SEEK, LIKE ...). #define BAS_PAIR_ARGS 2 // ST_ONERROR's ival: ON ERROR RESUME NEXT (0: ON ERROR GOTO). #define BAS_ON_ERROR_RESUME_NEXT 1 // ST_LABEL ival: a QBasic line number (its value in ival2), which ERL reports #define BAS_LABEL_LINE_NUMBER 1 // MsgBox: the OK button only (vbOKOnly, the default flags). #define BAS_MSGBOX_OK_ONLY 0x0000 // The error for a name after AS that is no type. #define BAS_TYPE_EXPECTED "Expected type name (Integer, Long, Single, Double, String, Boolean, Date, Variant, Control, Form, Object, Collection, TYPE, ENUM or class name)" // Types named by identifiers rather than reserved words. #define BAS_DATE_TYPE_NAME "DATE" #define BAS_BYTE_TYPE_NAME "BYTE" #define BAS_CURRENCY_TYPE_NAME "CURRENCY" #define BAS_VARIANT_TYPE_NAME "VARIANT" #define BAS_COLLECTION_TYPE_NAME "COLLECTION" // The Collection class as messages name it. #define BAS_COLLECTION_DISPLAY_NAME "Collection" // Built-in function flags. #define BI_PURE 0x01 // result depends on the arguments alone: allowed in constant expressions #define BI_FOLD 0x02 // folded in ordinary code when its arguments are literals #define BI_OBJECT_ARG 0x04 // the first argument is an object (a bare control or form name is the object) // The built-in function a statement may call too (CallByName obj, ...). #define BAS_CALLBYNAME_NAME "CallByName" // A built-in function (BasBuiltinT table in resolveExpr.c). An // OP_BUILTIN entry names its BasBuiltinFnE in func and takes its argument // counts from basBuiltinArity. typedef struct { const char *name; uint8_t opcode; uint8_t func; uint8_t minArgs; uint8_t maxArgs; uint8_t resultType; // BAS_TYPE_* the result always has (BAS_NODE_TYPE_UNKNOWN: depends) uint8_t flags; // BI_* uint8_t nullMask; // arguments (BAS_NULL_ARG_*) whose Null makes the result Null: VB's Variant forms (Left, Mid ...); 0: none const char *const *argNames; // VB's names of its arguments (Name:=value), NULL-terminated; NULL: none given by name } BasBuiltinT; // How an early-bound member is used (basBindMember). typedef enum { BAS_ACCESS_READ, // obj.name: its value (no argument list) BAS_ACCESS_VALUE, // obj.name(args) in an expression BAS_ACCESS_STATEMENT, // obj.name args / obj.name(args) as a statement BAS_ACCESS_LET, // obj.name(args) = value BAS_ACCESS_SET // Set obj.name(args) = value } BasAccessE; // How an unresolved name is being used (resolver). typedef enum { BAS_USE_VALUE, // its value BAS_USE_OBJECT, // an object is expected (SET value, IS / TypeOf operand, object parameter) BAS_USE_MEMBERBASE // name.member } BasUseE; // Deferred argument forms of the drawing methods (obj.Line ...), read // once the resolver knows whether obj is a class instance. typedef enum { BAS_DEFER_ARGS, // comma-separated method arguments BAS_DEFER_DRAWING // the method's QBasic statement syntax (Print items, Line / Circle / PSet blocks, Scale rectangle) } BasDeferModeE; // How an assignment stores (BasStmtT.ival2 of ST_ASSIGN). typedef enum { BAS_STORE_PLAIN, // the value replaces what the target holds BAS_STORE_APPEND, // s = s + x / s = s & x on a STRING variable: x appended in place (OP_STR_APPEND); ival = the operator BAS_STORE_RECORD // a TYPE value copied into the record the target holds (BAS_FN_RECORD_ASSIGN) } BasStoreE; // A change the resolver made to a symbol in the middle of a unit (see // basSymChange): what it was before and after statement at. typedef struct { const BasNodeT *at; BasSymT *sym; uint32_t beforeFlags; uint32_t afterFlags; int32_t beforeUdtTypeId; int32_t afterUdtTypeId; uint8_t beforeType; uint8_t afterType; } BasSymChangeT; // A loop or SELECT the generator is inside. typedef struct { int32_t *exitPatches; // stb_ds: EXIT jumps to land after the loop int32_t selectBase; // SELECT depth at the loop's start (EXIT pops the ones opened since) bool isFor; // FOR / FOR EACH (else DO / WHILE) bool isForEach; // no VM FOR frame to drop on EXIT FOR } BasGenLoopT; struct BasCompilerS { // Source and tokens const char *source; int32_t sourceLen; BasLexerT lex; int32_t prevLine; // line of the previous token (errors at the end of a line) // First error char error[BAS_COMPILE_ERROR_LEN]; bool hasError; int32_t errorLine; int32_t errorCol; // Memory: module-lifetime data and the unit being compiled BasArenaT modArena; BasArenaT unitArena; // Parser context (syntax only) int32_t exprDepth; int32_t blockDepth; bool parseInClass; // between BEGINCLASS and ENDCLASS bool parseInProc; // inside a SUB / FUNCTION / Property body bool parseProcIsFunction; // ... a FUNCTION or Property Get (its name sets its result) bool parseProcIsStatic; // ... declared STATIC (its DIMs declare STATIC variables) bool parseInDeclareLib; // inside a DECLARE LIBRARY block (BINARY STRING allowed) const char *parseProcName; // the procedure being parsed (its own name sets its result) const char *parseClassName; // the class module being parsed (module arena; parseInClass) BasWithT *parseWith; // the innermost WITH block being parsed (its '.name's) // Symbols BasScopeTabT moduleTab; // globals, procedures, constants, TYPE / ENUM / class names BasScopeTabT moduleLabels; BasScopeTabT formTab; // the current form's variables (inForm) BasScopeTabT localTab; // the current procedure's parameters and locals (inProc) BasScopeTabT localLabels; BasTypeDefT **typeDefs; // stb_ds, indexed by TYPE id BasClassDefT *classes; // stb_ds, indexed by class number BasWithEventsDefT *withEvents; // stb_ds, binding number order const char **formNames; // stb_ds, every BEGINFORM name (declaration pass) BasSymT **moduleVars; // stb_ds, module / form / member variables in creation order (debug info) BasMemberVarDeclT *memberVarDecls; // stb_ds, class member variables the declaration pass read (registered at its end) BasMemberPatchT *memberPatches; // stb_ds, early-bound member operands to fill in at the end // Scope state (resolver, in source order) bool inForm; bool inClass; bool inProc; bool inDefFn; // a DEF FN body: undeclared names are module variables bool inConstExpr; // a constant expression: only constants may be named const char *formName; // current form ("" outside) int32_t fileIdx; // the project file being compiled (BEGINMODULE / BEGINFORM / BEGINCLASS block; 0 outside them): where a Private CONST / ENUM is seen int32_t outerFileIdx; // fileIdx around the BEGINFORM / BEGINCLASS block being compiled (a class inside a project's module goes back to the module's) int32_t fileCount; // file numbers given out so far int32_t filePrivates; // file-private names declared (lookups try the file's own first while there are any) int32_t classIdx; // current class (inClass) BasSymT *curProc; // procedure being compiled (inProc) const char *curProcName; // its name as written (its result is set by it) uint8_t curProcKind; // its BasMemberKindE bool curProcStatic; // it was declared STATIC: its implicit variables are STATIC int32_t nextGlobalSlot; int32_t nextFormSlot; int32_t nextMemberSlot; int32_t nextLocalSlot; int32_t hiddenCount; // names of compiler variables uint8_t defType[BAS_DEFTYPE_LETTERS]; int32_t optionBase; bool optionExplicit; bool compareText; // OPTION COMPARE TEXT (constant expressions) // Resolver bookkeeping inside a procedure (or the module body) int32_t forDepth; int32_t doDepth; int32_t selectDepth; int32_t lastLabelDepth; // SELECT depth at the label defined last (RETURN pops the ones opened since) int32_t savedForDepth; // the module body's bookkeeping while a procedure is compiled int32_t savedDoDepth; int32_t savedSelectDepth; int32_t savedLabelDepth; BasSymChangeT *symChanges; // stb_ds: the current unit's symbol changes, in source order // Code generation BasCodeGenT cg; int32_t initJmpAddr; // JMP over a form / class set-up block (-1: none) int32_t initCodeStart; // first byte of that block int32_t procSkipJump; // JMP over the procedures defined since the last module code (-1: none) int32_t *tempSlots; // stb_ds: compiler temporaries of the module code (global / form slots) int32_t *procTempSlots; // stb_ds: compiler temporaries of the procedure being generated (local slots) int32_t tempUsed; // temporaries the current statement holds BasGenLoopT *loops; // stb_ds: open loops, innermost last int32_t genSelectDepth; // SELECT test values on the eval stack int32_t *exitProcPatches; // stb_ds: EXIT SUB / FUNCTION / PROPERTY jumps int32_t debugProcCount; // procedures emitted (debugger procIndex) BasVmT *constVm; // evaluates constant expressions (made on first use) const BasCtrlValidatorT *validator; }; // ============================================================ // Errors (compiler.c) // ============================================================ // Records the first error at line / col (col 0: not known). void basErrorAt(BasCompilerT *c, int32_t line, int32_t col, const char *fmt, ...); // Records the first error at a node. void basErrorNode(BasCompilerT *c, const BasNodeT *n, const char *fmt, ...); // ============================================================ // Parser (parse.c, parseExpr.c, parseStmt.c, parseDecl.c) // ============================================================ void basParseAdvance(BasCompilerT *c); BasTokenTypeE basParseAfterParens(BasLexerT *lex); BasNodeT *basParseArgList(BasCompilerT *c, int32_t *outArgc); bool basParseAtEnd(BasCompilerT *c); BasNodeT *basParseAttribute(BasCompilerT *c); BasNodeT *basParseBareArgs(BasCompilerT *c, int32_t *outArgc); BasNodeT *basParseBuiltinCall(BasCompilerT *c, const char *name, BasNodeT *args, int32_t argc, int32_t line, int32_t col); BasNodeT *basParseChain(BasCompilerT *c, BasNodeT *base, bool statement); bool basParseCheck(const BasCompilerT *c, BasTokenTypeE type); bool basParseCheckWord(const BasCompilerT *c, const char *word); BasNodeT *basParseCurLit(BasCompilerT *c, int64_t scaled); void basParseDeclarations(BasCompilerT *c); BasNodeT *basParseDeclStatement(BasCompilerT *c); BasNodeT *basParseDeferredArgs(BasCompilerT *c, BasStmtT *call, BasDeferModeE mode, int32_t *outArgc); void basParseError(BasCompilerT *c, const char *fmt, ...); void basParseErrorExpected(BasCompilerT *c, const char *what); BasNodeT *basParseEvent(BasCompilerT *c); void basParseExpect(BasCompilerT *c, BasTokenTypeE type); void basParseExpectEnd(BasCompilerT *c); BasNodeT *basParseExpr(BasCompilerT *c); bool basParseFriendAhead(const BasCompilerT *c); BasNodeT *basParseFriendProc(BasCompilerT *c); BasNodeT *basParseInputBoxArgs(BasCompilerT *c, int32_t *outArgc); BasNodeT *basParseIntLit(BasCompilerT *c, int32_t value); BasNodeT *basParseIntrinsic(BasCompilerT *c, uint8_t opcode, BasNodeT *args, int32_t argc, int32_t operand); BasNodeT *basParseLValue(BasCompilerT *c, bool allowFields); bool basParseMatch(BasCompilerT *c, BasTokenTypeE type); bool basParseMatchEnd(BasCompilerT *c, BasTokenTypeE kw); BasNodeT *basParseMsgBoxArgs(BasCompilerT *c, int32_t *outArgc); bool basParseNameFollows(BasCompilerT *c, bool anyWord); BasNodeT *basParseNode(BasCompilerT *c, int32_t size, uint8_t kind); BasNodeT *basParseObjectOperand(BasCompilerT *c, BasNodeT *operand); BasTokenTypeE basParsePeekAfterParens(const BasCompilerT *c); BasProcT *basParseProcHeader(BasCompilerT *c, uint8_t memberKind, bool memberName); void basParseSkipNewlines(BasCompilerT *c); BasNodeT *basParseStatement(BasCompilerT *c); BasNodeT *basParseStrLit(BasCompilerT *c, const char *text, int32_t len); char *basParseTokenName(BasCompilerT *c); BasNodeT *basParseUnit(BasCompilerT *c); BasNodeT *basParseWithRef(BasCompilerT *c); // ============================================================ // Resolver (resolve.c, resolveExpr.c) // ============================================================ BasSymT *basAddGlobalVar(BasCompilerT *c, const char *name, uint8_t dataType); BasSymT *basAddLocal(BasCompilerT *c, const char *name, uint8_t kind, uint8_t dataType); BasSymT *basAddLocalVar(BasCompilerT *c, const char *name, uint8_t dataType); BasSymT *basAddModuleVar(BasCompilerT *c, const char *name, uint8_t dataType); BasNodeT *basBindMember(BasCompilerT *c, BasNodeT *obj, int32_t cls, const char *name, BasNodeT *args, int32_t argc, uint8_t access, const BasNodeT *at); const BasBuiltinT *basBuiltinFind(const char *name); int32_t basClassFind(BasCompilerT *c, const char *name); bool basClassKnown(int32_t cls); void basCloseProcScope(BasCompilerT *c); BasNodeT *basControlNode(BasCompilerT *c, const char *name, const BasNodeT *at); bool basConvertsArg(uint8_t dataType, uint8_t paramFlags); void basDeclareClass(BasCompilerT *c, const char *name); uint8_t basDeclaredStoreType(const BasSymT *sym); void basDeclareEnumName(BasCompilerT *c, const char *name, int32_t privateFile); void basDeclareForm(BasCompilerT *c, const char *name); void basDeclareLibrary(BasCompilerT *c, const BasStmtT *s); void basDeclareMemberVars(BasCompilerT *c, const BasStmtT *dim, int32_t classIdx); void basDeclareMemberVarsEnd(BasCompilerT *c); void basDeclareProc(BasCompilerT *c, BasProcT *proc, int32_t classIdx); void basDeclareTypeName(BasCompilerT *c, const char *name); void basDeclareUserControlVar(BasCompilerT *c, int32_t classIdx); BasSymT *basEnsureVariable(BasCompilerT *c, const char *name, const BasNodeT *at); int32_t basExprClass(const BasCompilerT *c, const BasNodeT *n); int32_t basExprUdtType(const BasCompilerT *c, const BasNodeT *n); int32_t basFieldIndex(const BasTypeDefT *td, const char *name); bool basFilePrivateName(const BasCompilerT *c, const char *name, int32_t fileIdx, char *out, int32_t outSize); uint8_t basImplicitType(const BasCompilerT *c, const char *name, bool *outTyped); bool basIsDefFnName(const char *name); bool basIsFormName(const BasCompilerT *c, const char *name); bool basLateArgs(BasCompilerT *c, BasCallT *call, BasNodeT *args, int32_t argc, bool byRef); BasNodeT *basLoadFormNode(BasCompilerT *c, const char *name, const BasNodeT *at); BasSymT *basLookup(BasCompilerT *c, const char *name); BasSymT *basLookupModuleVar(BasCompilerT *c, const char *name); BasSymT *basLookupProc(BasCompilerT *c, const char *name); BasSymT *basModuleFind(const BasCompilerT *c, const char *name); BasNodeT *basNamedArgs(BasCompilerT *c, const char *const *names, int32_t count, BasNodeT *args, const BasNodeT *at); BasNodeT *basNodeConst(BasCompilerT *c, const BasConstValT *v, const BasNodeT *at); BasNodeT *basNodeConv(BasCompilerT *c, BasNodeT *a, uint8_t op, int32_t aux); BasNodeT *basNodeCur(BasCompilerT *c, int64_t scaled, const BasNodeT *at); BasNodeT *basNodeInt(BasCompilerT *c, int32_t value, uint8_t type, const BasNodeT *at); BasNodeT *basNodeIntrinsic(BasCompilerT *c, uint8_t opcode, BasNodeT *args, int32_t argc, int32_t operand, int32_t line, int32_t col); BasNodeT *basNodeSpecial(BasCompilerT *c, int32_t kind, const BasNodeT *at); BasNodeT *basNodeStr(BasCompilerT *c, const char *text, int32_t len, const BasNodeT *at); BasNodeT *basNodeVar(BasCompilerT *c, BasSymT *sym, const BasNodeT *at); BasNodeT *basNodeZero(BasCompilerT *c, uint8_t dataType, const BasNodeT *at); BasSymT *basPropertyProc(BasCompilerT *c, const char *name, bool isSet); bool basQualify(const BasCompilerT *c, int32_t classIdx, const char *name, char *out, int32_t outSize); bool basRejectHiddenModuleVar(BasCompilerT *c, const char *name, const BasNodeT *at); BasNodeT *basResolveArg(BasCompilerT *c, BasNodeT *arg, bool byRef, uint8_t *outRefType); void basResolveBody(BasCompilerT *c, BasNodeT *list); BasNodeT *basResolveCallee(BasCompilerT *c, BasCallT *call, bool statement); void basResolveDefType(BasCompilerT *c, const BasStmtT *s); BasNodeT *basResolveExpr(BasCompilerT *c, BasNodeT *n, uint8_t use); BasNodeT *basResolveLValue(BasCompilerT *c, BasNodeT *n, bool allowFields); BasNodeT *basResolveMemberParts(BasCompilerT *c, BasMemberT *m, bool isProp, BasNodeT **outObj, int32_t *outClass); BasNodeT *basResolveMethodArgs(BasCompilerT *c, BasNodeT *args, int32_t argc, bool byRef); void basResolveModuleEnd(BasCompilerT *c); BasNodeT *basResolveObjectMember(BasCompilerT *c, BasNodeT *obj, const char *name, int32_t memberClass, uint16_t flags, const BasNodeT *at); BasNodeT *basResolveProcArgs(BasCompilerT *c, const BasSymT *sym, BasNodeT *args, int32_t valueParams, const BasNodeT *at, int32_t *outArgc); void basResolveStatement(BasCompilerT *c, BasNodeT *s); bool basResolveTypeSpec(BasCompilerT *c, const BasTypeSpecT *t, bool prescan, uint8_t *outType, int32_t *outUdt, int32_t *outClass); void basResolveUnit(BasCompilerT *c, BasNodeT *unit); void basResolveUnitEnd(BasCompilerT *c, BasNodeT *unit); BasSymT *basStaticVariable(BasCompilerT *c, const char *name, uint8_t dataType, bool isTyped, int32_t objClass, int32_t fixedLen, const BasNodeT *at, BasSymT **outSlot); BasScopeE basStorageScope(const BasSymT *sym); void basSymChange(BasCompilerT *c, BasSymT *sym, const BasNodeT *at, uint8_t dataType, int32_t udtTypeId, uint32_t flags); void basSymChangesUndo(BasCompilerT *c); BasNodeT *basTypedArg(BasCompilerT *c, const char *procName, int32_t idx, uint8_t dataType, bool byVal, BasNodeT *arg); BasSymT *basUserControlProc(const BasCompilerT *c, int32_t classIdx, int32_t evt); bool basValidateCtrlMember(BasCompilerT *c, const char *ctrlName, const char *member, bool isProp, const BasNodeT *at); BasNodeT *basWithObject(BasCompilerT *c, const BasNodeT *ref); // ============================================================ // Types and folding (typecheck.c, fold.c) // ============================================================ bool basConstConvert(BasCompilerT *c, BasConstValT *v, uint8_t asType, const char *what, const BasNodeT *at); bool basFoldConstExpr(BasCompilerT *c, BasNodeT *expr, BasConstValT *out); BasNodeT *basFoldConv(BasCompilerT *c, BasNodeT *value, uint8_t op); BasNodeT *basFoldExpr(BasCompilerT *c, BasNodeT *n); bool basStartsTyped(uint8_t dataType); uint8_t basStaticType(const BasNodeT *n); void basTypeUnit(BasCompilerT *c, BasNodeT *unit); // ============================================================ // Generator (gen.c, genExpr.c, genStmt.c) // ============================================================ uint8_t basBinaryOpcode(uint8_t tok); void basGenAddrOf(BasCompilerT *c, const BasSymT *sym); void basGenArgs(BasCompilerT *c, const BasNodeT *list); void basGenBody(BasCompilerT *c, const BasNodeT *list); void basGenCall(BasCompilerT *c, BasSymT *sym, int32_t argc); void basGenDeclaration(BasCompilerT *c, const BasNodeT *s); void basGenExpr(BasCompilerT *c, const BasNodeT *n); void basGenFlushProcSkip(BasCompilerT *c); int32_t basGenJump(BasCompilerT *c, uint8_t op); void basGenJumpTo(BasCompilerT *c, uint8_t op, int32_t target); void basGenLine(BasCompilerT *c, const BasNodeT *s); void basGenLoadTemp(BasCompilerT *c, int32_t slot); void basGenLoadVar(BasCompilerT *c, const BasSymT *sym); void basGenNew(BasCompilerT *c, const char *name, int32_t objClass); void basGenObjMember(BasCompilerT *c, uint8_t op, const BasCallT *call); void basGenPatchHere(BasCompilerT *c, int32_t operandPos); void basGenPushCStr(BasCompilerT *c, const char *text); void basGenPushInt16(BasCompilerT *c, int16_t v); void basGenPushSpecial(BasCompilerT *c, uint8_t kind); void basGenPushStr(BasCompilerT *c, const char *text, int32_t len); void basGenRef(BasCompilerT *c, const BasNodeT *n); void basGenSlotRef(BasCompilerT *c, int32_t scope, int32_t slot, uint8_t storeType); void basGenStatement(BasCompilerT *c, const BasNodeT *s); void basGenStore(BasCompilerT *c, const BasSymT *sym); void basGenStoreConv(BasCompilerT *c, uint8_t dataType); void basGenStoreFrom(BasCompilerT *c, const BasSymT *sym, uint8_t valueType); void basGenStoreRaw(BasCompilerT *c, const BasSymT *sym); void basGenStoreSlot(BasCompilerT *c, int32_t scope, int32_t slot, uint8_t conv); void basGenStoreTemp(BasCompilerT *c, int32_t slot); uint8_t basGenStoreValue(BasCompilerT *c, const BasNodeT *value, uint8_t convType, int32_t fixedLen, int32_t objClass, bool isSet, bool deferConv); void basGenSymChanges(BasCompilerT *c, const BasNodeT *at); int32_t basGenTemp(BasCompilerT *c); void basGenTempRef(BasCompilerT *c); void basGenTempReset(BasCompilerT *c); bool basGenUdtLayout(BasCompilerT *c, int32_t typeId); bool basGenUdtSpec(BasCompilerT *c, int32_t typeId); #endif // DVXBASIC_FRONT_H