├── .changeset ├── README.md └── config.json ├── .commitlintrc.ts ├── .eslintrc.yml ├── .github └── workflows │ ├── deploy-site.yml │ └── test.yml ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── LICENSE.md ├── README.md ├── apps ├── cli │ ├── .changeset │ │ ├── README.md │ │ └── config.json │ ├── .eslintrc.yml │ ├── .npmignore │ ├── CHANGELOG.md │ ├── jest.config.mjs │ ├── package.json │ ├── src │ │ ├── NodeFsIncludeResolver.ts │ │ └── index.ts │ ├── tsconfig.json │ └── webpack.config.js ├── machine │ ├── .changeset │ │ ├── README.md │ │ └── config.json │ ├── .eslintrc.yml │ ├── .npmignore │ ├── CHANGELOG.md │ ├── jest.config.mjs │ ├── package.json │ ├── src │ │ ├── client │ │ │ ├── client.tsx │ │ │ ├── index.ts │ │ │ └── screen │ │ │ │ ├── Screen.styled.tsx │ │ │ │ ├── Screen.tsx │ │ │ │ └── index.ts │ │ └── server │ │ │ ├── getManifestJSON.ts │ │ │ ├── index.ts │ │ │ └── server.ts │ ├── tsconfig.json │ └── webpack.config.js └── site │ ├── .eslintrc.yml │ ├── CHANGELOG.md │ ├── astro.config.mjs │ ├── package.json │ ├── public │ └── favicon.svg │ ├── src │ ├── env.d.ts │ ├── helpers │ │ ├── index.ts │ │ └── shallowCompareArrays.ts │ ├── hooks │ │ ├── index.ts │ │ ├── useInstantBeforeMount.ts │ │ └── useInstantUpdateEffect.ts │ ├── i18n │ │ ├── I18nProvider.ts │ │ ├── index.ts │ │ └── packs │ │ │ ├── en.ts │ │ │ └── index.ts │ ├── modules │ │ ├── Editor │ │ │ ├── EditorContainer.tsx │ │ │ ├── EditorHeader │ │ │ │ ├── EditorCompilationToolbar.tsx │ │ │ │ ├── EditorEmulationToolbar.tsx │ │ │ │ ├── EditorHeader.tsx │ │ │ │ ├── EditorLinksToolbar.tsx │ │ │ │ ├── index.ts │ │ │ │ └── parts │ │ │ │ │ ├── EditorCompileLangDropdown.tsx │ │ │ │ │ └── index.ts │ │ │ ├── EditorInput │ │ │ │ ├── EditorInput.module.scss │ │ │ │ ├── EditorInput.tsx │ │ │ │ ├── index.ts │ │ │ │ └── syntax │ │ │ │ │ ├── index.ts │ │ │ │ │ └── nasmCodemirrorSyntaxDefine.ts │ │ │ ├── EditorOutput │ │ │ │ ├── EditorOutput.tsx │ │ │ │ ├── EditorOutputBinaryTab │ │ │ │ │ ├── EditorOutputBinaryTab.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── utils │ │ │ │ │ │ ├── highlightInstructionHTML.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ ├── EditorOutputErrorsTab │ │ │ │ │ ├── EditorOutputErrorsTab.tsx │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── EditorRoot.tsx │ │ │ ├── EditorScreen │ │ │ │ ├── EditorScreen.tsx │ │ │ │ └── index.ts │ │ │ ├── EditorSidebar │ │ │ │ ├── EditorSidebar.tsx │ │ │ │ └── index.ts │ │ │ ├── EditorStateProvider │ │ │ │ ├── EditorStateProvider.ts │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ └── index.ts │ │ └── index.ts │ ├── pages │ │ └── index.astro │ ├── styles │ │ ├── index.scss │ │ └── reset.scss │ └── types │ │ ├── index.ts │ │ └── nullable.type.ts │ ├── tailwind.config.mjs │ └── tsconfig.json ├── assets ├── index.html ├── kernels │ ├── .bochsrc │ ├── asm │ │ ├── bootsec.asm │ │ ├── dateTime.asm │ │ ├── interrupt.asm │ │ └── speaker.asm │ └── build.sh └── videomodes.txt ├── config ├── jest-extensions │ └── file-transformer.js ├── jest.shared.config.mjs ├── rollup.shared.config.mjs └── webpack.config.js ├── doc ├── asm │ └── ANSI C grammar (Yacc).html ├── editor.png ├── logo.png ├── repl.png ├── screen-10.png ├── screen-11.png ├── screen-12.png ├── screen-13.png ├── screen-2.png ├── screen-3.png ├── screen-4.png ├── screen-5.png ├── screen-6.png ├── screen-7.png ├── screen-8.png ├── screen-9.png └── screen.gif ├── package.json ├── packages ├── compiler-core │ ├── .eslintrc.yml │ ├── CHANGELOG.md │ ├── jest.config.mjs │ ├── package.json │ ├── rollup.config.mjs │ ├── src │ │ ├── constants.ts │ │ ├── decorators │ │ │ ├── index.ts │ │ │ ├── logMethod.ts │ │ │ ├── memoizeMethod.ts │ │ │ └── wrapMethod.ts │ │ ├── index.ts │ │ ├── interfaces │ │ │ ├── IsEmpty.ts │ │ │ ├── IsEqual.ts │ │ │ ├── IsPrintable.ts │ │ │ └── index.ts │ │ ├── monads │ │ │ ├── Identity.ts │ │ │ └── index.ts │ │ ├── shared │ │ │ ├── CodeTranslatedError.ts │ │ │ ├── CompilerError.ts │ │ │ ├── Observable.ts │ │ │ ├── UnionStruct.ts │ │ │ └── index.ts │ │ ├── types.ts │ │ └── utils │ │ │ ├── IEEE754.ts │ │ │ ├── appendToMapKeyArray.ts │ │ │ ├── arrayToHexString.ts │ │ │ ├── asap.ts │ │ │ ├── assertUnreachable.ts │ │ │ ├── bits.ts │ │ │ ├── concatNonEmptyStrings.ts │ │ │ ├── createTiming.ts │ │ │ ├── dropFromHashQueue.ts │ │ │ ├── dropNewLines.ts │ │ │ ├── extractNthByte.ts │ │ │ ├── findByProp.ts │ │ │ ├── flipMap.ts │ │ │ ├── flipObject.ts │ │ │ ├── format.ts │ │ │ ├── fp-ts │ │ │ ├── index.ts │ │ │ ├── tap-either-error.ts │ │ │ ├── tap-either.ts │ │ │ ├── try-reduce-eithers.ts │ │ │ └── unwrap-either-or-throw.ts │ │ │ ├── genUUID.ts │ │ │ ├── index.ts │ │ │ ├── mapMapValues.ts │ │ │ ├── mapObjectKeys.ts │ │ │ ├── memoizeOne.ts │ │ │ ├── mergeNumberBytes.ts │ │ │ ├── mutableOmitChildKeys.ts │ │ │ ├── numberByteSize.ts │ │ │ ├── padLeftLines.ts │ │ │ ├── removeNullValues.ts │ │ │ ├── replaceEscapeSequences.ts │ │ │ ├── safeArray.ts │ │ │ ├── safeFirstMatch.ts │ │ │ ├── serializers │ │ │ ├── dumpAttributesToString.ts │ │ │ ├── dumpCompilerAttrs.ts │ │ │ └── index.ts │ │ │ ├── setCharAt.ts │ │ │ ├── shallowDiffers.ts │ │ │ ├── stripNonPrintableCharacters.ts │ │ │ ├── tagFunction.ts │ │ │ ├── trimLines.ts │ │ │ ├── truncateText.ts │ │ │ └── wrapAround.ts │ └── tsconfig.json ├── compiler-grammar │ ├── .eslintrc.yml │ ├── CHANGELOG.md │ ├── jest.config.mjs │ ├── package.json │ ├── rollup.config.mjs │ ├── src │ │ ├── Grammar.ts │ │ ├── GrammarError.ts │ │ ├── decorators │ │ │ ├── index.ts │ │ │ └── walkOverFields.ts │ │ ├── index.ts │ │ ├── matchers │ │ │ ├── empty.ts │ │ │ └── index.ts │ │ ├── tree │ │ │ ├── AbstractTreeVisitor.ts │ │ │ ├── NodeLocation.ts │ │ │ ├── TokensIterator.ts │ │ │ ├── TreeGroupedVisitor.ts │ │ │ ├── TreeNode.ts │ │ │ ├── TreePrintVisitor.ts │ │ │ ├── TreeVisitor.ts │ │ │ └── index.ts │ │ ├── utils │ │ │ ├── createBinOpIfBothSidesPresent.ts │ │ │ ├── eatLeftRecursiveOperators.ts │ │ │ ├── fetchTokensUntil.ts │ │ │ ├── fetchTokensUntilEOL.ts │ │ │ └── index.ts │ │ └── visitors │ │ │ ├── ReducePostifxOperatorsVisitor.ts │ │ │ └── index.ts │ └── tsconfig.json ├── compiler-lexer │ ├── .eslintrc.yml │ ├── CHANGELOG.md │ ├── jest.config.mjs │ ├── package.json │ ├── rollup.config.mjs │ ├── src │ │ ├── index.ts │ │ ├── lexer.ts │ │ ├── safeResultLexer.ts │ │ ├── shared │ │ │ ├── LexerError.ts │ │ │ ├── TokenLocation.ts │ │ │ ├── TokenTypes.ts │ │ │ └── index.ts │ │ ├── tokens │ │ │ ├── Token.ts │ │ │ ├── index.ts │ │ │ └── types │ │ │ │ ├── FloatNumberToken.ts │ │ │ │ ├── IdentifierToken.ts │ │ │ │ ├── NumberToken.ts │ │ │ │ └── index.ts │ │ └── utils │ │ │ ├── extractNestableTokensList.ts │ │ │ ├── index.ts │ │ │ ├── isEOFToken.ts │ │ │ ├── isFloatMathOpToken.ts │ │ │ ├── isLineTerminatorToken.ts │ │ │ ├── isLogicOpToken.ts │ │ │ ├── isMathOpToken.ts │ │ │ ├── isNonIdentifierKeywordToken.ts │ │ │ ├── isNumericToken.ts │ │ │ ├── isRelationOpToken.ts │ │ │ ├── joinTokensTexts.ts │ │ │ ├── matchCharacter.ts │ │ │ └── parseNumberToken.ts │ └── tsconfig.json ├── compiler-pico-c │ ├── .eslintrc.yml │ ├── CHANGELOG.md │ ├── jest.config.mjs │ ├── package.json │ ├── rollup.config.mjs │ ├── src │ │ ├── arch │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── x86 │ │ │ │ ├── asm-utils │ │ │ │ ├── genComment.ts │ │ │ │ ├── genDefConst.ts │ │ │ │ ├── genInstruction.ts │ │ │ │ ├── genLabel.ts │ │ │ │ ├── genLabeledInstruction.ts │ │ │ │ ├── genMemAddress.ts │ │ │ │ ├── index.ts │ │ │ │ └── wrapWithX86BootsectorAsm.ts │ │ │ │ ├── backend │ │ │ │ ├── X86Allocator.ts │ │ │ │ ├── X86ArchBackend.ts │ │ │ │ ├── X86LabelsResolver.ts │ │ │ │ ├── X86StackFrame.ts │ │ │ │ ├── call-conventions │ │ │ │ │ ├── X86ConventionalFnCaller.ts │ │ │ │ │ ├── X86StdcallFnCaller.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── compilers │ │ │ │ │ ├── asm │ │ │ │ │ │ ├── compileAsmClobbers.ts │ │ │ │ │ │ ├── compileAsmInputs.ts │ │ │ │ │ │ ├── compileAsmInstruction.ts │ │ │ │ │ │ ├── compileAsmOutputs.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── builtin │ │ │ │ │ │ ├── compileBuiltinAlloca.ts │ │ │ │ │ │ ├── compileBuiltinCallFn.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── va │ │ │ │ │ │ │ ├── compileBuiltinVaArg.ts │ │ │ │ │ │ │ ├── compileBuiltinVaStart.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── compileAllocInstruction.ts │ │ │ │ │ ├── compileAssignInstruction.ts │ │ │ │ │ ├── compileCallInstruction.ts │ │ │ │ │ ├── compileCastInstruction.ts │ │ │ │ │ ├── compileFnDeclInstructionsBlock.ts │ │ │ │ │ ├── compileICmpInstruction.ts │ │ │ │ │ ├── compileInstructionsBlock.ts │ │ │ │ │ ├── compileJmpInstruction.ts │ │ │ │ │ ├── compileLabelInstruction.ts │ │ │ │ │ ├── compileLabelOffsetInstruction.ts │ │ │ │ │ ├── compileLeaInstruction.ts │ │ │ │ │ ├── compileLoadInstruction.ts │ │ │ │ │ ├── compilePhiInstruction.ts │ │ │ │ │ ├── compileRetInstruction.ts │ │ │ │ │ ├── compileStoreInstruction.ts │ │ │ │ │ ├── data │ │ │ │ │ │ ├── compileArrayInitializerDef.ts │ │ │ │ │ │ ├── compileDataSegment.ts │ │ │ │ │ │ ├── compileDefDataInstruction.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── math │ │ │ │ │ │ ├── compileMathInstruction.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── int │ │ │ │ │ │ │ ├── compileIntMathInstruction.ts │ │ │ │ │ │ │ ├── compileIntMathSingleInstruction.ts │ │ │ │ │ │ │ ├── ensureFunctionNotOverrideOutput.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── isNopMathInstruction.ts │ │ │ │ │ │ └── x87 │ │ │ │ │ │ │ ├── compileX87MathInstruction.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── shared │ │ │ │ │ │ ├── X86CompileInstructionOutput.ts │ │ │ │ │ │ ├── X86ConventionalFnCaller.ts │ │ │ │ │ │ ├── compileMemcpy.ts │ │ │ │ │ │ ├── compileStackMemcpy.ts │ │ │ │ │ │ └── index.ts │ │ │ │ ├── reg-allocator │ │ │ │ │ ├── X86VarLifetimeGraph.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── int │ │ │ │ │ │ ├── X86BasicRegAllocator.ts │ │ │ │ │ │ ├── X86RegOwnershipTracker.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── ownership.ts │ │ │ │ │ ├── mem │ │ │ │ │ │ ├── X86MemOwnershipTracker.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── ownership.ts │ │ │ │ │ └── x87 │ │ │ │ │ │ ├── X87BasicRegAllocator.ts │ │ │ │ │ │ ├── X87RegOwnershipTracker.ts │ │ │ │ │ │ └── index.ts │ │ │ │ ├── utils │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── queryAndMarkX86RegsMap.ts │ │ │ │ │ ├── queryX86RegsMap.ts │ │ │ │ │ ├── recursiveSetAvailabilityInX86RegMap.ts │ │ │ │ │ ├── recursiveX86RegMapLookup.ts │ │ │ │ │ └── restoreInX86IntRegsMap.ts │ │ │ │ └── variables │ │ │ │ │ ├── X86Label.ts │ │ │ │ │ ├── X86StackOffset.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── constants │ │ │ │ ├── regs.ts │ │ │ │ └── types.ts │ │ │ │ ├── index.ts │ │ │ │ └── modes │ │ │ │ └── 16bit │ │ │ │ ├── index.ts │ │ │ │ └── sizeofPrimitiveType.ts │ │ ├── backend │ │ │ ├── abstract │ │ │ │ └── CAbstractArchBackend.ts │ │ │ ├── constants │ │ │ │ └── types.ts │ │ │ ├── errors │ │ │ │ └── CBackendError.ts │ │ │ ├── index.ts │ │ │ └── safeGenAsmIRCode.ts │ │ ├── builtins │ │ │ ├── CBuiltinFnDeclType.ts │ │ │ ├── createBuiltinAnalyzeScope.ts │ │ │ ├── defs │ │ │ │ ├── Alloca.builtin.ts │ │ │ │ ├── index.ts │ │ │ │ └── va │ │ │ │ │ ├── VaArgFn.builtin.ts │ │ │ │ │ ├── VaEndFn.builtin.ts │ │ │ │ │ ├── VaList.builtin.ts │ │ │ │ │ ├── VaStartFn.builtin.ts │ │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ └── utils │ │ │ │ ├── builtinPrefix.ts │ │ │ │ └── index.ts │ │ ├── ccompiler.ts │ │ ├── constants │ │ │ ├── config.ts │ │ │ ├── index.ts │ │ │ └── lang.ts │ │ ├── frontend │ │ │ ├── analyze │ │ │ │ ├── ast │ │ │ │ │ ├── expression-eval │ │ │ │ │ │ ├── evalConstantExpression.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── visitors │ │ │ │ │ │ │ └── ConstantExpressionEvalVisitor.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── initializer-builder │ │ │ │ │ │ ├── CVariableInitializerPrintVisitor.ts │ │ │ │ │ │ ├── CVariableInitializerVisitor.ts │ │ │ │ │ │ ├── builder │ │ │ │ │ │ │ └── CTypeInitializerBuilderVisitor.ts │ │ │ │ │ │ ├── extractor │ │ │ │ │ │ │ └── extractInitializerTreeForType.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── type-builder │ │ │ │ │ │ ├── CInnerTypeTreeVisitor.ts │ │ │ │ │ │ ├── CTypeAnalyzeContext.ts │ │ │ │ │ │ ├── CTypeAnalyzeVisitor.ts │ │ │ │ │ │ ├── builder │ │ │ │ │ │ └── CTreeTypeBuilderVisitor.ts │ │ │ │ │ │ ├── constants │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ ├── creators │ │ │ │ │ │ ├── ASTCAssignmentExpressionTypeCreator.ts │ │ │ │ │ │ ├── ASTCBinaryOpTypeCreator.ts │ │ │ │ │ │ ├── ASTCCastExpressionTypeCreator.ts │ │ │ │ │ │ ├── ASTCCastUnaryExpressionTypeCreator.ts │ │ │ │ │ │ ├── ASTCCompoundExpressionTypeCreator.ts │ │ │ │ │ │ ├── ASTCConditionalTypeCreator.ts │ │ │ │ │ │ ├── ASTCDeclarationTypeCreator.ts │ │ │ │ │ │ ├── ASTCDoWhileStmtTypeCreator.ts │ │ │ │ │ │ ├── ASTCExpressionStmtTypeCreator.ts │ │ │ │ │ │ ├── ASTCExpressionTypeCreator.ts │ │ │ │ │ │ ├── ASTCForStmtTypeCreator.ts │ │ │ │ │ │ ├── ASTCFunctionDefTypeCreator.ts │ │ │ │ │ │ ├── ASTCIfStmtTypeCreator.ts │ │ │ │ │ │ ├── ASTCInitializerTypeCreator.ts │ │ │ │ │ │ ├── ASTCPostfixExpressionTypeCreator.ts │ │ │ │ │ │ ├── ASTCPrimaryExpressionTypeCreator.ts │ │ │ │ │ │ ├── ASTCReturnStmtTypeCreator.ts │ │ │ │ │ │ ├── ASTCSizeofUnaryExpressionTypeCreator.ts │ │ │ │ │ │ ├── ASTCTypeCreator.ts │ │ │ │ │ │ ├── ASTCTypeNameTypeCreator.ts │ │ │ │ │ │ ├── ASTCUnaryExpressionTypeCreator.ts │ │ │ │ │ │ ├── ASTCWhileStmtTypeCreator.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── extractor │ │ │ │ │ │ ├── extractEnumTypeFromNode.ts │ │ │ │ │ │ ├── extractInitDeclaratorTypeVariables.ts │ │ │ │ │ │ ├── extractSpecifierType.ts │ │ │ │ │ │ ├── extractStructTypeFromNode.ts │ │ │ │ │ │ ├── extractUnionTypeFromNode.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── index.ts │ │ │ │ ├── casts │ │ │ │ │ ├── castToBaseTypeIfPointer.ts │ │ │ │ │ ├── castToPointerIfArray.ts │ │ │ │ │ ├── castToPointerIfFunction.ts │ │ │ │ │ ├── charToInt.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── tryCastToPointer.ts │ │ │ │ ├── checker │ │ │ │ │ ├── checkLeftTypeOverlapping.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── isPointerArithmeticOperator.ts │ │ │ │ ├── constants │ │ │ │ │ ├── bitmaps.ts │ │ │ │ │ ├── config.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── dump │ │ │ │ │ └── CScopePrintVisitor.ts │ │ │ │ ├── errors │ │ │ │ │ └── CTypeCheckError.ts │ │ │ │ ├── index.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── IsNewScopeASTNode.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── safeBuildTypedTree.tsx │ │ │ │ ├── scope │ │ │ │ │ ├── CFunctionScope.ts │ │ │ │ │ ├── CScopeTree.ts │ │ │ │ │ ├── CScopeVisitor.ts │ │ │ │ │ ├── CTypedef.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── variables │ │ │ │ │ │ ├── CNamedTypedEntry.ts │ │ │ │ │ │ ├── CVariable.ts │ │ │ │ │ │ ├── CVariableInitializerTree.ts │ │ │ │ │ │ └── index.ts │ │ │ │ ├── types │ │ │ │ │ ├── CArrayType.ts │ │ │ │ │ ├── CEnumType.ts │ │ │ │ │ ├── CFlagType.ts │ │ │ │ │ ├── CPointerType.ts │ │ │ │ │ ├── CPrimitiveType.ts │ │ │ │ │ ├── CType.ts │ │ │ │ │ ├── CUnknownType.ts │ │ │ │ │ ├── function │ │ │ │ │ │ ├── CFunctionDeclType.ts │ │ │ │ │ │ ├── CFunctionSpecifierMonad.ts │ │ │ │ │ │ ├── CFunctionStorageClassMonad.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── struct │ │ │ │ │ │ ├── CStructType.ts │ │ │ │ │ │ ├── align │ │ │ │ │ │ │ ├── getPackedAlignEntryOffset.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── constants │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── union │ │ │ │ │ │ ├── CUnionType.ts │ │ │ │ │ │ ├── constants │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── utils │ │ │ │ │ │ ├── getBaseType.ts │ │ │ │ │ │ ├── getBaseTypeIfArray.ts │ │ │ │ │ │ ├── getBaseTypeIfPtr.ts │ │ │ │ │ │ ├── getSourceNonArrayType.ts │ │ │ │ │ │ ├── getSourceNonPtrType.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── isImplicitPtrType.ts │ │ │ │ │ │ └── typeofValueOrNode.ts │ │ │ │ └── utils │ │ │ │ │ ├── bitsetToKeywords.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── isNamedType.ts │ │ │ │ │ └── parseKeywordsToBitset.ts │ │ │ ├── cIRcompiler.ts │ │ │ ├── index.ts │ │ │ ├── ir │ │ │ │ ├── constants │ │ │ │ │ ├── config.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── ir.ts │ │ │ │ ├── dump │ │ │ │ │ ├── IRResultView.ts │ │ │ │ │ ├── getIRTypeDisplayName.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── errors │ │ │ │ │ └── IRError.ts │ │ │ │ ├── generator │ │ │ │ │ ├── IRGeneratorGlobalVisitor.ts │ │ │ │ │ ├── IRGlobalVariablesMap.ts │ │ │ │ │ ├── IRGotoLabelsFactory.ts │ │ │ │ │ ├── IRLabelsFactory.ts │ │ │ │ │ ├── IRVariableAllocator.ts │ │ │ │ │ ├── emitters │ │ │ │ │ │ ├── emit-expr │ │ │ │ │ │ │ ├── emitCompoundExpressionStmtIR.ts │ │ │ │ │ │ │ ├── emitConditionalExpressionIR.ts │ │ │ │ │ │ │ ├── emitExpressionIR.ts │ │ │ │ │ │ │ ├── emitLogicBinaryJmpExpressionIR.ts │ │ │ │ │ │ │ ├── emitLogicExpressionIR.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── emit-fn-call-expression │ │ │ │ │ │ │ ├── emitFnArgsLoadIR.ts │ │ │ │ │ │ │ ├── emitFnCallExpressionIR.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── emit-fn │ │ │ │ │ │ │ ├── emitBlockItemIR.ts │ │ │ │ │ │ │ ├── emitFunctionIR.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── emit-initializer │ │ │ │ │ │ │ ├── emitVariableInitializerIR.ts │ │ │ │ │ │ │ ├── emitVariableLoadInitializerIR.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── literal │ │ │ │ │ │ │ │ ├── emitStringLiteralBlobLocalInitializerIR.ts │ │ │ │ │ │ │ │ ├── emitStringLiteralPtrInitializerIR.ts │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── shouldEmitStringPtrInitializer.ts │ │ │ │ │ │ ├── emit-while-stmt │ │ │ │ │ │ │ ├── emitDoWhileStmtIR.ts │ │ │ │ │ │ │ ├── emitWhileStmtIR.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── emitAsmStatementIR.ts │ │ │ │ │ │ ├── emitAssignmentIR.ts │ │ │ │ │ │ ├── emitCastIR.ts │ │ │ │ │ │ ├── emitDeclarationIR.ts │ │ │ │ │ │ ├── emitExpressionStmtIR.ts │ │ │ │ │ │ ├── emitForStmtIR.ts │ │ │ │ │ │ ├── emitGlobalDeclarationsIR.ts │ │ │ │ │ │ ├── emitGotoStmtIR.ts │ │ │ │ │ │ ├── emitIdentifierGetterIR.ts │ │ │ │ │ │ ├── emitIfStmtIR.ts │ │ │ │ │ │ ├── emitIncExpressionIR.ts │ │ │ │ │ │ ├── emitLabeledStmtIR.ts │ │ │ │ │ │ ├── emitPointerAddressExpression.ts │ │ │ │ │ │ ├── emitSwitchStmtIR.ts │ │ │ │ │ │ ├── emitUnaryLoadPointerValueIR.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── types.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── segments │ │ │ │ │ │ ├── IRDataSegmentBuilder.ts │ │ │ │ │ │ ├── IRFlatCodeSegmentBuilder.ts │ │ │ │ │ │ ├── IRSegmentBuilder.ts │ │ │ │ │ │ └── index.ts │ │ │ │ ├── guards │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── isIRBranchInstruction.ts │ │ │ │ │ ├── isIRLabeledInstruction.ts │ │ │ │ │ └── isIROutputInstruction.ts │ │ │ │ ├── index.ts │ │ │ │ ├── instructions │ │ │ │ │ ├── IRAllocInstruction.ts │ │ │ │ │ ├── IRAsmInstruction.ts │ │ │ │ │ ├── IRAssignInstruction.ts │ │ │ │ │ ├── IRBrInstruction.ts │ │ │ │ │ ├── IRCallInstruction.ts │ │ │ │ │ ├── IRCastInstruction.ts │ │ │ │ │ ├── IRCommentInstruction.ts │ │ │ │ │ ├── IRDefDataInstruction.ts │ │ │ │ │ ├── IRFnDeclInstruction.ts │ │ │ │ │ ├── IRFnEndDeclInstruction.ts │ │ │ │ │ ├── IRICmpInstruction.ts │ │ │ │ │ ├── IRInstruction.ts │ │ │ │ │ ├── IRInstructionsBlock.ts │ │ │ │ │ ├── IRJmpInstruction.ts │ │ │ │ │ ├── IRLabelInstruction.ts │ │ │ │ │ ├── IRLabelOffsetInstruction.ts │ │ │ │ │ ├── IRLeaInstruction.ts │ │ │ │ │ ├── IRLoadInstruction.ts │ │ │ │ │ ├── IRMathInstruction.ts │ │ │ │ │ ├── IRMathSingleArgInstruction.ts │ │ │ │ │ ├── IROpInstruction.ts │ │ │ │ │ ├── IRPhiInstruction.ts │ │ │ │ │ ├── IRRetInstruction.ts │ │ │ │ │ ├── IRStoreInstruction.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── interfaces │ │ │ │ │ ├── HasLabeledBranches.ts │ │ │ │ │ ├── IsLabeledInstruction.ts │ │ │ │ │ ├── IsOutputInstruction.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── iterator │ │ │ │ │ ├── IRBlockIterator.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── optimizer │ │ │ │ │ ├── block │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── optimizeInstructionsBlock.ts │ │ │ │ │ │ ├── optimizeInstructionsList.ts │ │ │ │ │ │ ├── phases │ │ │ │ │ │ │ ├── concatConstantStoreInstructions.ts │ │ │ │ │ │ │ ├── dropConstantBranchInstructions.ts │ │ │ │ │ │ │ ├── dropConstantLabelOffsetsArgs.ts │ │ │ │ │ │ │ ├── dropDeadStoreInstructions.ts │ │ │ │ │ │ │ ├── dropInstructionsWithOrphanOutputs.ts │ │ │ │ │ │ │ ├── dropOrConcatConstantInstructions.ts │ │ │ │ │ │ │ ├── dropRedundantAddressInstructions.ts │ │ │ │ │ │ │ ├── dropRedundantLabelInstructions.ts │ │ │ │ │ │ │ ├── dropRedundantLoadInstructions.ts │ │ │ │ │ │ │ ├── dropUselessBranchJmps.ts │ │ │ │ │ │ │ ├── flipMathInstructionsOperands.ts │ │ │ │ │ │ │ ├── foldAddressOffsetsInstructions.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── reassignPhiInstructions.ts │ │ │ │ │ │ └── utils │ │ │ │ │ │ │ ├── dropConstantInstructionArgs.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── tryConcatMathInstructions.ts │ │ │ │ │ │ │ └── tryEvalConstArgsBinaryInstruction.ts │ │ │ │ │ ├── constants │ │ │ │ │ │ └── types.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── optimizeIRResult.ts │ │ │ │ │ └── segment │ │ │ │ │ │ └── optimizeCodeSegment.ts │ │ │ │ ├── safeBuildIRCode.ts │ │ │ │ ├── utils │ │ │ │ │ ├── checkIfVirtualGlobalArrayPtr.ts │ │ │ │ │ ├── checkIfVirtualLocalArrayPtr.ts │ │ │ │ │ ├── getBiggerIRArg.ts │ │ │ │ │ ├── getSmallerIRArg.ts │ │ │ │ │ ├── getTypeAtOffset.ts │ │ │ │ │ ├── getTypeOffsetByteSize.ts │ │ │ │ │ └── index.ts │ │ │ │ └── variables │ │ │ │ │ ├── IRConstant.ts │ │ │ │ │ ├── IRInstructionArg.ts │ │ │ │ │ ├── IRInstructionTypedArg.ts │ │ │ │ │ ├── IRLabel.ts │ │ │ │ │ ├── IRVariable.ts │ │ │ │ │ ├── constants │ │ │ │ │ ├── index.ts │ │ │ │ │ └── prefixes.ts │ │ │ │ │ └── index.ts │ │ │ ├── parser │ │ │ │ ├── ast │ │ │ │ │ ├── ASTCAbstractDeclarator.ts │ │ │ │ │ ├── ASTCAlignmentSpecifier.ts │ │ │ │ │ ├── ASTCAlignmentSpecifiersList.ts │ │ │ │ │ ├── ASTCArgumentsExpressionList.ts │ │ │ │ │ ├── ASTCAssignmentExpression.ts │ │ │ │ │ ├── ASTCBinaryOpNode.ts │ │ │ │ │ ├── ASTCBlockItemsList.ts │ │ │ │ │ ├── ASTCBreakStatement.ts │ │ │ │ │ ├── ASTCCaseStatement.ts │ │ │ │ │ ├── ASTCCastExpression.ts │ │ │ │ │ ├── ASTCCompilerNode.ts │ │ │ │ │ ├── ASTCCompoundExpressionStmt.ts │ │ │ │ │ ├── ASTCConditionalExpression.ts │ │ │ │ │ ├── ASTCConstantExpression.ts │ │ │ │ │ ├── ASTCContinueStatement.ts │ │ │ │ │ ├── ASTCDeclaration.ts │ │ │ │ │ ├── ASTCDeclarationSpecifier.ts │ │ │ │ │ ├── ASTCDeclarationsList.ts │ │ │ │ │ ├── ASTCDeclarator.ts │ │ │ │ │ ├── ASTCDesignator.ts │ │ │ │ │ ├── ASTCDesignatorList.ts │ │ │ │ │ ├── ASTCDirectAbstractDeclarator.ts │ │ │ │ │ ├── ASTCDirectDeclarator.ts │ │ │ │ │ ├── ASTCEnumEnumerator.ts │ │ │ │ │ ├── ASTCEnumSpecifier.ts │ │ │ │ │ ├── ASTCExpression.ts │ │ │ │ │ ├── ASTCExpressionStatement.ts │ │ │ │ │ ├── ASTCForStatement.ts │ │ │ │ │ ├── ASTCFunctionDefinition.ts │ │ │ │ │ ├── ASTCFunctionSpecifiersList.ts │ │ │ │ │ ├── ASTCGotoStatement.ts │ │ │ │ │ ├── ASTCIdentifiersList.ts │ │ │ │ │ ├── ASTCIfStatement.ts │ │ │ │ │ ├── ASTCInitDeclarator.ts │ │ │ │ │ ├── ASTCInitDeclaratorList.ts │ │ │ │ │ ├── ASTCInitializer.ts │ │ │ │ │ ├── ASTCLabelStatement.ts │ │ │ │ │ ├── ASTCParameterDeclaration.ts │ │ │ │ │ ├── ASTCParametersList.ts │ │ │ │ │ ├── ASTCPointer.ts │ │ │ │ │ ├── ASTCPostfixExpression.ts │ │ │ │ │ ├── ASTCPrimaryExpression.ts │ │ │ │ │ ├── ASTCReturnStatement.ts │ │ │ │ │ ├── ASTCSpecifiersQualifiersList.ts │ │ │ │ │ ├── ASTCStaticAssertDeclaration.ts │ │ │ │ │ ├── ASTCStmt.ts │ │ │ │ │ ├── ASTCStorageClassSpecifiersList.ts │ │ │ │ │ ├── ASTCStructDeclaration.ts │ │ │ │ │ ├── ASTCStructDeclarationList.ts │ │ │ │ │ ├── ASTCStructDeclarator.ts │ │ │ │ │ ├── ASTCStructDeclaratorList.ts │ │ │ │ │ ├── ASTCStructSpecifier.ts │ │ │ │ │ ├── ASTCSwitchStatement.ts │ │ │ │ │ ├── ASTCTranslationUnit.ts │ │ │ │ │ ├── ASTCTypeName.ts │ │ │ │ │ ├── ASTCTypeQualifiersList.ts │ │ │ │ │ ├── ASTCTypeSpecifier.ts │ │ │ │ │ ├── ASTCTypeSpecifiersList.ts │ │ │ │ │ ├── ASTCUnaryExpression.ts │ │ │ │ │ ├── ASTCUnionSpecifier.ts │ │ │ │ │ ├── ASTCValueNode.ts │ │ │ │ │ ├── ASTCWhileStatement.ts │ │ │ │ │ ├── asm │ │ │ │ │ │ ├── ASTCAsmClobberOperand.ts │ │ │ │ │ │ ├── ASTCAsmStatement.ts │ │ │ │ │ │ ├── ASTCAsmStmtInputConstraint.ts │ │ │ │ │ │ ├── ASTCAsmStmtInputOperand.ts │ │ │ │ │ │ ├── ASTCAsmStmtOutputConstraint.ts │ │ │ │ │ │ ├── ASTCAsmStmtOutputOperand.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── dump │ │ │ │ │ ├── index.ts │ │ │ │ │ └── serializeTypedTreeToString.ts │ │ │ │ ├── grammar │ │ │ │ │ ├── errors │ │ │ │ │ │ └── CGrammarError.ts │ │ │ │ │ ├── generateTree.ts │ │ │ │ │ ├── grammar.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── matchers │ │ │ │ │ │ ├── declarations │ │ │ │ │ │ ├── abstractDeclarator.ts │ │ │ │ │ │ ├── declaration.ts │ │ │ │ │ │ ├── declarationList.ts │ │ │ │ │ │ ├── declarator.ts │ │ │ │ │ │ ├── designation.ts │ │ │ │ │ │ ├── directAbstractDeclarator.ts │ │ │ │ │ │ ├── directDeclarator.ts │ │ │ │ │ │ ├── enumDeclator.ts │ │ │ │ │ │ ├── externalDeclaration.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── initDeclarator.ts │ │ │ │ │ │ ├── initializer.ts │ │ │ │ │ │ ├── parameterDeclaration.ts │ │ │ │ │ │ ├── pointer.ts │ │ │ │ │ │ ├── staticAssertDeclaration.ts │ │ │ │ │ │ ├── structDeclaration.ts │ │ │ │ │ │ ├── structDeclarationList.ts │ │ │ │ │ │ └── structDeclarator.ts │ │ │ │ │ │ ├── definitions │ │ │ │ │ │ ├── functionDefinition.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── translationUnit.ts │ │ │ │ │ │ ├── expressions │ │ │ │ │ │ ├── additiveExpression.ts │ │ │ │ │ │ ├── assignmentExpression.ts │ │ │ │ │ │ ├── bitwiseExpression.ts │ │ │ │ │ │ ├── castExpression.ts │ │ │ │ │ │ ├── conditionalExpression.ts │ │ │ │ │ │ ├── constantExpression.ts │ │ │ │ │ │ ├── equalityExpression.ts │ │ │ │ │ │ ├── expression.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── logicalExpression.ts │ │ │ │ │ │ ├── multiplicativeExpression.ts │ │ │ │ │ │ ├── postfixExpression.ts │ │ │ │ │ │ ├── primaryExpression.ts │ │ │ │ │ │ ├── relationalExpression.ts │ │ │ │ │ │ ├── shiftExpression.ts │ │ │ │ │ │ └── unaryExpression.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── parameters │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── parameterList.ts │ │ │ │ │ │ └── parameterTypeList.ts │ │ │ │ │ │ ├── shared.ts │ │ │ │ │ │ ├── specifiers │ │ │ │ │ │ ├── alignmentSpecifier.ts │ │ │ │ │ │ ├── declarationSpecifiers.ts │ │ │ │ │ │ ├── functionSpecifier.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── qualifiersSpecifiers.ts │ │ │ │ │ │ ├── storageClassSpecifier.ts │ │ │ │ │ │ ├── structSpecifier.ts │ │ │ │ │ │ ├── typeQualifier.ts │ │ │ │ │ │ ├── typeQualifiers.ts │ │ │ │ │ │ ├── typeSpecifier.ts │ │ │ │ │ │ └── unionSpecifier.ts │ │ │ │ │ │ ├── statements │ │ │ │ │ │ ├── asm │ │ │ │ │ │ │ ├── asmClobberOperand.ts │ │ │ │ │ │ │ ├── asmInputConstraint.ts │ │ │ │ │ │ │ ├── asmInputOperand.ts │ │ │ │ │ │ │ ├── asmOutputConstraint.ts │ │ │ │ │ │ │ ├── asmOutputOperand.ts │ │ │ │ │ │ │ ├── asmStatement.ts │ │ │ │ │ │ │ ├── asmSymbolicName.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── compoundExpressionStatement.ts │ │ │ │ │ │ ├── compoundStatement.ts │ │ │ │ │ │ ├── expressionStatement.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── iterationStatement.ts │ │ │ │ │ │ ├── jumpStatement.ts │ │ │ │ │ │ ├── labeledStatement.ts │ │ │ │ │ │ ├── selectionStatement.ts │ │ │ │ │ │ └── statement.ts │ │ │ │ │ │ ├── types │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── stringLiteral.ts │ │ │ │ │ │ └── typename.ts │ │ │ │ │ │ └── utils │ │ │ │ │ │ ├── CReducePostfixOperatorVisitor.ts │ │ │ │ │ │ ├── createLeftRecursiveOperatorMatcher.ts │ │ │ │ │ │ ├── fetchSplittedProductionsList.ts │ │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ └── lexer │ │ │ │ │ ├── clexer.ts │ │ │ │ │ └── parsers │ │ │ │ │ ├── cCommentParser.ts │ │ │ │ │ ├── cMergeNumbersTokens.ts │ │ │ │ │ └── index.ts │ │ │ ├── preprocessor │ │ │ │ ├── ast │ │ │ │ │ ├── ASTCBinaryOpNode.ts │ │ │ │ │ ├── ASTCCodeBlockNode.ts │ │ │ │ │ ├── ASTCDefineNode.ts │ │ │ │ │ ├── ASTCElifDefNode.ts │ │ │ │ │ ├── ASTCElifNode.ts │ │ │ │ │ ├── ASTCElifNotDefNode.ts │ │ │ │ │ ├── ASTCExpressionNode.ts │ │ │ │ │ ├── ASTCIfDefNode.ts │ │ │ │ │ ├── ASTCIfNode.ts │ │ │ │ │ ├── ASTCIfNotDefNode.ts │ │ │ │ │ ├── ASTCIncludeNode.ts │ │ │ │ │ ├── ASTCPreprocessorTreeNode.ts │ │ │ │ │ ├── ASTCStmtNode.ts │ │ │ │ │ ├── ASTCValueNode.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── grammar │ │ │ │ │ ├── CPreprocessorError.ts │ │ │ │ │ ├── CPreprocessorGrammar.ts │ │ │ │ │ ├── CPreprocessorIdentifiers.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── matchers │ │ │ │ │ │ ├── codeBlockMatcher.ts │ │ │ │ │ │ ├── defineMatcher.ts │ │ │ │ │ │ ├── elifDefMatcher.ts │ │ │ │ │ │ ├── elifMatcher.ts │ │ │ │ │ │ ├── elifNotDefMatcher.ts │ │ │ │ │ │ ├── expressions │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── logicExpression.ts │ │ │ │ │ │ ├── mathExpression.ts │ │ │ │ │ │ ├── relationExpression.ts │ │ │ │ │ │ └── utils │ │ │ │ │ │ │ ├── PreprocessorReducePostifxOperatorsVisitor.ts │ │ │ │ │ │ │ ├── createLeftRecursiveOperatorMatcher.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── ifDefMatcher.ts │ │ │ │ │ │ ├── ifFalseStmtMatcher.ts │ │ │ │ │ │ ├── ifMatcher.ts │ │ │ │ │ │ ├── ifNotDefMatcher.ts │ │ │ │ │ │ ├── includeMatcher.ts │ │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── interpreter │ │ │ │ │ ├── ExpressionResultTreeVisitor.ts │ │ │ │ │ ├── concatTokens.ts │ │ │ │ │ ├── createInterpreterContext.ts │ │ │ │ │ ├── evalTokens.ts │ │ │ │ │ ├── execMacro.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── interpret.ts │ │ │ │ │ └── types │ │ │ │ │ │ ├── CInterpreterContext.ts │ │ │ │ │ │ ├── CInterpreterIncludeResolver.ts │ │ │ │ │ │ ├── CPreprocessorConfig.ts │ │ │ │ │ │ ├── CPreprocessorInterpretable.ts │ │ │ │ │ │ ├── CPreprocessorMacro.ts │ │ │ │ │ │ └── index.ts │ │ │ │ ├── preprocess.ts │ │ │ │ └── utils │ │ │ │ │ ├── index.ts │ │ │ │ │ └── isPreprocessorIdentifierLikeToken.ts │ │ │ └── utils │ │ │ │ └── createCCompilerTimings.ts │ │ ├── fs │ │ │ ├── CInternalCompilerFsResolver.ts │ │ │ ├── index.ts │ │ │ ├── kernel │ │ │ │ ├── graphicsMode.h.ts │ │ │ │ ├── index.ts │ │ │ │ └── textMode.h.ts │ │ │ └── std │ │ │ │ ├── alloca.h.ts │ │ │ │ ├── index.ts │ │ │ │ ├── stdarg.h.ts │ │ │ │ ├── stdbool.h.ts │ │ │ │ ├── stdio.h.ts │ │ │ │ └── string.h.ts │ │ ├── index.ts │ │ └── output │ │ │ ├── CBinaryObjectOutput.ts │ │ │ ├── CCompilerOutput.ts │ │ │ └── index.ts │ ├── tests │ │ ├── analyze │ │ │ ├── access.test.ts │ │ │ ├── casts.test.ts │ │ │ ├── enums.test.ts │ │ │ ├── floats.test.ts │ │ │ ├── functions.test.ts │ │ │ ├── initializer.test.ts │ │ │ ├── scope.test.ts │ │ │ └── utils │ │ │ │ ├── analyzeMatcher.ts │ │ │ │ └── index.ts │ │ ├── codegen │ │ │ ├── declarations │ │ │ │ ├── globals.test.ts │ │ │ │ ├── initializer.test.ts │ │ │ │ ├── typedef.test.ts │ │ │ │ └── unions.test.ts │ │ │ ├── examples │ │ │ │ └── rainbowHelloWorld.test.ts │ │ │ ├── preprocessor │ │ │ │ └── macros.test.ts │ │ │ ├── sign │ │ │ │ ├── signArithmetic.test.ts │ │ │ │ └── signConditions.test.ts │ │ │ ├── statements │ │ │ │ ├── alloca.test.ts │ │ │ │ ├── asm.test.ts │ │ │ │ ├── assign.test.ts │ │ │ │ ├── call.test.ts │ │ │ │ ├── compound.test.ts │ │ │ │ ├── fn.test.ts │ │ │ │ ├── for.test.ts │ │ │ │ ├── goto.test.ts │ │ │ │ ├── if.test.ts │ │ │ │ ├── literal.test.ts │ │ │ │ ├── math.test.ts │ │ │ │ ├── pointers.test.ts │ │ │ │ ├── return.test.ts │ │ │ │ ├── switch.test.ts │ │ │ │ ├── ternary.test.ts │ │ │ │ └── va.test.ts │ │ │ ├── utils │ │ │ │ ├── asmMatcher.ts │ │ │ │ └── index.ts │ │ │ └── x87 │ │ │ │ ├── accessors.test.ts │ │ │ │ ├── conditions.test.ts │ │ │ │ ├── functions.test.ts │ │ │ │ └── math.test.ts │ │ └── ir │ │ │ ├── declarations │ │ │ ├── array.test.ts │ │ │ ├── pointers.test.ts │ │ │ ├── primitive.test.ts │ │ │ └── scope.test.ts │ │ │ ├── examples │ │ │ └── strlen.test.ts │ │ │ ├── expressions │ │ │ └── sizeof.test.ts │ │ │ ├── logic │ │ │ ├── assign.test.ts │ │ │ └── ternary.test.ts │ │ │ ├── statements │ │ │ ├── assignment.test.ts │ │ │ ├── constants.test.ts │ │ │ ├── continue.test.ts │ │ │ ├── for.test.ts │ │ │ ├── functions.test.ts │ │ │ ├── if.test.ts │ │ │ ├── increment.test.ts │ │ │ └── while.test.ts │ │ │ └── utils │ │ │ ├── index.ts │ │ │ └── irMatcher.ts │ └── tsconfig.json ├── compiler-rpn │ ├── .eslintrc.yml │ ├── CHANGELOG.md │ ├── jest.config.mjs │ ├── package.json │ ├── rollup.config.mjs │ ├── src │ │ ├── index.ts │ │ ├── rpn.ts │ │ └── utils │ │ │ ├── MathError.ts │ │ │ ├── MathExpression.ts │ │ │ ├── MathOperators.ts │ │ │ └── index.ts │ ├── tests │ │ └── rpn.test.ts │ └── tsconfig.json ├── x86-assembler │ ├── .eslintrc.yml │ ├── CHANGELOG.md │ ├── jest.config.mjs │ ├── package.json │ ├── rollup.config.mjs │ ├── src │ │ ├── asm.ts │ │ ├── assets │ │ │ ├── binaryInstructionsDefs.ts │ │ │ └── index.ts │ │ ├── constants │ │ │ ├── MemoryRegion.ts │ │ │ ├── SegmentedAddress.ts │ │ │ ├── index.ts │ │ │ ├── instructionSetSchema.ts │ │ │ ├── x86.ts │ │ │ ├── x86rm.ts │ │ │ ├── x86sib.ts │ │ │ └── x86utils.ts │ │ ├── index.ts │ │ ├── parser │ │ │ ├── ast │ │ │ │ ├── ASTAsmNode.ts │ │ │ │ ├── ASTAsmParser.ts │ │ │ │ ├── ast.ts │ │ │ │ ├── critical │ │ │ │ │ ├── ASTEqu.ts │ │ │ │ │ ├── ASTExpression.ts │ │ │ │ │ ├── ASTLabel.ts │ │ │ │ │ └── ASTTimes.ts │ │ │ │ ├── def │ │ │ │ │ ├── ASTCompilerOption.ts │ │ │ │ │ └── ASTDef.ts │ │ │ │ ├── index.ts │ │ │ │ ├── instruction │ │ │ │ │ ├── ASTInstruction.ts │ │ │ │ │ ├── ASTInstructionSchema.ts │ │ │ │ │ ├── ASTResolvableArg.ts │ │ │ │ │ ├── args │ │ │ │ │ │ ├── ASTInstructionArg.ts │ │ │ │ │ │ ├── ASTInstructionArgMatchers.ts │ │ │ │ │ │ ├── ASTInstructionMemPtrArg.ts │ │ │ │ │ │ ├── ASTInstructionMemSegmentedArg.ts │ │ │ │ │ │ ├── ASTInstructionNumberArg.ts │ │ │ │ │ │ ├── ASTInstructionRegisterArg.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── matchers │ │ │ │ │ │ │ ├── farSegPointer.ts │ │ │ │ │ │ │ ├── imm.ts │ │ │ │ │ │ │ ├── immCanBeImplicitSignExtendedToByte.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── indirectFarSegPointer.ts │ │ │ │ │ │ │ ├── mem.ts │ │ │ │ │ │ │ ├── moffs.ts │ │ │ │ │ │ │ ├── nearPointer.ts │ │ │ │ │ │ │ ├── reg.ts │ │ │ │ │ │ │ ├── relLabel.ts │ │ │ │ │ │ │ ├── sreg.ts │ │ │ │ │ │ │ └── x87.ts │ │ │ │ │ └── utils │ │ │ │ │ │ └── isTokenInstructionBeginning.ts │ │ │ │ └── types.ts │ │ │ ├── compiler │ │ │ │ ├── BinaryBlob.ts │ │ │ │ ├── BinaryPassResults.ts │ │ │ │ ├── X86Compiler.ts │ │ │ │ ├── compile.ts │ │ │ │ ├── index.ts │ │ │ │ ├── types │ │ │ │ │ ├── BinaryDefinition.ts │ │ │ │ │ ├── BinaryEqu.ts │ │ │ │ │ ├── BinaryInstruction.ts │ │ │ │ │ └── BinaryRepeatedNode.ts │ │ │ │ ├── utils │ │ │ │ │ ├── findMatchingMemAddressingRMByte.ts │ │ │ │ │ ├── findMatchingSregPrefix.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── rpnTokens.ts │ │ │ │ └── view │ │ │ │ │ ├── BinaryView.ts │ │ │ │ │ ├── TableBinaryView.ts │ │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── lexer │ │ │ │ ├── asmLexer.ts │ │ │ │ ├── index.ts │ │ │ │ └── tokens │ │ │ │ │ ├── BranchAddressingTypeToken.ts │ │ │ │ │ ├── RegisterToken.ts │ │ │ │ │ ├── SizeOverrideToken.ts │ │ │ │ │ └── index.ts │ │ │ └── utils │ │ │ │ ├── assignLabelsToTokens.ts │ │ │ │ ├── externalLinkerLabel.ts │ │ │ │ ├── fetchInstructionTokensArgsList.ts │ │ │ │ ├── getByteSizeArgPrefixName.ts │ │ │ │ ├── index.ts │ │ │ │ ├── isJumpInstruction.ts │ │ │ │ ├── isPossibleLabelToken.ts │ │ │ │ ├── isReservedKeyword.ts │ │ │ │ ├── isX87Instruction.ts │ │ │ │ └── toStringArgsList.ts │ │ ├── preprocessor │ │ │ ├── PreprocessorError.ts │ │ │ ├── constants.ts │ │ │ ├── grammar.ts │ │ │ ├── index.ts │ │ │ ├── interpreter │ │ │ │ ├── ExpressionResultTreeVisitor.ts │ │ │ │ ├── PreprocessorInterpreter.ts │ │ │ │ └── utils │ │ │ │ │ └── fetchRuntimeCallArgsList.ts │ │ │ ├── matchers │ │ │ │ ├── index.ts │ │ │ │ ├── logicExpression.ts │ │ │ │ ├── mathExpression.ts │ │ │ │ ├── relationExpression.ts │ │ │ │ └── utils │ │ │ │ │ ├── PreprocessorReducePostifxOperatorsVisitor.ts │ │ │ │ │ ├── createLeftRecursiveOperatorMatcher.ts │ │ │ │ │ └── index.ts │ │ │ └── nodes │ │ │ │ ├── ASTPreprocessorBinaryOpNode.ts │ │ │ │ ├── ASTPreprocessorCriticalEQU.ts │ │ │ │ ├── ASTPreprocessorDefine.ts │ │ │ │ ├── ASTPreprocessorExpression.ts │ │ │ │ ├── ASTPreprocessorIF.ts │ │ │ │ ├── ASTPreprocessorIFDef.ts │ │ │ │ ├── ASTPreprocessorMacro.ts │ │ │ │ ├── ASTPreprocessorStmt.ts │ │ │ │ ├── ASTPreprocessorSyntaxLine.ts │ │ │ │ ├── ASTPreprocessorUndef.ts │ │ │ │ ├── ASTPreprocessorValueNode.ts │ │ │ │ └── index.ts │ │ ├── shared │ │ │ ├── ParserError.ts │ │ │ └── index.ts │ │ ├── types.ts │ │ └── utils │ │ │ ├── createAssemblerTimings.ts │ │ │ ├── getSignedNumber.ts │ │ │ ├── index.ts │ │ │ ├── signExtend.ts │ │ │ └── toUnsignedNumber.ts │ ├── tests │ │ ├── asm │ │ │ ├── arithmetic.asm │ │ │ ├── bootman.asm │ │ │ ├── bootos.asm │ │ │ ├── bootslide.asm │ │ │ ├── db.asm │ │ │ ├── equ.asm │ │ │ ├── jumps.asm │ │ │ ├── macros.asm │ │ │ ├── modrm.asm │ │ │ ├── operands.asm │ │ │ ├── prefixes.asm │ │ │ ├── printf.asm │ │ │ ├── tetros.asm │ │ │ ├── times.asm │ │ │ └── various.asm │ │ ├── binary.test.ts │ │ ├── compilerOptions.test.ts │ │ ├── errors.test.ts │ │ └── utils │ │ │ ├── asmMatcher.ts │ │ │ ├── parseBinaryTestList.ts │ │ │ └── types.d.ts │ └── tsconfig.json └── x86-cpu │ ├── .eslintrc.yml │ ├── CHANGELOG.md │ ├── jest.config.mjs │ ├── package.json │ ├── rollup.config.mjs │ ├── src │ ├── Logger.ts │ ├── X86ALU.ts │ ├── X86CPU.ts │ ├── X86IO.ts │ ├── X86InstructionSet.ts │ ├── X86Stack.ts │ ├── X86Unit.ts │ ├── constants │ │ ├── index.ts │ │ └── x86.ts │ ├── devices │ │ ├── BIOS │ │ │ ├── BIOS.ts │ │ │ ├── VideoMode.ts │ │ │ └── asm │ │ │ │ ├── fakeBIOS.ts │ │ │ │ └── index.ts │ │ ├── CMOS.ts │ │ ├── Keyboard.ts │ │ ├── PIT │ │ │ ├── CountdownTimer.ts │ │ │ ├── PIT.ts │ │ │ └── SpeakerTimer.ts │ │ ├── PS2.ts │ │ ├── Video │ │ │ ├── HTML │ │ │ │ └── VGARenderLoopDriver.ts │ │ │ ├── Renderers │ │ │ │ ├── VGAGraphicsModeCanvasRenderer.ts │ │ │ │ ├── VGATextModeCanvasRenderer.ts │ │ │ │ ├── index.ts │ │ │ │ └── utils │ │ │ │ │ ├── VGACanvasRenderer.ts │ │ │ │ │ └── VGAPixBufCanvasRenderer.ts │ │ │ ├── VGA.ts │ │ │ ├── VGAAttrRegs.ts │ │ │ ├── VGAConstants.ts │ │ │ ├── VGACrtcRegs.ts │ │ │ ├── VGADacRegs.ts │ │ │ ├── VGAExternalRegs.ts │ │ │ ├── VGAGraphicsRegs.ts │ │ │ ├── VGAModesPresets.ts │ │ │ ├── VGASequencerRegs.ts │ │ │ └── index.ts │ │ └── index.ts │ ├── guards │ │ ├── index.ts │ │ └── isIntegerReg.ts │ ├── helpers │ │ ├── binaryToFloppy35Buffer.ts │ │ └── index.ts │ ├── index.ts │ ├── memory │ │ ├── VirtualMemBlockDriver.ts │ │ └── index.ts │ ├── parts │ │ ├── X86AbstractCPU.ts │ │ ├── X86AbstractDevice.ts │ │ ├── X86Interrupt.ts │ │ ├── X86Port.ts │ │ ├── X86RAM.ts │ │ ├── X86Regs.ts │ │ └── index.ts │ └── x87 │ │ ├── X87.ts │ │ ├── X87Error.ts │ │ ├── X87Regs.ts │ │ └── index.ts │ └── tsconfig.json ├── prettier.config.js ├── scripts ├── opcodesScrapper.js └── vgaColorsScrapper.js ├── tsconfig.json ├── turbo.json └── yarn.lock /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "restricted", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /.commitlintrc.ts: -------------------------------------------------------------------------------- 1 | import type { UserConfig } from '@commitlint/types'; 2 | 3 | const commitlintConfig: UserConfig = { 4 | extends: ['@commitlint/config-conventional'], 5 | }; 6 | 7 | export default commitlintConfig; 8 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | . "$(dirname "$0")/_/husky.sh" 5 | 6 | npx --no-install commitlint --edit "$1" 7 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | . "$(dirname "$0")/_/husky.sh" 5 | 6 | npx --no-install pretty-quick --staged 7 | yarn lint-staged 8 | -------------------------------------------------------------------------------- /apps/cli/.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /apps/cli/.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "restricted", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /apps/cli/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: ../../.eslintrc.yml 2 | -------------------------------------------------------------------------------- /apps/cli/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .turbo/ 3 | -------------------------------------------------------------------------------- /apps/cli/jest.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/extensions, import/no-default-export */ 2 | import { fileURLToPath } from 'node:url'; 3 | import { dirname } from 'path'; 4 | import { createJestConfig } from '../../config/jest.shared.config.mjs'; 5 | 6 | export default createJestConfig({ 7 | rootDir: dirname(fileURLToPath(import.meta.url)), 8 | }); 9 | -------------------------------------------------------------------------------- /apps/cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["src/"], 4 | "compilerOptions": { 5 | "baseUrl": "src", 6 | "module": "CommonJS", 7 | "declaration": false, 8 | "declarationMap": false 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/cli/webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const { createConfig } = require('../../config/webpack.config'); 3 | 4 | module.exports = createConfig({ 5 | target: 'node', 6 | entryName: 'cli', 7 | mainFile: 'src/index.ts', 8 | outputFile: 'bin/cli.js', 9 | configDir: __dirname, 10 | nodemon: { 11 | enabled: true, 12 | attrs: { 13 | args: ['./.mock/main.c', '-d'], 14 | }, 15 | }, 16 | plugins: [ 17 | new webpack.BannerPlugin({ 18 | banner: '#!/usr/bin/env node', 19 | raw: true, 20 | }), 21 | ], 22 | }); 23 | -------------------------------------------------------------------------------- /apps/machine/.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /apps/machine/.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "restricted", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /apps/machine/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: ../../.eslintrc.yml 2 | -------------------------------------------------------------------------------- /apps/machine/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .turbo/ 3 | src/ 4 | -------------------------------------------------------------------------------- /apps/machine/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @ts-cc/vm 2 | 3 | ## 1.8.0 4 | 5 | ### Minor Changes 6 | 7 | - Better C support 8 | 9 | ## 1.7.1 10 | 11 | ### Patch Changes 12 | 13 | - Force publish machine 14 | 15 | ## 1.7.0 16 | 17 | ### Minor Changes 18 | 19 | - Publish packages 20 | 21 | ## 1.6.0 22 | 23 | ### Minor Changes 24 | 25 | - Fix changesets 26 | 27 | ## 1.5.0 28 | 29 | ### Minor Changes 30 | 31 | - Improve C support 32 | 33 | ## 1.4.0 34 | 35 | ### Minor Changes 36 | 37 | - Improve C support 38 | 39 | ## 1.3.0 40 | 41 | ### Minor Changes 42 | 43 | - Add more new things 44 | 45 | ## 1.2.0 46 | 47 | ### Minor Changes 48 | 49 | - Add web vm 50 | -------------------------------------------------------------------------------- /apps/machine/jest.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/extensions, import/no-default-export */ 2 | import { fileURLToPath } from 'node:url'; 3 | import { dirname } from 'path'; 4 | import { createJestConfig } from '../../config/jest.shared.config.mjs'; 5 | 6 | export default createJestConfig({ 7 | rootDir: dirname(fileURLToPath(import.meta.url)), 8 | }); 9 | -------------------------------------------------------------------------------- /apps/machine/src/client/client.tsx: -------------------------------------------------------------------------------- 1 | import { createRoot } from 'react-dom/client'; 2 | import { Screen } from './screen'; 3 | 4 | const root = createRoot(document.getElementById('root')); 5 | 6 | root.render(); 7 | -------------------------------------------------------------------------------- /apps/machine/src/client/index.ts: -------------------------------------------------------------------------------- 1 | import './client'; 2 | -------------------------------------------------------------------------------- /apps/machine/src/client/screen/Screen.styled.tsx: -------------------------------------------------------------------------------- 1 | import { styled } from 'styled-components'; 2 | 3 | export const ScreenWrapper = styled.div` 4 | position: absolute; 5 | left: 0; 6 | top: 0; 7 | width: 100%; 8 | height: 100%; 9 | display: grid; 10 | place-content: center; 11 | `; 12 | 13 | export const ScreenCanvasWrapper = styled.div` 14 | display: block; 15 | margin: 0 auto; 16 | text-align: center; 17 | image-rendering: pixelated; 18 | `; 19 | -------------------------------------------------------------------------------- /apps/machine/src/client/screen/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Screen'; 2 | -------------------------------------------------------------------------------- /apps/machine/src/server/getManifestJSON.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'node:path'; 2 | import * as fs from 'node:fs'; 3 | 4 | type FilesManifest = Record; 5 | 6 | export const getManifestJSON = (): FilesManifest => { 7 | const json = fs.readFileSync(path.resolve(__dirname, 'client/manifest.json'), 'utf-8'); 8 | 9 | return JSON.parse(json); 10 | }; 11 | -------------------------------------------------------------------------------- /apps/machine/src/server/index.ts: -------------------------------------------------------------------------------- 1 | import './server'; 2 | -------------------------------------------------------------------------------- /apps/machine/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["src/"], 4 | "compilerOptions": { 5 | "baseUrl": "src", 6 | "module": "ESNext", 7 | "moduleResolution": "node", 8 | "jsx": "react-jsx", 9 | "declaration": false, 10 | "declarationMap": false 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/site/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: ../../.eslintrc.yml 2 | rules: 3 | '@typescript-eslint/consistent-type-imports': 'error' 4 | import/order: 5 | ['error', { 'groups': ['builtin', 'external', 'type', 'parent', 'sibling', 'index'] }] 6 | -------------------------------------------------------------------------------- /apps/site/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @ts-cc/site 2 | 3 | ## 1.8.0 4 | 5 | ### Minor Changes 6 | 7 | - Better C support 8 | 9 | ## 1.7.1 10 | 11 | ### Patch Changes 12 | 13 | - Force publish machine 14 | 15 | ## 1.7.0 16 | 17 | ### Minor Changes 18 | 19 | - Publish packages 20 | 21 | ## 1.6.0 22 | 23 | ### Minor Changes 24 | 25 | - Fix changesets 26 | 27 | ## 1.5.0 28 | 29 | ### Minor Changes 30 | 31 | - Improve C support 32 | 33 | ## 1.4.0 34 | 35 | ### Minor Changes 36 | 37 | - Improve C support 38 | -------------------------------------------------------------------------------- /apps/site/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'astro/config'; 2 | import react from '@astrojs/react'; 3 | import tailwind from '@astrojs/tailwind'; 4 | 5 | export default defineConfig({ 6 | integrations: [react(), tailwind()], 7 | ...(process.env.NODE_ENV === 'production' && { 8 | site: 'https://mati365.github.io', 9 | base: '/ts-c-compiler', 10 | }), 11 | }); 12 | -------------------------------------------------------------------------------- /apps/site/public/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/site/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /apps/site/src/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './shallowCompareArrays'; 2 | -------------------------------------------------------------------------------- /apps/site/src/helpers/shallowCompareArrays.ts: -------------------------------------------------------------------------------- 1 | import type { Nullable } from '../types'; 2 | 3 | export const shallowCompareArrays = ( 4 | a: Nullable, 5 | b: Nullable, 6 | ) => { 7 | if (a === b) { 8 | return true; 9 | } 10 | 11 | if (!a || !b) { 12 | return false; 13 | } 14 | 15 | for (let i = 0; i < a.length; ++i) { 16 | if (a[i] !== b[i]) { 17 | return false; 18 | } 19 | } 20 | 21 | return true; 22 | }; 23 | -------------------------------------------------------------------------------- /apps/site/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useInstantBeforeMount'; 2 | export * from './useInstantUpdateEffect'; 3 | -------------------------------------------------------------------------------- /apps/site/src/hooks/useInstantBeforeMount.ts: -------------------------------------------------------------------------------- 1 | import { useRef } from 'react'; 2 | 3 | export const useInstantBeforeMount = (fn: VoidFunction) => { 4 | const executedRef = useRef(false); 5 | 6 | if (!executedRef.current) { 7 | executedRef.current = true; 8 | fn(); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /apps/site/src/hooks/useInstantUpdateEffect.ts: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import type { DependencyList } from 'react'; 3 | 4 | import { shallowCompareArrays } from '../helpers'; 5 | 6 | export const useInstantUpdateEffect = (fn: VoidFunction, deps: DependencyList) => { 7 | const [prevDeps, setPrevDeps] = useState(deps); 8 | 9 | if (prevDeps && !shallowCompareArrays(prevDeps, deps)) { 10 | setPrevDeps(deps); 11 | fn(); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /apps/site/src/i18n/I18nProvider.ts: -------------------------------------------------------------------------------- 1 | import constate from 'constate'; 2 | import { I18N_PACKS } from './packs'; 3 | 4 | const useI18nValue = () => ({ 5 | pack: I18N_PACKS.en, 6 | }); 7 | 8 | export const [I18nProvider, useI18n] = constate(useI18nValue); 9 | -------------------------------------------------------------------------------- /apps/site/src/i18n/index.ts: -------------------------------------------------------------------------------- 1 | export * from './I18nProvider'; 2 | export * from './packs'; 3 | -------------------------------------------------------------------------------- /apps/site/src/i18n/packs/index.ts: -------------------------------------------------------------------------------- 1 | import { EN_18N_VALUE } from './en'; 2 | 3 | export const I18N_PACKS = { 4 | en: EN_18N_VALUE, 5 | }; 6 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorHeader/EditorCompilationToolbar.tsx: -------------------------------------------------------------------------------- 1 | import { useEditorState } from '../EditorStateProvider'; 2 | import { EditorCompileLangDropdown } from './parts'; 3 | 4 | export const EditorCompilationToolbar = () => { 5 | const { control, emulation } = useEditorState(); 6 | 7 | return ( 8 |
9 | 13 |
14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorHeader/EditorHeader.tsx: -------------------------------------------------------------------------------- 1 | import { EditorEmulationToolbar } from './EditorEmulationToolbar'; 2 | import { EditorCompilationToolbar } from './EditorCompilationToolbar'; 3 | import { EditorLinksToolbar } from './EditorLinksToolbar'; 4 | 5 | export const EditorHeader = () => ( 6 |
10 | 11 | 12 | 13 |
14 | ); 15 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorHeader/EditorLinksToolbar.tsx: -------------------------------------------------------------------------------- 1 | import { BiLogoGithub } from 'react-icons/bi'; 2 | import { useI18n } from 'i18n'; 3 | 4 | export const EditorLinksToolbar = () => { 5 | const t = useI18n().pack.header; 6 | 7 | return ( 8 |
    9 |
  1. 10 | 17 | 18 | 19 |
  2. 20 |
21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorHeader/index.ts: -------------------------------------------------------------------------------- 1 | export * from './EditorHeader'; 2 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorHeader/parts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './EditorCompileLangDropdown'; 2 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorInput/EditorInput.module.scss: -------------------------------------------------------------------------------- 1 | .editor-codemirror :global { 2 | .cm { 3 | &-editor, 4 | &-wrap { 5 | height: 100%; 6 | } 7 | 8 | &-scroller { 9 | overflow: auto; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorInput/index.ts: -------------------------------------------------------------------------------- 1 | export * from './EditorInput'; 2 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorInput/syntax/index.ts: -------------------------------------------------------------------------------- 1 | export * from './nasmCodemirrorSyntaxDefine'; 2 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorOutput/EditorOutputBinaryTab/index.ts: -------------------------------------------------------------------------------- 1 | export * from './EditorOutputBinaryTab'; 2 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorOutput/EditorOutputBinaryTab/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './highlightInstructionHTML'; 2 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorOutput/EditorOutputErrorsTab/index.ts: -------------------------------------------------------------------------------- 1 | export * from './EditorOutputErrorsTab'; 2 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorOutput/index.ts: -------------------------------------------------------------------------------- 1 | export * from './EditorOutput'; 2 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorRoot.tsx: -------------------------------------------------------------------------------- 1 | import { I18nProvider } from '../../i18n'; 2 | import { EditorContainer } from './EditorContainer'; 3 | import { EditorStateProvider } from './EditorStateProvider'; 4 | 5 | export const EditorRoot = () => ( 6 | 7 | 8 | 9 | 10 | 11 | ); 12 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorScreen/index.ts: -------------------------------------------------------------------------------- 1 | export * from './EditorScreen'; 2 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorSidebar/EditorSidebar.tsx: -------------------------------------------------------------------------------- 1 | import { EditorScreen } from '../EditorScreen'; 2 | 3 | export const EditorSidebar = () => ( 4 |
5 | 6 |
7 | ); 8 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorSidebar/index.ts: -------------------------------------------------------------------------------- 1 | export * from './EditorSidebar'; 2 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/EditorStateProvider/index.ts: -------------------------------------------------------------------------------- 1 | export * from './EditorStateProvider'; 2 | export * from './types'; 3 | -------------------------------------------------------------------------------- /apps/site/src/modules/Editor/index.ts: -------------------------------------------------------------------------------- 1 | export * from './EditorContainer'; 2 | export * from './EditorRoot'; 3 | export * from './EditorStateProvider'; 4 | export * from './EditorHeader'; 5 | export * from './EditorInput'; 6 | -------------------------------------------------------------------------------- /apps/site/src/modules/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Editor'; 2 | -------------------------------------------------------------------------------- /apps/site/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { EditorRoot } from '../modules'; 3 | import '../styles/index.scss'; 4 | --- 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Typescript C Compiler 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /apps/site/src/styles/index.scss: -------------------------------------------------------------------------------- 1 | @import './reset.scss'; 2 | 3 | body { 4 | font-family: Arial, Helvetica, sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /apps/site/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './nullable.type'; 2 | -------------------------------------------------------------------------------- /apps/site/src/types/nullable.type.ts: -------------------------------------------------------------------------------- 1 | export type Nullable = T | null | undefined; 2 | -------------------------------------------------------------------------------- /apps/site/tailwind.config.mjs: -------------------------------------------------------------------------------- 1 | import flowBitePlugin from 'flowbite/plugin'; 2 | 3 | export default { 4 | content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'], 5 | theme: { 6 | extend: {}, 7 | }, 8 | content: ['src/**/*.{ts,tsx}', '../../node_modules/flowbite-react/lib/esm/**/*.js'], 9 | plugins: [ 10 | ({ addComponents }) => { 11 | flowBitePlugin, 12 | addComponents({ 13 | '.layer-absolute': { 14 | '@apply absolute left-0 top-0 w-full h-full': {}, 15 | }, 16 | }); 17 | }, 18 | ], 19 | }; 20 | -------------------------------------------------------------------------------- /apps/site/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "jsxImportSource": "react", 6 | "baseUrl": "src", 7 | "strict": true, 8 | "strictNullChecks": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /assets/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Emulator 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /assets/kernels/asm/interrupt.asm: -------------------------------------------------------------------------------- 1 | %macro mount_interrupt 2 2 | ; %1 - code 3 | ; %2 - handler 4 | mov ax, %1 5 | mov bx, 4 6 | imul bx 7 | mov bx, ax 8 | 9 | xor cx, cx 10 | mov es, cx 11 | 12 | mov word [es:bx], %2 13 | mov word [es:bx + 0x2], cs 14 | 15 | %endmacro 16 | 17 | ; MAIN 18 | jmp 0x7C0:main 19 | main: 20 | sti 21 | mount_interrupt 0x0, div_by_zero_handler 22 | mov ax, 6 23 | mov bx, 0 24 | idiv bx 25 | hlt 26 | 27 | div_by_zero_handler: 28 | xchg bx, bx 29 | iret 30 | 31 | ; At the end we need the boot sector signature. 32 | times 510-($-$$) db 0 33 | db 0x55 34 | db 0xaa 35 | -------------------------------------------------------------------------------- /assets/kernels/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p build/ 3 | nasm -f bin -o ./build/bootsec.bin ./asm/bootsec.asm 4 | objdump -D -b binary -mi386 -M intel -Maddr16,data16 ./build/bootsec.bin 5 | hexdump -ve '/1 "%02x"' ./build/bootsec.bin 6 | -------------------------------------------------------------------------------- /config/jest-extensions/file-transformer.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | process(sourceText) { 3 | return { 4 | code: ` 5 | module.exports = ${JSON.stringify(sourceText)}; 6 | `, 7 | }; 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /doc/editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/editor.png -------------------------------------------------------------------------------- /doc/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/logo.png -------------------------------------------------------------------------------- /doc/repl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/repl.png -------------------------------------------------------------------------------- /doc/screen-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen-10.png -------------------------------------------------------------------------------- /doc/screen-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen-11.png -------------------------------------------------------------------------------- /doc/screen-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen-12.png -------------------------------------------------------------------------------- /doc/screen-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen-13.png -------------------------------------------------------------------------------- /doc/screen-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen-2.png -------------------------------------------------------------------------------- /doc/screen-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen-3.png -------------------------------------------------------------------------------- /doc/screen-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen-4.png -------------------------------------------------------------------------------- /doc/screen-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen-5.png -------------------------------------------------------------------------------- /doc/screen-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen-6.png -------------------------------------------------------------------------------- /doc/screen-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen-7.png -------------------------------------------------------------------------------- /doc/screen-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen-8.png -------------------------------------------------------------------------------- /doc/screen-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen-9.png -------------------------------------------------------------------------------- /doc/screen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mati365/ts-c-compiler/1b77b2dff0e5d2c735add7f9500559e46af04b2f/doc/screen.gif -------------------------------------------------------------------------------- /packages/compiler-core/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: ../../.eslintrc.yml 2 | -------------------------------------------------------------------------------- /packages/compiler-core/jest.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/extensions, import/no-default-export */ 2 | import { fileURLToPath } from 'node:url'; 3 | import { dirname } from 'path'; 4 | import { createJestConfig } from '../../config/jest.shared.config.mjs'; 5 | 6 | export default createJestConfig({ 7 | rootDir: dirname(fileURLToPath(import.meta.url)), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/compiler-core/rollup.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-default-export, import/extensions */ 2 | import { createPackageRollupConfig } from '../../config/rollup.shared.config.mjs'; 3 | 4 | export default createPackageRollupConfig(); 5 | -------------------------------------------------------------------------------- /packages/compiler-core/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const BINARY_MASKS = { 2 | 0x1: (0x2 << 0x7) - 0x1, 3 | 0x2: (0x2 << 0xf) - 0x1, 4 | 0x4: ((0x2 << 0x1f) - 0x1) >>> 0, 5 | }; 6 | -------------------------------------------------------------------------------- /packages/compiler-core/src/decorators/index.ts: -------------------------------------------------------------------------------- 1 | export * from './logMethod'; 2 | export * from './memoizeMethod'; 3 | export * from './wrapMethod'; 4 | -------------------------------------------------------------------------------- /packages/compiler-core/src/decorators/memoizeMethod.ts: -------------------------------------------------------------------------------- 1 | import { shallowMemoizeOneCall } from '../utils/memoizeOne'; 2 | import { wrapMethod } from './wrapMethod'; 3 | 4 | export const memoizeMethod = wrapMethod(shallowMemoizeOneCall); 5 | -------------------------------------------------------------------------------- /packages/compiler-core/src/decorators/wrapMethod.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Wraps class method with decorator function 3 | */ 4 | export function wrapMethod(decorator: (fn: T) => any) { 5 | return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => ({ 6 | configurable: true, 7 | get() { 8 | const method = decorator(descriptor.value.bind(this)); 9 | Object.defineProperty(this, propertyKey, { 10 | value: method, 11 | configurable: true, 12 | writable: true, 13 | }); 14 | return method; 15 | }, 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /packages/compiler-core/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | export * from './decorators'; 3 | export * from './interfaces'; 4 | export * from './monads'; 5 | export * from './shared'; 6 | export * from './types'; 7 | export * from './utils'; 8 | -------------------------------------------------------------------------------- /packages/compiler-core/src/interfaces/IsEmpty.ts: -------------------------------------------------------------------------------- 1 | export interface IsEmpty { 2 | isEmpty(): boolean; 3 | } 4 | -------------------------------------------------------------------------------- /packages/compiler-core/src/interfaces/IsEqual.ts: -------------------------------------------------------------------------------- 1 | export interface IsEqual { 2 | isEqual(value: T): boolean; 3 | } 4 | -------------------------------------------------------------------------------- /packages/compiler-core/src/interfaces/IsPrintable.ts: -------------------------------------------------------------------------------- 1 | export interface IsPrintable { 2 | getDisplayName(): string; 3 | } 4 | -------------------------------------------------------------------------------- /packages/compiler-core/src/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './IsEmpty'; 2 | export * from './IsEqual'; 3 | export * from './IsPrintable'; 4 | -------------------------------------------------------------------------------- /packages/compiler-core/src/monads/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Identity'; 2 | -------------------------------------------------------------------------------- /packages/compiler-core/src/shared/CodeTranslatedError.ts: -------------------------------------------------------------------------------- 1 | import { format } from '../utils/format'; 2 | 3 | export class CodeTranslatedError extends Error { 4 | constructor( 5 | readonly translations: object, 6 | readonly code: C, 7 | readonly meta?: object, 8 | ) { 9 | super(); 10 | this.message = format(this.translations[code], meta || {}); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/compiler-core/src/shared/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CompilerError'; 2 | export * from './CodeTranslatedError'; 3 | export * from './UnionStruct'; 4 | export * from './Observable'; 5 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/appendToMapKeyArray.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fast append to map array, if array on key not exists - create 3 | */ 4 | export function appendToMapKeyArray(keyName: K, item: V, map: Map): void { 5 | const prevArray: V[] = map.get(keyName) || []; 6 | prevArray.push(item); 7 | map.set(keyName, prevArray); 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/arrayToHexString.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | export const arrayToHex = R.map((num: number) => 4 | R.isNil(num) ? '' : `${num.toString(16).padStart(2, '0')}`, 5 | ); 6 | 7 | /** 8 | * Converts array of number to hex string 9 | */ 10 | export function arrayToHexString(numbers: number[], delimeter: string = ' '): string { 11 | return R.join(delimeter, arrayToHex(numbers)); 12 | } 13 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/assertUnreachable.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 2 | export function assertUnreachable(x: never): never { 3 | throw new Error('Did not expect to get here'); 4 | } 5 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/concatNonEmptyStrings.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Removes empty strings from array and rest of items 3 | */ 4 | export function concatNonEmptyStrings(strings: string[]): string { 5 | return (strings || []).filter(Boolean).join(' '); 6 | } 7 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/dropFromHashQueue.ts: -------------------------------------------------------------------------------- 1 | export function dropFromHashQueue( 2 | uuid: K, 3 | obj: Record, 4 | ) { 5 | const value = obj[uuid]; 6 | delete obj[uuid]; 7 | return value; 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/dropNewLines.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | export function dropNewLines(str: string): string { 4 | return (str || '').split('\n').map(R.trim).join(' '); 5 | } 6 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/findByProp.ts: -------------------------------------------------------------------------------- 1 | import { propEq, find, findIndex } from 'ramda'; 2 | 3 | export function findByProp(keyName: string) { 4 | return (value: any) => 5 | (list: T[]): T => 6 | find(propEq(keyName, value) as any, list); 7 | } 8 | 9 | export function findIndexByProp(keyName: string) { 10 | return (value: any) => 11 | (list: any[]): number => 12 | findIndex(propEq(keyName, value), list); 13 | } 14 | 15 | export const findIndexByName = findIndexByProp('name'); 16 | export const findIndexById = findIndexByProp('id'); 17 | 18 | export const findByName = findByProp('name'); 19 | export const findById = findByProp('id'); 20 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/flipMap.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Flips value with key in Map 3 | */ 4 | export function flipMap(map: Map): Map { 5 | const flipped = new Map(); 6 | for (const [key, val] of map) { 7 | flipped.set(val, key); 8 | } 9 | 10 | return flipped; 11 | } 12 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/flipObject.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Flips keys with values 3 | */ 4 | export function flipObject(obj: Object): Object { 5 | const flipped: Object = {}; 6 | 7 | for (const [key, val] of Object.entries(obj)) { 8 | flipped[val] = key; 9 | } 10 | 11 | return flipped; 12 | } 13 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/fp-ts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tap-either-error'; 2 | export * from './tap-either'; 3 | export * from './try-reduce-eithers'; 4 | export * from './unwrap-either-or-throw'; 5 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/fp-ts/tap-either-error.ts: -------------------------------------------------------------------------------- 1 | import { pipe } from 'fp-ts/function'; 2 | import * as E from 'fp-ts/Either'; 3 | 4 | export const tapEitherError = 5 | (onLeft?: (error: E) => void) => 6 | (task: E.Either): E.Either => 7 | pipe( 8 | task, 9 | E.fold(error => { 10 | onLeft?.(error); 11 | return E.left(error); 12 | }, E.right), 13 | ); 14 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/fp-ts/tap-either.ts: -------------------------------------------------------------------------------- 1 | import { pipe } from 'fp-ts/function'; 2 | import * as E from 'fp-ts/Either'; 3 | 4 | export const tapEither = 5 | (onRight: (data: A) => void, onLeft?: (error: E) => void) => 6 | (task: E.Either): E.Either => 7 | pipe( 8 | task, 9 | E.fold( 10 | error => { 11 | onLeft?.(error); 12 | return E.left(error); 13 | }, 14 | data => { 15 | onRight(data); 16 | return E.right(data); 17 | }, 18 | ), 19 | ); 20 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/fp-ts/try-reduce-eithers.ts: -------------------------------------------------------------------------------- 1 | import * as E from 'fp-ts/Either'; 2 | 3 | export function tryReduceEithers( 4 | mapper: (acc: T, item: A) => E.Either, 5 | init: T, 6 | array: A[] | Iterable, 7 | ): E.Either { 8 | let acc: T = init; 9 | 10 | for (const item of array) { 11 | const result = mapper(acc, item); 12 | 13 | if (result) { 14 | if (E.isLeft(result)) { 15 | return result; 16 | } 17 | 18 | acc = result.right; 19 | } else { 20 | acc = null; 21 | } 22 | } 23 | 24 | return E.right(acc); 25 | } 26 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/fp-ts/unwrap-either-or-throw.ts: -------------------------------------------------------------------------------- 1 | import * as E from 'fp-ts/Either'; 2 | 3 | export const unwrapEitherOrThrow = (either: E.Either) => { 4 | if (E.isLeft(either)) { 5 | throw either.left; 6 | } 7 | 8 | return either.right; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/genUUID.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Generates random ID based on time 3 | */ 4 | export function genUUID(prefix: string = '', postfix: string = ''): string { 5 | const randomNum = (+Math.random().toString().slice(2) + Date.now()).toString(36); 6 | 7 | return `${prefix}${randomNum}${postfix}`; 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/mapMapValues.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Iterates over map values and maps them 3 | */ 4 | export function mapMapValues(fn: (v: V, k?: K) => O, map: Map): Map { 5 | const mapped = new Map(); 6 | 7 | for (const [key, val] of map) { 8 | const result = fn(val, key); 9 | 10 | if (result !== undefined) { 11 | mapped.set(key, result); 12 | } 13 | } 14 | 15 | return mapped; 16 | } 17 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/mapObjectKeys.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Iterates over map keys and executes fn on key name. 3 | * Outputs with object with mapped keys names 4 | */ 5 | export function mapObjectKeys(fn: (key: string) => string, obj: K): K { 6 | const newObj: K = {}; 7 | 8 | for (const key in obj) { 9 | if (Object.prototype.hasOwnProperty.call(obj, key)) { 10 | newObj[fn(key)] = obj[key]; 11 | } 12 | } 13 | 14 | return newObj; 15 | } 16 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/mergeNumberBytes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Concat array of numbers into single digit 3 | */ 4 | export function mergeNumberBytes(num: number[]): number { 5 | let acc = 0; 6 | for (let i = 0; i < num.length; ++i) { 7 | acc = (acc << 0x8) | num[i]; 8 | } 9 | 10 | return acc; 11 | } 12 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/mutableOmitChildKeys.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | /** 4 | * Remove child keys from parent keeping parent reference 5 | */ 6 | export function mutableOmitChildKeys(parent: object, child: object): object { 7 | R.forEach((key: any) => { 8 | delete parent[key]; 9 | }, R.keys(child)); 10 | 11 | return parent; 12 | } 13 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/padLeftLines.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Appends spaces to start of lines 3 | */ 4 | export function padLeftLines(nesting: number, lines: string[]): string[] { 5 | return lines.filter(Boolean).map(line => `${' '.padStart(nesting, ' ')}${line}`); 6 | } 7 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/removeNullValues.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | export function removeNullValues(obj: T): T { 4 | return R.pickBy(R.complement(R.isNil), obj); 5 | } 6 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/safeArray.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | /** 4 | * Always returns array, even if provided single value 5 | */ 6 | export function safeArray(array: T | T[]): T[] { 7 | if (R.is(Array, array)) { 8 | return array; 9 | } 10 | 11 | return [array]; 12 | } 13 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/safeFirstMatch.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | /** 4 | * Returns first matching group of regex 5 | */ 6 | export const safeFirstMatch = R.curry((regex: RegExp, str: string): string => { 7 | const output = R.match(regex, str); 8 | 9 | if (!output || !output.length) { 10 | return null; 11 | } 12 | 13 | return R.defaultTo(output[2], output[1]); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/serializers/dumpAttributesToString.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | import { removeNullValues } from '../removeNullValues'; 3 | 4 | /** 5 | * Serializes attributes to GET similar format 6 | */ 7 | export function dumpAttributesToString(kind: string, attrs: Record): string { 8 | const serializedAttrs = R.pipe( 9 | removeNullValues, 10 | R.mapObjIndexed(R.when(R.is(Boolean), val => +val)), 11 | R.toPairs as any, 12 | R.map(([key, value]) => `${key}="${value}"`), 13 | R.join(' '), 14 | )(attrs); 15 | 16 | if (R.isNil(kind)) { 17 | return serializedAttrs; 18 | } 19 | 20 | return `${kind} ${serializedAttrs}`.trim(); 21 | } 22 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/serializers/dumpCompilerAttrs.ts: -------------------------------------------------------------------------------- 1 | import { dumpAttributesToString } from './dumpAttributesToString'; 2 | 3 | /** 4 | * Appends custom flags to specific fields such as struct members (offsets) 5 | */ 6 | export function dumpCompilerAttrs(attrs: object): string { 7 | return `[[${dumpAttributesToString(null, attrs)}]]`; 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/serializers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dumpAttributesToString'; 2 | export * from './dumpCompilerAttrs'; 3 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/setCharAt.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Sets character at current position in string 3 | */ 4 | export function setCharAt(str: string, index: number, chr: string): string { 5 | if (index > str.length - 1) { 6 | return str; 7 | } 8 | 9 | return str.substr(0, index) + chr + str.substr(index + 1); 10 | } 11 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/shallowDiffers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Compares only first level of object keys 3 | */ 4 | export function shallowDiffers(a: any, b: any): boolean { 5 | if (a === b) { 6 | return false; 7 | } 8 | 9 | if (a instanceof Object && b instanceof Object) { 10 | for (const i in a) { 11 | if (!(i in b)) { 12 | return true; 13 | } 14 | } 15 | 16 | for (const i in b) { 17 | if (a[i] !== b[i]) { 18 | return true; 19 | } 20 | } 21 | 22 | return false; 23 | } 24 | 25 | return true; 26 | } 27 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/stripNonPrintableCharacters.ts: -------------------------------------------------------------------------------- 1 | export function stripNonPrintableCharacters(text: string): string { 2 | return text 3 | .replace(/\p{C}/gu, '') 4 | .replace(/\n\r/g, '\n') 5 | .replace(/\p{Zl}/gu, '\n') 6 | .replace(/\p{Zp}/gu, '\n') 7 | .replace(/\p{Zs}/gu, ' '); 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/tagFunction.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | const defaultToEmpty = R.defaultTo(''); 4 | 5 | const indexedReduce = R.addIndex(R.reduce); 6 | 7 | export const tagFunction = 8 | (fn: (template: string) => T) => 9 | (strings: TemplateStringsArray, ...values: any[]) => { 10 | const template = ( 11 | indexedReduce( 12 | (prev, string, index) => `${prev}${string}${defaultToEmpty(values[index])}`, 13 | '', 14 | strings, 15 | ) 16 | ); 17 | 18 | return fn(template); 19 | }; 20 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/trimLines.ts: -------------------------------------------------------------------------------- 1 | export function trimLines(str: string): string { 2 | if (!str) { 3 | return null; 4 | } 5 | 6 | return str 7 | .split('\n') 8 | .map(line => line.trim()) 9 | .filter(Boolean) 10 | .join('\n'); 11 | } 12 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/truncateText.ts: -------------------------------------------------------------------------------- 1 | export function truncateText(suffix: string, maxLen: number, str: string): string { 2 | if (str.length < maxLen) { 3 | return str; 4 | } 5 | 6 | return `${str.substr(0, maxLen)}${suffix}`; 7 | } 8 | -------------------------------------------------------------------------------- /packages/compiler-core/src/utils/wrapAround.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @example 3 | * wrapAround(10, -1) => 9 4 | * wrapAround(10, 1) => 1 5 | */ 6 | export const wrapAround = (max: number, value: number) => ((value % max) + max) % max; 7 | -------------------------------------------------------------------------------- /packages/compiler-core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["src/"], 4 | "compilerOptions": { 5 | "baseUrl": "src", 6 | "module": "CommonJS" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-grammar/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: ../../.eslintrc.yml 2 | -------------------------------------------------------------------------------- /packages/compiler-grammar/jest.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/extensions, import/no-default-export */ 2 | import { fileURLToPath } from 'node:url'; 3 | import { dirname } from 'path'; 4 | import { createJestConfig } from '../../config/jest.shared.config.mjs'; 5 | 6 | export default createJestConfig({ 7 | rootDir: dirname(fileURLToPath(import.meta.url)), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/compiler-grammar/rollup.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-default-export, import/extensions */ 2 | import { createPackageRollupConfig } from '../../config/rollup.shared.config.mjs'; 3 | 4 | export default createPackageRollupConfig(); 5 | -------------------------------------------------------------------------------- /packages/compiler-grammar/src/GrammarError.ts: -------------------------------------------------------------------------------- 1 | import { CompilerError } from '@ts-cc/core'; 2 | import { TokenLocation } from '@ts-cc/lexer'; 3 | 4 | export enum GrammarErrorCode { 5 | SYNTAX_ERROR, 6 | } 7 | 8 | export const GRAMMAR_ERROR_TRANSLATIONS: Record = { 9 | [GrammarErrorCode.SYNTAX_ERROR]: 'Syntax error!', 10 | }; 11 | 12 | /** 13 | * Error shown during grammar tokens analyze 14 | */ 15 | export class GrammarError extends CompilerError { 16 | constructor(code: GrammarErrorCode, loc?: TokenLocation, meta?: object) { 17 | super(GRAMMAR_ERROR_TRANSLATIONS, code, loc, meta); 18 | this.name = 'Grammar'; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/compiler-grammar/src/decorators/index.ts: -------------------------------------------------------------------------------- 1 | export * from './walkOverFields'; 2 | -------------------------------------------------------------------------------- /packages/compiler-grammar/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Grammar'; 2 | export * from './GrammarError'; 3 | export * from './decorators'; 4 | export * from './matchers'; 5 | export * from './tree'; 6 | export * from './utils'; 7 | export * from './visitors'; 8 | -------------------------------------------------------------------------------- /packages/compiler-grammar/src/matchers/empty.ts: -------------------------------------------------------------------------------- 1 | import { TreeNode } from '../tree/TreeNode'; 2 | 3 | export function empty(): TreeNode { 4 | return null; 5 | } 6 | -------------------------------------------------------------------------------- /packages/compiler-grammar/src/matchers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './empty'; 2 | -------------------------------------------------------------------------------- /packages/compiler-grammar/src/tree/NodeLocation.ts: -------------------------------------------------------------------------------- 1 | import { TokenLocation } from '@ts-cc/lexer'; 2 | 3 | /** 4 | * Location of single node (begin, end) 5 | */ 6 | export class NodeLocation { 7 | constructor( 8 | readonly start: TokenLocation, 9 | readonly end: TokenLocation, 10 | ) {} 11 | 12 | static fromTokenLoc(tokenLoc: TokenLocation): NodeLocation { 13 | return new NodeLocation(tokenLoc, tokenLoc); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/compiler-grammar/src/tree/TreeVisitor.ts: -------------------------------------------------------------------------------- 1 | import { AbstractTreeVisitor } from './AbstractTreeVisitor'; 2 | import { isTreeNode, TreeNode } from './TreeNode'; 3 | 4 | /** 5 | * Iterates over tree 6 | */ 7 | export abstract class TreeVisitor< 8 | T extends TreeNode = TreeNode, 9 | > extends AbstractTreeVisitor { 10 | /** 11 | * Begins iteration over tree 12 | */ 13 | override visit(node: T): this { 14 | if (!isTreeNode(node)) { 15 | return this; 16 | } 17 | 18 | return super.visit(node); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/compiler-grammar/src/tree/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AbstractTreeVisitor'; 2 | export * from './NodeLocation'; 3 | export * from './TokensIterator'; 4 | export * from './TreeGroupedVisitor'; 5 | export * from './TreeNode'; 6 | export * from './TreePrintVisitor'; 7 | export * from './TreeVisitor'; 8 | -------------------------------------------------------------------------------- /packages/compiler-grammar/src/utils/createBinOpIfBothSidesPresent.ts: -------------------------------------------------------------------------------- 1 | import { TreeNode } from '../tree/TreeNode'; 2 | 3 | export function createBinOpIfBothSidesPresent( 4 | ClassType: new (_op: O, _left: E, _right: E) => T, 5 | op: O, 6 | left: E, 7 | right: E, 8 | ): T | E { 9 | if (left && right) { 10 | return new ClassType(op, left, right); 11 | } 12 | 13 | if (!left) { 14 | return right; 15 | } 16 | 17 | return left; 18 | } 19 | -------------------------------------------------------------------------------- /packages/compiler-grammar/src/utils/fetchTokensUntilEOL.ts: -------------------------------------------------------------------------------- 1 | import { isLineTerminatorToken, type Token } from '@ts-cc/lexer'; 2 | import { TokensIterator } from '../tree/TokensIterator'; 3 | import { fetchTokensUntil } from './fetchTokensUntil'; 4 | 5 | /** 6 | * Fetch all tokens to end of line 7 | */ 8 | export function fetchTokensUntilEOL( 9 | parser: TokensIterator, 10 | excludeBreakToken?: boolean, 11 | ): Token[] { 12 | return fetchTokensUntil(isLineTerminatorToken, parser, excludeBreakToken); 13 | } 14 | -------------------------------------------------------------------------------- /packages/compiler-grammar/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './createBinOpIfBothSidesPresent'; 2 | export * from './eatLeftRecursiveOperators'; 3 | export * from './fetchTokensUntil'; 4 | export * from './fetchTokensUntilEOL'; 5 | -------------------------------------------------------------------------------- /packages/compiler-grammar/src/visitors/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ReducePostifxOperatorsVisitor'; 2 | -------------------------------------------------------------------------------- /packages/compiler-grammar/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["src/"], 4 | "compilerOptions": { 5 | "baseUrl": "src", 6 | "module": "CommonJS" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-lexer/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: ../../.eslintrc.yml 2 | -------------------------------------------------------------------------------- /packages/compiler-lexer/jest.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/extensions, import/no-default-export */ 2 | import { fileURLToPath } from 'node:url'; 3 | import { dirname } from 'path'; 4 | import { createJestConfig } from '../../config/jest.shared.config.mjs'; 5 | 6 | export default createJestConfig({ 7 | rootDir: dirname(fileURLToPath(import.meta.url)), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/compiler-lexer/rollup.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-default-export, import/extensions */ 2 | import { createPackageRollupConfig } from '../../config/rollup.shared.config.mjs'; 3 | 4 | export default createPackageRollupConfig(); 5 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lexer'; 2 | export * from './safeResultLexer'; 3 | export * from './shared'; 4 | export * from './tokens'; 5 | export * from './utils'; 6 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/safeResultLexer.ts: -------------------------------------------------------------------------------- 1 | import * as E from 'fp-ts/Either'; 2 | import { CompilerError } from '@ts-cc/core'; 3 | 4 | import { lexer, type LexerConfig } from './lexer'; 5 | import type { Token } from './tokens'; 6 | 7 | /** 8 | * Lexer that returns Result instead of throwable call 9 | */ 10 | export const safeResultLexer = 11 | (config: LexerConfig) => 12 | (code: string): E.Either => { 13 | try { 14 | return E.right(Array.from(lexer(config)(code))); 15 | } catch (e) { 16 | console.error(e); 17 | return E.left([e]); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/shared/LexerError.ts: -------------------------------------------------------------------------------- 1 | import { CompilerError } from '@ts-cc/core'; 2 | import { TokenLocation } from './TokenLocation'; 3 | 4 | export enum LexerErrorCode { 5 | UNKNOWN_TOKEN, 6 | UNTERMINATED_STRING, 7 | } 8 | 9 | export const LEXER_ERROR_TRANSLATIONS: Record = { 10 | [LexerErrorCode.UNKNOWN_TOKEN]: 'Unknown token "%{token}"!', 11 | [LexerErrorCode.UNTERMINATED_STRING]: 'Unterminated string!', 12 | }; 13 | 14 | /** 15 | * Error thrown during lexer phase! 16 | */ 17 | export class LexerError extends CompilerError { 18 | constructor(code: LexerErrorCode, loc?: TokenLocation, meta?: object) { 19 | super(LEXER_ERROR_TRANSLATIONS, code, loc, meta); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/shared/TokenLocation.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Provides row/column position of token inside source code 3 | */ 4 | export class TokenLocation { 5 | constructor( 6 | public row: number = 0, 7 | public column: number = 0, 8 | public pathname: string | null = null, 9 | ) {} 10 | 11 | append(row: number, column: number = 0): TokenLocation { 12 | return new TokenLocation(this.row + row, this.column + column, this.pathname); 13 | } 14 | 15 | clone(): TokenLocation { 16 | return new TokenLocation(this.row, this.column, this.pathname); 17 | } 18 | 19 | toString() { 20 | const { row, column } = this; 21 | 22 | return `row: ${row + 1}, col: ${column + 1}`; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/shared/index.ts: -------------------------------------------------------------------------------- 1 | export * from './LexerError'; 2 | export * from './TokenTypes'; 3 | export * from './TokenLocation'; 4 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/tokens/index.ts: -------------------------------------------------------------------------------- 1 | export { Token } from './Token'; 2 | 3 | export * from './types'; 4 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/tokens/types/IdentifierToken.ts: -------------------------------------------------------------------------------- 1 | import { Token, TokenType, TokenKind } from '../Token'; 2 | import { TokenLocation } from '../../shared/TokenLocation'; 3 | 4 | /** 5 | * Used in higher level grammar syntaxes 6 | */ 7 | export class IdentifierToken extends Token { 8 | constructor(value: T, text: string, loc: TokenLocation) { 9 | super(TokenType.KEYWORD, TokenKind.IDENTIFIER, text, loc, value); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/tokens/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './NumberToken'; 2 | export * from './FloatNumberToken'; 3 | export * from './IdentifierToken'; 4 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './extractNestableTokensList'; 2 | export * from './isEOFToken'; 3 | export * from './isFloatMathOpToken'; 4 | export * from './isLineTerminatorToken'; 5 | export * from './isLogicOpToken'; 6 | export * from './isMathOpToken'; 7 | export * from './isNonIdentifierKeywordToken'; 8 | export * from './isNumericToken'; 9 | export * from './isRelationOpToken'; 10 | export * from './joinTokensTexts'; 11 | export * from './matchCharacter'; 12 | export * from './parseNumberToken'; 13 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/utils/isEOFToken.ts: -------------------------------------------------------------------------------- 1 | import { TokenType } from '../shared/TokenTypes'; 2 | import type { Token } from '../tokens'; 3 | 4 | /** 5 | * Checks if end of file 6 | */ 7 | export function isEOFToken(token: Token): boolean { 8 | return token.type === TokenType.EOF; 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/utils/isFloatMathOpToken.ts: -------------------------------------------------------------------------------- 1 | import { TokenType } from '../shared/TokenTypes'; 2 | import { isMathOpToken } from './isMathOpToken'; 3 | 4 | /** 5 | * Checks if token can perform numeric expression 6 | */ 7 | export function isFloatMathOpToken(type: TokenType): boolean { 8 | switch (type) { 9 | case TokenType.BIT_SHIFT_LEFT: 10 | case TokenType.BIT_SHIFT_RIGHT: 11 | case TokenType.BIT_OR: 12 | case TokenType.BIT_AND: 13 | case TokenType.POW: 14 | case TokenType.NOT: 15 | return false; 16 | 17 | default: 18 | return isMathOpToken(type); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/utils/isLineTerminatorToken.ts: -------------------------------------------------------------------------------- 1 | import { TokenType } from '../shared/TokenTypes'; 2 | import type { Token } from '../tokens'; 3 | 4 | /** 5 | * Used for check when stop parsing 6 | */ 7 | export function isLineTerminatorToken(token: Token): boolean { 8 | return token.type === TokenType.EOL || token.type === TokenType.EOF; 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/utils/isNonIdentifierKeywordToken.ts: -------------------------------------------------------------------------------- 1 | import type { Token } from '../tokens/Token'; 2 | import { TokenType } from '../shared/TokenTypes'; 3 | 4 | export function isNonIdentifierKeywordToken(token: Token) { 5 | return token?.type === TokenType.KEYWORD && token.kind === null; 6 | } 7 | -------------------------------------------------------------------------------- /packages/compiler-lexer/src/utils/isNumericToken.ts: -------------------------------------------------------------------------------- 1 | import { TokenType } from '../shared/TokenTypes'; 2 | 3 | export function isNumericToken(type: TokenType): boolean { 4 | switch (type) { 5 | case TokenType.NUMBER: 6 | case TokenType.FLOAT_NUMBER: 7 | return true; 8 | 9 | default: 10 | return false; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/compiler-lexer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["src/"], 4 | "compilerOptions": { 5 | "baseUrl": "src", 6 | "module": "CommonJS" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: ../../.eslintrc.yml 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/jest.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/extensions, import/no-default-export */ 2 | import { fileURLToPath } from 'node:url'; 3 | import { dirname } from 'path'; 4 | import { createJestConfig } from '../../config/jest.shared.config.mjs'; 5 | 6 | export default createJestConfig({ 7 | rootDir: dirname(fileURLToPath(import.meta.url)), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/rollup.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-default-export, import/extensions */ 2 | import { createPackageRollupConfig } from '../../config/rollup.shared.config.mjs'; 3 | 4 | export default createPackageRollupConfig(); 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/index.ts: -------------------------------------------------------------------------------- 1 | import { CCompilerArch } from '../constants'; 2 | import { CArchDescriptor } from './types'; 3 | 4 | export * from './x86/asm-utils'; 5 | import * as X86_16 from './x86/modes/16bit/sizeofPrimitiveType'; 6 | 7 | const COMPILER_ARCH_DESCRIPTORS: Record> = { 8 | [CCompilerArch.X86_16]: { 9 | sizeofPrimitiveType: X86_16.sizeofPrimitiveType, 10 | regs: { 11 | integral: { 12 | maxRegSize: 2, 13 | }, 14 | }, 15 | }, 16 | }; 17 | 18 | export function getCompilerArchDescriptor(arch: CCompilerArch) { 19 | return COMPILER_ARCH_DESCRIPTORS[arch]; 20 | } 21 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/types.ts: -------------------------------------------------------------------------------- 1 | export type SizeofPrimitiveTypeFn = (specifiers: number) => number; 2 | 3 | export type CArchRegsInfo = { 4 | integral: { 5 | maxRegSize: number; 6 | }; 7 | }; 8 | 9 | export type CArchDescriptor = { 10 | sizeofPrimitiveType: SizeofPrimitiveTypeFn; 11 | regs: CArchRegsInfo; 12 | }; 13 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/asm-utils/genComment.ts: -------------------------------------------------------------------------------- 1 | export function genComment(msg: string): string { 2 | return `; ${msg}`; 3 | } 4 | 5 | export function withInlineComment(line: string, msg: string) { 6 | if (!line) { 7 | return line; 8 | } 9 | 10 | return `${line.trim().padEnd(25)} ${genComment(msg)}`; 11 | } 12 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/asm-utils/genInstruction.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | import { X86PrefixName } from '@ts-cc/x86-assembler'; 3 | 4 | export function genInstruction( 5 | mnemonic: [X86PrefixName, string] | string, 6 | ...args: (number | string)[] 7 | ): string { 8 | const [prefix, name] = R.is(String, mnemonic) ? [null, mnemonic] : mnemonic; 9 | 10 | const code = [prefix, name, args && R.reject(R.isNil, args).join(', ')] 11 | .filter(Boolean) 12 | .join(' '); 13 | 14 | return code; 15 | } 16 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/asm-utils/genLabel.ts: -------------------------------------------------------------------------------- 1 | const DEFAULT_UNIQ_PREFIX = '@@_'; 2 | 3 | export function genLabelName(name: string): string { 4 | return `${DEFAULT_UNIQ_PREFIX}${name.replace(/[{}]/g, '_')}`; 5 | } 6 | 7 | /** 8 | * @todo 9 | * Move it to compiler context! Compiler should generate unique 10 | * label prefix per compilation unit! 11 | */ 12 | export function genLabel(name: string, prefix: boolean = true): string { 13 | const inner = prefix ? genLabelName(name) : name; 14 | 15 | return `${inner}:`; 16 | } 17 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/asm-utils/genLabeledInstruction.ts: -------------------------------------------------------------------------------- 1 | export function genLabeledInstruction(label: string, instruction: string) { 2 | return `${label}: ${instruction}`; 3 | } 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/asm-utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './genComment'; 2 | export * from './genDefConst'; 3 | export * from './genInstruction'; 4 | export * from './genLabel'; 5 | export * from './genLabeledInstruction'; 6 | export * from './genMemAddress'; 7 | export * from './wrapWithX86BootsectorAsm'; 8 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/call-conventions/index.ts: -------------------------------------------------------------------------------- 1 | import { CFunctionCallConvention } from '#constants'; 2 | 3 | import type { X86ConventionalFnCaller } from './X86ConventionalFnCaller'; 4 | import { X86StdcallFnCaller } from './X86StdcallFnCaller'; 5 | 6 | const X86ConventionalFnCallers: Record = 7 | { 8 | [CFunctionCallConvention.STDCALL]: new X86StdcallFnCaller(), 9 | }; 10 | 11 | export const getX86FnCaller = ( 12 | convention: CFunctionCallConvention, 13 | ): X86ConventionalFnCaller => X86ConventionalFnCallers[convention]; 14 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/compilers/asm/index.ts: -------------------------------------------------------------------------------- 1 | export * from './compileAsmClobbers'; 2 | export * from './compileAsmInputs'; 3 | export * from './compileAsmInstruction'; 4 | export * from './compileAsmOutputs'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/compilers/builtin/index.ts: -------------------------------------------------------------------------------- 1 | export * from './compileBuiltinCallFn'; 2 | export * from './va'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/compilers/builtin/va/index.ts: -------------------------------------------------------------------------------- 1 | export * from './compileBuiltinVaArg'; 2 | export * from './compileBuiltinVaStart'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/compilers/compileLabelInstruction.ts: -------------------------------------------------------------------------------- 1 | import { IRLabelInstruction } from 'frontend/ir/instructions'; 2 | import { X86CompilerInstructionFnAttrs } from '../../constants/types'; 3 | import { genLabel } from '../../asm-utils'; 4 | import { X86CompileInstructionOutput } from './shared'; 5 | 6 | type LabelInstructionCompilerAttrs = X86CompilerInstructionFnAttrs; 7 | 8 | export function compileLabelInstruction({ instruction }: LabelInstructionCompilerAttrs) { 9 | return X86CompileInstructionOutput.ofInstructions([genLabel(instruction.name)]); 10 | } 11 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/compilers/data/index.ts: -------------------------------------------------------------------------------- 1 | export * from './compileDataSegment'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/compilers/math/index.ts: -------------------------------------------------------------------------------- 1 | export * from './compileMathInstruction'; 2 | export * from './int'; 3 | export * from './isNopMathInstruction'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/compilers/math/int/index.ts: -------------------------------------------------------------------------------- 1 | export * from './compileIntMathInstruction'; 2 | export * from './compileIntMathSingleInstruction'; 3 | export * from './ensureFunctionNotOverrideOutput'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/compilers/math/x87/index.ts: -------------------------------------------------------------------------------- 1 | export * from './compileX87MathInstruction'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/compilers/shared/index.ts: -------------------------------------------------------------------------------- 1 | export * from './X86CompileInstructionOutput'; 2 | export * from './X86ConventionalFnCaller'; 3 | export * from './compileMemcpy'; 4 | export * from './compileStackMemcpy'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/reg-allocator/index.ts: -------------------------------------------------------------------------------- 1 | export * from './int'; 2 | export * from './x87'; 3 | export * from './mem'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/reg-allocator/int/index.ts: -------------------------------------------------------------------------------- 1 | export * from './X86BasicRegAllocator'; 2 | export * from './X86RegOwnershipTracker'; 3 | export * from './ownership'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/reg-allocator/int/ownership.ts: -------------------------------------------------------------------------------- 1 | import { X86RegName } from '@ts-cc/x86-assembler'; 2 | 3 | export type IRRegOwnership = { 4 | reg: X86RegName; 5 | noPrune?: boolean; 6 | }; 7 | 8 | export type IRRegOwnershipMap = Partial>; 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/reg-allocator/mem/index.ts: -------------------------------------------------------------------------------- 1 | export * from './X86MemOwnershipTracker'; 2 | export * from './ownership'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/reg-allocator/x87/index.ts: -------------------------------------------------------------------------------- 1 | export * from './X87BasicRegAllocator'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './queryAndMarkX86RegsMap'; 2 | export * from './queryX86RegsMap'; 3 | export * from './recursiveSetAvailabilityInX86RegMap'; 4 | export * from './recursiveX86RegMapLookup'; 5 | export * from './restoreInX86IntRegsMap'; 6 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/variables/X86Label.ts: -------------------------------------------------------------------------------- 1 | export class X86Label { 2 | constructor(readonly name: string) {} 3 | } 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/variables/X86StackOffset.ts: -------------------------------------------------------------------------------- 1 | export class X86StackOffset { 2 | constructor(readonly offset: number) {} 3 | } 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/backend/variables/index.ts: -------------------------------------------------------------------------------- 1 | export * from './X86Label'; 2 | export * from './X86StackOffset'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/index.ts: -------------------------------------------------------------------------------- 1 | export * from './asm-utils'; 2 | export * from './backend/X86ArchBackend'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/arch/x86/modes/16bit/index.ts: -------------------------------------------------------------------------------- 1 | export * from './sizeofPrimitiveType'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/backend/abstract/CAbstractArchBackend.ts: -------------------------------------------------------------------------------- 1 | import { CCompilerConfig } from '../../constants'; 2 | import { IRScopeGeneratorResult } from '../../frontend/ir/generator'; 3 | import { CBackendCompilerResult } from '../constants/types'; 4 | 5 | export abstract class CAbstractArchBackend { 6 | constructor(readonly config: CCompilerConfig) {} 7 | 8 | abstract compileIR(ir: IRScopeGeneratorResult): CBackendCompilerResult; 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/backend/constants/types.ts: -------------------------------------------------------------------------------- 1 | export type CBackendCompilerResult = { 2 | asm: string; 3 | }; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/backend/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants/types'; 2 | export * from './safeGenAsmIRCode'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/builtins/createBuiltinAnalyzeScope.ts: -------------------------------------------------------------------------------- 1 | import type { CCompilerArch } from '#constants'; 2 | 3 | import { CScopeTree } from 'frontend/analyze/scope'; 4 | import * as Defs from './defs'; 5 | 6 | export const createBuiltinAnalyzeScope = (arch: CCompilerArch): CScopeTree => { 7 | const tree = new CScopeTree({ 8 | arch, 9 | }); 10 | 11 | tree.defineTypes([ 12 | new Defs.VA.CVaListBuiltinStruct({ arch }), 13 | new Defs.VA.CVaStartBuiltinFn({ arch }), 14 | new Defs.VA.CVaArgBuiltinFn({ arch }), 15 | new Defs.VA.CVaEndBuiltinFn({ arch }), 16 | new Defs.CAllocaBuiltinFn({ arch }), 17 | ]); 18 | 19 | return tree; 20 | }; 21 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/builtins/defs/index.ts: -------------------------------------------------------------------------------- 1 | export * as VA from './va'; 2 | export * from './Alloca.builtin'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/builtins/defs/va/index.ts: -------------------------------------------------------------------------------- 1 | export * from './VaArgFn.builtin'; 2 | export * from './VaEndFn.builtin'; 3 | export * from './VaList.builtin'; 4 | export * from './VaStartFn.builtin'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/builtins/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CBuiltinFnDeclType'; 2 | export * from './createBuiltinAnalyzeScope'; 3 | export * from './utils'; 4 | export * from './defs/va'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/builtins/utils/builtinPrefix.ts: -------------------------------------------------------------------------------- 1 | const BUILTIN_PREFIX = '__builtin_'; 2 | 3 | type BuiltinPrefixName = typeof BUILTIN_PREFIX; 4 | 5 | export type BuiltinFnName = `${BuiltinPrefixName}${S}`; 6 | 7 | export const withBuiltinPrefix = (name: S): BuiltinFnName => 8 | `${BUILTIN_PREFIX}${name}`; 9 | 10 | export const hasBuiltinPrefix = (name: string) => name.startsWith(BUILTIN_PREFIX); 11 | 12 | export const extractBuiltinName = (name: string) => name.substring(BUILTIN_PREFIX.length); 13 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/builtins/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './builtinPrefix'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/constants/config.ts: -------------------------------------------------------------------------------- 1 | import type { X86TargetCPU } from '@ts-cc/x86-assembler'; 2 | import type { CLexerConfig } from '../frontend/parser'; 3 | import type { IRGeneratorConfig } from '../frontend/ir/constants'; 4 | import type { CPreprocessorConfig } from '../frontend/preprocessor/interpreter'; 5 | 6 | export type CCompilerTargetCPU = X86TargetCPU; 7 | 8 | export enum CCompilerArch { 9 | X86_16 = 'X86_16', 10 | } 11 | 12 | export type CCompilerConfig = IRGeneratorConfig & { 13 | target?: CCompilerTargetCPU; 14 | lexer?: CLexerConfig; 15 | preprocessor?: CPreprocessorConfig; 16 | }; 17 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lang'; 2 | export * from './config'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/expression-eval/index.ts: -------------------------------------------------------------------------------- 1 | export * from './evalConstantExpression'; 2 | export * from './visitors/ConstantExpressionEvalVisitor'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/index.ts: -------------------------------------------------------------------------------- 1 | export * from './type-builder/CTypeAnalyzeContext'; 2 | export * from './type-builder/CTypeAnalyzeVisitor'; 3 | export * from './type-builder/CInnerTypeTreeVisitor'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/initializer-builder/CVariableInitializerVisitor.ts: -------------------------------------------------------------------------------- 1 | import { isCompilerTreeNode } from 'frontend/parser'; 2 | 3 | import { AbstractTreeVisitor } from '@ts-cc/grammar'; 4 | import { CVariableInitializePair, CVariableInitializerTree } from '../../scope/variables'; 5 | 6 | export class CVariableInitializerVisitor extends AbstractTreeVisitor< 7 | CVariableInitializePair | CVariableInitializerTree 8 | > { 9 | shouldVisitNode(node: CVariableInitializePair | CVariableInitializerTree): boolean { 10 | return !isCompilerTreeNode(node); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/initializer-builder/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CVariableInitializerPrintVisitor'; 2 | export * from './CVariableInitializerVisitor'; 3 | export * from './builder/CTypeInitializerBuilderVisitor'; 4 | export * from './extractor/extractInitializerTreeForType'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/CInnerTypeTreeVisitor.ts: -------------------------------------------------------------------------------- 1 | import { GroupTreeVisitor } from '@ts-cc/grammar'; 2 | import { ASTCCompilerNode } from '../../../parser/ast/ASTCCompilerNode'; 3 | import { CTypeAnalyzeContext } from './CTypeAnalyzeContext'; 4 | import type { CTypeAnalyzeVisitor } from './CTypeAnalyzeVisitor'; 5 | 6 | export abstract class CInnerTypeTreeVisitor< 7 | P extends GroupTreeVisitor = CTypeAnalyzeVisitor, 8 | C extends CTypeAnalyzeContext = CTypeAnalyzeContext, 9 | > extends GroupTreeVisitor { 10 | get arch() { 11 | return this.context.config.arch; 12 | } 13 | 14 | get scope() { 15 | return this.context.scope; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/CTypeAnalyzeContext.ts: -------------------------------------------------------------------------------- 1 | import { CTypeCheckConfig } from '../../constants'; 2 | import { CScopeTree } from '../../scope/CScopeTree'; 3 | import { CFunctionDeclType } from '../../types'; 4 | 5 | export type CTypeAnalyzeContext = { 6 | abstract?: boolean; 7 | scope: CScopeTree; 8 | config: CTypeCheckConfig; 9 | currentAnalyzed: { 10 | fnType: CFunctionDeclType; 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/creators/ASTCConditionalTypeCreator.ts: -------------------------------------------------------------------------------- 1 | import { ASTCCompilerKind, ASTCConditionalExpression } from 'frontend/parser/ast'; 2 | 3 | import { ASTCTypeCreator } from './ASTCTypeCreator'; 4 | 5 | export class ASTCConditionalExpressionTypeCreator extends ASTCTypeCreator { 6 | kind = ASTCCompilerKind.ConditionalExpression; 7 | 8 | override leave(node: ASTCConditionalExpression): void { 9 | node.type = node.trueExpression?.type ?? node.falseExpression?.type; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/creators/ASTCDoWhileStmtTypeCreator.ts: -------------------------------------------------------------------------------- 1 | import { ASTCCompilerKind, ASTCDoWhileStatement } from 'frontend/parser/ast'; 2 | import { ASTCTypeCreator } from './ASTCTypeCreator'; 3 | 4 | export class ASTCDoWhileStmtTypeCreator extends ASTCTypeCreator { 5 | kind = ASTCCompilerKind.DoWhileStmt; 6 | 7 | override enter(node: ASTCDoWhileStatement): boolean { 8 | const { analyzeVisitor } = this; 9 | const { expression, statement } = node; 10 | 11 | if (expression) { 12 | analyzeVisitor.visit(expression); 13 | } 14 | 15 | if (statement) { 16 | analyzeVisitor.visitBlockScope(statement); 17 | } 18 | 19 | return false; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/creators/ASTCExpressionStmtTypeCreator.ts: -------------------------------------------------------------------------------- 1 | import { ASTCCompilerKind, ASTCExpressionStatement } from 'frontend/parser/ast'; 2 | import { ASTCTypeCreator } from './ASTCTypeCreator'; 3 | 4 | export class ASTCExpressionStmtTypeCreator extends ASTCTypeCreator { 5 | kind = ASTCCompilerKind.ExpressionStmt; 6 | 7 | override leave(node: ASTCExpressionStatement): void { 8 | node.type ??= node.expression?.type; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/creators/ASTCExpressionTypeCreator.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | import { ASTCCompilerKind, ASTCExpression } from 'frontend/parser/ast'; 4 | import { ASTCTypeCreator } from './ASTCTypeCreator'; 5 | 6 | export class ASTCExpressionTypeCreator extends ASTCTypeCreator { 7 | kind = ASTCCompilerKind.Expression; 8 | 9 | override leave(node: ASTCExpression): void { 10 | node.type ??= R.last(node.assignments)?.type; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/creators/ASTCForStmtTypeCreator.ts: -------------------------------------------------------------------------------- 1 | import { ASTCCompilerKind, ASTCForStatement } from 'frontend/parser/ast'; 2 | import { ASTCTypeCreator } from './ASTCTypeCreator'; 3 | 4 | export class ASTCForStmtTypeCreator extends ASTCTypeCreator { 5 | kind = ASTCCompilerKind.ForStmt; 6 | 7 | override enter(node: ASTCForStatement): boolean { 8 | const { analyzeVisitor } = this; 9 | const { declaration, condition, expression, statement } = node; 10 | 11 | analyzeVisitor.enterScope(node, visitor => { 12 | visitor.visit(declaration).visit(condition).visit(expression).visit(statement); 13 | }); 14 | 15 | return false; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/creators/ASTCInitializerTypeCreator.ts: -------------------------------------------------------------------------------- 1 | import { ASTCCompilerKind, ASTCInitializer } from 'frontend/parser/ast'; 2 | import { ASTCTypeCreator } from './ASTCTypeCreator'; 3 | 4 | export class ASTCInitializerTypeCreator extends ASTCTypeCreator { 5 | kind = ASTCCompilerKind.Initializer; 6 | 7 | override leave(node: ASTCInitializer): void { 8 | node.type = node.assignmentExpression?.type; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/creators/ASTCSizeofUnaryExpressionTypeCreator.ts: -------------------------------------------------------------------------------- 1 | import { CPrimitiveType } from 'frontend/analyze/types'; 2 | import { ASTCCompilerKind, ASTCSizeofUnaryExpression } from 'frontend/parser/ast'; 3 | 4 | import { ASTCTypeCreator } from './ASTCTypeCreator'; 5 | 6 | export class ASTCSizeofUnaryExpressionTypeCreator extends ASTCTypeCreator { 7 | kind = ASTCCompilerKind.SizeofUnaryExpression; 8 | 9 | override leave(node: ASTCSizeofUnaryExpression): boolean { 10 | node.type = CPrimitiveType.int(this.arch); 11 | node.extractedType = node.typeName?.type ?? node.unaryExpression?.type; 12 | return false; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/creators/ASTCUnaryExpressionTypeCreator.ts: -------------------------------------------------------------------------------- 1 | import { ASTCCompilerKind, ASTCUnaryExpression } from 'frontend/parser/ast'; 2 | 3 | import { ASTCTypeCreator } from './ASTCTypeCreator'; 4 | 5 | export class ASTCUnaryExpressionTypeCreator extends ASTCTypeCreator { 6 | kind = ASTCCompilerKind.UnaryExpression; 7 | 8 | override leave(node: ASTCUnaryExpression): void { 9 | node.type = node.castExpression?.type; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/creators/ASTCWhileStmtTypeCreator.ts: -------------------------------------------------------------------------------- 1 | import { ASTCCompilerKind, ASTCWhileStatement } from 'frontend/parser/ast'; 2 | import { ASTCTypeCreator } from './ASTCTypeCreator'; 3 | 4 | export class ASTCWhileStmtTypeCreator extends ASTCTypeCreator { 5 | kind = ASTCCompilerKind.WhileStmt; 6 | 7 | override enter(node: ASTCWhileStatement): boolean { 8 | const { analyzeVisitor } = this; 9 | const { expression, statement } = node; 10 | 11 | if (expression) { 12 | analyzeVisitor.visit(expression); 13 | } 14 | 15 | if (statement) { 16 | analyzeVisitor.visitBlockScope(statement); 17 | } 18 | 19 | return false; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/extractor/index.ts: -------------------------------------------------------------------------------- 1 | export * from './extractStructTypeFromNode'; 2 | export * from './extractEnumTypeFromNode'; 3 | export * from './extractSpecifierType'; 4 | export * from './extractInitDeclaratorTypeVariables'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/ast/type-builder/index.ts: -------------------------------------------------------------------------------- 1 | export * from './extractor'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/casts/castToBaseTypeIfPointer.ts: -------------------------------------------------------------------------------- 1 | import { CType, isPointerLikeType } from '../types'; 2 | 3 | export function castToBaseTypeIfPointer(type: CType) { 4 | if (!isPointerLikeType(type)) { 5 | return type; 6 | } 7 | 8 | return type.baseType; 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/casts/castToPointerIfArray.ts: -------------------------------------------------------------------------------- 1 | import { CPointerType, CType, isArrayLikeType } from '../types'; 2 | 3 | export function castToPointerIfArray(type: CType) { 4 | if (!isArrayLikeType(type)) { 5 | return type; 6 | } 7 | 8 | return CPointerType.ofType(type.getSourceType()); 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/casts/castToPointerIfFunction.ts: -------------------------------------------------------------------------------- 1 | import { CPointerType, CType, isFuncDeclLikeType } from '../types'; 2 | 3 | export function castToPointerIfFunction(type: CType) { 4 | if (!isFuncDeclLikeType(type)) { 5 | return type; 6 | } 7 | 8 | return CPointerType.ofType(type); 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/casts/charToInt.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Converts char to ascii code 3 | */ 4 | export function charToInt(character: String): number { 5 | return character.charCodeAt(0); 6 | } 7 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/casts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './castToBaseTypeIfPointer'; 2 | export * from './castToPointerIfArray'; 3 | export * from './castToPointerIfFunction'; 4 | export * from './charToInt'; 5 | export * from './tryCastToPointer'; 6 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/casts/tryCastToPointer.ts: -------------------------------------------------------------------------------- 1 | import type { CType } from '../types'; 2 | 3 | import { castToPointerIfArray } from './castToPointerIfArray'; 4 | import { castToPointerIfFunction } from './castToPointerIfFunction'; 5 | 6 | export function tryCastToPointer(type: CType) { 7 | return castToPointerIfArray(castToPointerIfFunction(type)); 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/checker/index.ts: -------------------------------------------------------------------------------- 1 | export * from './checkLeftTypeOverlapping'; 2 | export * from './isPointerArithmeticOperator'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/checker/isPointerArithmeticOperator.ts: -------------------------------------------------------------------------------- 1 | import { TokenType } from '@ts-cc/lexer'; 2 | 3 | export function isPointerArithmeticOperator(operator: TokenType) { 4 | return operator === TokenType.PLUS || operator === TokenType.MINUS; 5 | } 6 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/constants/config.ts: -------------------------------------------------------------------------------- 1 | import { CCompilerArch } from '#constants'; 2 | 3 | export type CTypeCheckConfig = { 4 | arch: CCompilerArch; 5 | }; 6 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './config'; 2 | export * from './bitmaps'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | export * from './utils'; 3 | export * from './types'; 4 | export * from './scope'; 5 | export * from './safeBuildTypedTree'; 6 | export * from './errors/CTypeCheckError'; 7 | export * from './dump/CScopePrintVisitor'; 8 | export * from './ast'; 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/interfaces/IsNewScopeASTNode.ts: -------------------------------------------------------------------------------- 1 | import type { CScopeTree } from '../scope/CScopeTree'; 2 | 3 | export interface IsNewScopeASTNode { 4 | scope?: CScopeTree; 5 | } 6 | 7 | export function isNewScopeASTNode(node: any): node is IsNewScopeASTNode { 8 | return 'scope' in node; 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './IsNewScopeASTNode'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/scope/CScopeVisitor.ts: -------------------------------------------------------------------------------- 1 | import { AbstractTreeVisitor } from '@ts-cc/grammar'; 2 | import { CScopeTree } from './CScopeTree'; 3 | 4 | export class CScopeVisitor extends AbstractTreeVisitor {} 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/scope/CTypedef.ts: -------------------------------------------------------------------------------- 1 | import { CNamedTypedEntry, CVariable } from './variables'; 2 | 3 | export class CTypedef extends CNamedTypedEntry { 4 | static ofVariable({ name, type }: CVariable) { 5 | return new CTypedef({ 6 | name, 7 | type, 8 | }); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/scope/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CFunctionScope'; 2 | export * from './CScopeTree'; 3 | export * from './CScopeVisitor'; 4 | export * from './variables'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/scope/variables/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CNamedTypedEntry'; 2 | export * from './CVariable'; 3 | export * from './CVariableInitializerTree'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/CUnknownType.ts: -------------------------------------------------------------------------------- 1 | import { CType } from './CType'; 2 | 3 | export class CUnknownType extends CType { 4 | getDisplayName() { 5 | return 'unknown'; 6 | } 7 | 8 | override isUnknown() { 9 | return true; 10 | } 11 | 12 | override isEqual() { 13 | return true; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/function/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CFunctionDeclType'; 2 | export * from './CFunctionSpecifierMonad'; 3 | export * from './CFunctionStorageClassMonad'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CType'; 2 | export * from './CPrimitiveType'; 3 | export * from './CPointerType'; 4 | export * from './CEnumType'; 5 | export * from './CArrayType'; 6 | export * from './CFlagType'; 7 | export * from './CUnknownType'; 8 | export * from './struct'; 9 | export * from './union'; 10 | export * from './function'; 11 | export * from './utils/typeofValueOrNode'; 12 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/struct/align/getPackedAlignEntryOffset.ts: -------------------------------------------------------------------------------- 1 | import { StructFieldAlignFn } from '../constants/types'; 2 | 3 | export const getPackedAlignEntryOffset: StructFieldAlignFn = struct => 4 | struct.getByteSize(); 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/struct/align/index.ts: -------------------------------------------------------------------------------- 1 | import { CStructAlign } from '#constants'; 2 | import { StructFieldAlignFn } from '../constants/types'; 3 | import { getPackedAlignEntryOffset } from './getPackedAlignEntryOffset'; 4 | 5 | export const StructFieldAligner: Record = { 6 | [CStructAlign.PACKED]: getPackedAlignEntryOffset, 7 | }; 8 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/struct/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/struct/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CStructType'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/union/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/union/constants/types.ts: -------------------------------------------------------------------------------- 1 | import { CTypeDescriptor } from '../../CType'; 2 | import { CNamedTypedEntry } from '../../../scope/variables/CNamedTypedEntry'; 3 | 4 | export class CUnionEntry extends CNamedTypedEntry {} 5 | 6 | export type CUnionFieldsMap = Map; 7 | 8 | export type CUnionTypeDescriptor = CTypeDescriptor & { 9 | name?: string; 10 | fields: CUnionFieldsMap; 11 | }; 12 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/union/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CUnionType'; 2 | export * from './constants'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/utils/getBaseType.ts: -------------------------------------------------------------------------------- 1 | import { isArrayLikeType } from '../CArrayType'; 2 | import { isPointerLikeType } from '../CPointerType'; 3 | import { CType } from '../CType'; 4 | import { getBaseTypeIfArray } from './getBaseTypeIfArray'; 5 | 6 | export function getBaseType(type: CType) { 7 | if (isArrayLikeType(type)) { 8 | return getBaseTypeIfArray(type.baseType); 9 | } 10 | 11 | if (isPointerLikeType(type)) { 12 | return type.baseType; 13 | } 14 | 15 | return type; 16 | } 17 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/utils/getBaseTypeIfArray.ts: -------------------------------------------------------------------------------- 1 | import { isArrayLikeType } from '../CArrayType'; 2 | import type { CType } from '../CType'; 3 | 4 | export function getBaseTypeIfArray(type: CType): CType { 5 | if (isArrayLikeType(type)) { 6 | return getBaseTypeIfArray(type.baseType); 7 | } 8 | 9 | return type; 10 | } 11 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/utils/getBaseTypeIfPtr.ts: -------------------------------------------------------------------------------- 1 | import { isPointerLikeType } from '../CPointerType'; 2 | import type { CType } from '../CType'; 3 | 4 | export function getBaseTypeIfPtr(type: CType): CType { 5 | if (isPointerLikeType(type)) { 6 | return type.baseType; 7 | } 8 | 9 | return type; 10 | } 11 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/utils/getSourceNonArrayType.ts: -------------------------------------------------------------------------------- 1 | import { isArrayLikeType } from '../CArrayType'; 2 | import type { CType } from '../CType'; 3 | 4 | export function getSourceNonArrayType(type: CType): CType { 5 | if (isArrayLikeType(type)) { 6 | return type.getFlattenInfo().type; 7 | } 8 | 9 | return type; 10 | } 11 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/utils/getSourceNonPtrType.ts: -------------------------------------------------------------------------------- 1 | import { isArrayLikeType } from '../CArrayType'; 2 | import { isPointerLikeType } from '../CPointerType'; 3 | import type { CType } from '../CType'; 4 | 5 | /** 6 | * Extracts: 7 | * 8 | * - int from int** 9 | * - int from int[4][4] 10 | * - int from int 11 | */ 12 | export function getSourceNonPtrType(type: CType): CType { 13 | if (isPointerLikeType(type)) { 14 | return getSourceNonPtrType(type.baseType); 15 | } 16 | 17 | if (isArrayLikeType(type)) { 18 | return type.getFlattenInfo().type; 19 | } 20 | 21 | return type; 22 | } 23 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './getBaseType'; 2 | export * from './getBaseTypeIfArray'; 3 | export * from './getBaseTypeIfPtr'; 4 | export * from './getSourceNonArrayType'; 5 | export * from './getSourceNonPtrType'; 6 | export * from './isImplicitPtrType'; 7 | export * from './typeofValueOrNode'; 8 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/utils/isImplicitPtrType.ts: -------------------------------------------------------------------------------- 1 | import { CType } from '../CType'; 2 | import { isArrayLikeType } from '../CArrayType'; 3 | import { isFuncDeclLikeType } from '../function'; 4 | 5 | export function isImplicitPtrType(type: CType) { 6 | return isArrayLikeType(type) || isFuncDeclLikeType(type); 7 | } 8 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/types/utils/typeofValueOrNode.ts: -------------------------------------------------------------------------------- 1 | import { isCompilerTreeNode } from 'frontend/parser'; 2 | import { CCompilerArch } from '#constants'; 3 | 4 | import { CPrimitiveType } from '../CPrimitiveType'; 5 | import { CType } from '../CType'; 6 | 7 | export function typeofValueOrNode(arch: CCompilerArch, value: any): CType { 8 | if (isCompilerTreeNode(value)) { 9 | return value.type; 10 | } 11 | 12 | return CPrimitiveType.typeofValue(arch, value); 13 | } 14 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/utils/bitsetToKeywords.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | import { hasFlag } from '@ts-cc/core'; 4 | 5 | /** 6 | * 0b0110 => ['long', 'short'] 7 | */ 8 | export function bitsetToKeywords( 9 | bitmap: Record, 10 | number: number, 11 | ): string[] { 12 | if (R.isNil(number)) { 13 | return []; 14 | } 15 | 16 | const keywords: string[] = []; 17 | R.forEachObjIndexed((flag, keyword) => { 18 | if (hasFlag(flag, number)) { 19 | keywords.push(keyword); 20 | } 21 | }, bitmap); 22 | 23 | return keywords; 24 | } 25 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './bitsetToKeywords'; 2 | export * from './isNamedType'; 3 | export * from './parseKeywordsToBitset'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/analyze/utils/isNamedType.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | import type { CType } from '../types/CType'; 3 | 4 | export type CAbstractNamedType = CType & { 5 | name: string; 6 | }; 7 | 8 | export function isNamedType(obj: CType): obj is CAbstractNamedType { 9 | return R.has('name', obj.unwrap() || {}); 10 | } 11 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/index.ts: -------------------------------------------------------------------------------- 1 | export * from './parser'; 2 | export * from './preprocessor'; 3 | export * from './cIRcompiler'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/constants/config.ts: -------------------------------------------------------------------------------- 1 | import { CCompilerArch } from '#constants'; 2 | import { IROptimizerConfig } from '../optimizer/constants/types'; 3 | 4 | export type IRGeneratorConfig = { 5 | arch: CCompilerArch; 6 | optimization: IROptimizerConfig; 7 | }; 8 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './config'; 2 | export * from './ir'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/constants/ir.ts: -------------------------------------------------------------------------------- 1 | export enum IROpcode { 2 | ASM = 'ASM', 3 | ASSIGN = 'ASSIGN', 4 | ALLOC = 'ALLOC', 5 | STORE = 'STORE', 6 | LOAD = 'LOAD', 7 | CALL = 'CALL', 8 | LABEL = 'LABEL', 9 | BR = 'BR', 10 | ICMP = 'ICMP', 11 | PHI = 'PHI', 12 | JMP = 'JMP', 13 | FN_DECL = 'FN_DECL', 14 | FN_DECL_END = 'FN_DECL_END', 15 | RET = 'RET', 16 | MATH = 'MATH', 17 | MATH_SINGLE = 'MATH_SINGLE', 18 | LABEL_OFFSET = 'LABEL_OFFSET', 19 | LEA = 'LEA', 20 | DEF_DATA = 'DEF_DATA', 21 | COMMENT = 'COMMENT', 22 | CAST = 'CAST', 23 | } 24 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/dump/getIRTypeDisplayName.ts: -------------------------------------------------------------------------------- 1 | import { CType } from '../../analyze'; 2 | 3 | export function getIRTypeDisplayName(type: CType, prefix: boolean = true) { 4 | if (!type) { 5 | return null; 6 | } 7 | 8 | const byteSize = type.getByteSize(); 9 | return `${prefix ? ': ' : ''}${type.getShortestDisplayName()}${byteSize ? `${byteSize}B` : ''}`; 10 | } 11 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/dump/index.ts: -------------------------------------------------------------------------------- 1 | export * from './IRResultView'; 2 | export * from './getIRTypeDisplayName'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/IRGlobalVariablesMap.ts: -------------------------------------------------------------------------------- 1 | import { IRVariable } from '../variables'; 2 | 3 | export class IRGlobalVariablesMap { 4 | private readonly globals: Record = {}; 5 | 6 | hasVariable(name: string) { 7 | return name in this.globals; 8 | } 9 | 10 | putVariable(name: string, variable: IRVariable) { 11 | this.globals[name] = variable; 12 | } 13 | 14 | getVariable(name: string) { 15 | return this.globals[name]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/IRGotoLabelsFactory.ts: -------------------------------------------------------------------------------- 1 | export class IRGotoLabelsFactory { 2 | private functionID: number = 0; 3 | 4 | enterFunction() { 5 | this.functionID++; 6 | } 7 | 8 | prefixLabel(label: string) { 9 | return `F${this.functionID}_${label}`; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/IRLabelsFactory.ts: -------------------------------------------------------------------------------- 1 | import { IRLabelInstruction } from '../instructions'; 2 | 3 | export class IRLabelsFactory { 4 | readonly counters = { 5 | labels: 0, 6 | }; 7 | 8 | genTmpLabelName() { 9 | return `L${++this.counters.labels}`; 10 | } 11 | 12 | genTmpLabelInstruction() { 13 | return new IRLabelInstruction(this.genTmpLabelName()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/emitters/emit-expr/index.ts: -------------------------------------------------------------------------------- 1 | export * from './emitExpressionIR'; 2 | export * from './emitLogicBinaryJmpExpressionIR'; 3 | export * from './emitLogicExpressionIR'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/emitters/emit-fn-call-expression/index.ts: -------------------------------------------------------------------------------- 1 | export * from './emitFnCallExpressionIR'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/emitters/emit-fn/index.ts: -------------------------------------------------------------------------------- 1 | export * from './emitBlockItemIR'; 2 | export * from './emitFunctionIR'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/emitters/emit-initializer/index.ts: -------------------------------------------------------------------------------- 1 | export * from './emitVariableInitializerIR'; 2 | export * from './emitVariableLoadInitializerIR'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/emitters/emit-initializer/literal/index.ts: -------------------------------------------------------------------------------- 1 | export * from './emitStringLiteralBlobLocalInitializerIR'; 2 | export * from './emitStringLiteralPtrInitializerIR'; 3 | export * from './shouldEmitStringPtrInitializer'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/emitters/emit-initializer/literal/shouldEmitStringPtrInitializer.ts: -------------------------------------------------------------------------------- 1 | import { CType } from 'frontend/analyze'; 2 | import { getBaseTypeIfArray, getBaseTypeIfPtr } from 'frontend/analyze/types/utils'; 3 | 4 | export function shouldEmitStringPtrInitializer(type: CType) { 5 | return getBaseTypeIfArray(getBaseTypeIfPtr(type)).isPointer(); 6 | } 7 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/emitters/emit-while-stmt/index.ts: -------------------------------------------------------------------------------- 1 | export * from './emitDoWhileStmtIR'; 2 | export * from './emitWhileStmtIR'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/emitters/emitGotoStmtIR.ts: -------------------------------------------------------------------------------- 1 | import { ASTCGotoStatement } from 'frontend/parser'; 2 | import { IRJmpInstruction, IRLabelInstruction } from 'frontend/ir/instructions'; 3 | 4 | import { 5 | createBlankStmtResult, 6 | IREmitterContextAttrs, 7 | IREmitterStmtResult, 8 | } from './types'; 9 | 10 | type GotoStmtIREmitAttrs = IREmitterContextAttrs & { 11 | node: ASTCGotoStatement; 12 | }; 13 | 14 | export function emitGotoStmtIR({ 15 | context, 16 | node, 17 | }: GotoStmtIREmitAttrs): IREmitterStmtResult { 18 | const label = context.factory.goto.prefixLabel(node.name.text); 19 | 20 | return createBlankStmtResult([new IRJmpInstruction(new IRLabelInstruction(label))]); 21 | } 22 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/emitters/emitLabeledStmtIR.ts: -------------------------------------------------------------------------------- 1 | import { ASTCGotoStatement } from 'frontend/parser'; 2 | import { IRLabelInstruction } from 'frontend/ir/instructions'; 3 | 4 | import { 5 | createBlankStmtResult, 6 | IREmitterContextAttrs, 7 | IREmitterStmtResult, 8 | } from './types'; 9 | 10 | type LabeledStmtIREmitAttrs = IREmitterContextAttrs & { 11 | node: ASTCGotoStatement; 12 | }; 13 | 14 | export function emitLabeledStmtIR({ 15 | context, 16 | node, 17 | }: LabeledStmtIREmitAttrs): IREmitterStmtResult { 18 | const label = context.factory.goto.prefixLabel(node.name.text); 19 | 20 | return createBlankStmtResult([new IRLabelInstruction(label)]); 21 | } 22 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/index.ts: -------------------------------------------------------------------------------- 1 | export * from './IRGeneratorGlobalVisitor'; 2 | export * from './IRLabelsFactory'; 3 | export * from './IRVariableAllocator'; 4 | export * from './emitters'; 5 | export * from './segments'; 6 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/segments/IRDataSegmentBuilder.ts: -------------------------------------------------------------------------------- 1 | import { IRInstruction } from '../../instructions'; 2 | import { IRSegmentBuilder } from './IRSegmentBuilder'; 3 | 4 | export type IRDataSegmentBuilderResult = { 5 | instructions: IRInstruction[]; 6 | }; 7 | 8 | /** 9 | * Initialized data block builder 10 | */ 11 | export class IRDataSegmentBuilder extends IRSegmentBuilder { 12 | private instructions: IRInstruction[] = []; 13 | 14 | emit(instruction: IRInstruction): this { 15 | this.instructions.push(instruction); 16 | return this; 17 | } 18 | 19 | flush(): IRDataSegmentBuilderResult { 20 | return { 21 | instructions: this.instructions, 22 | }; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/segments/IRSegmentBuilder.ts: -------------------------------------------------------------------------------- 1 | import { IRInstruction } from '../../instructions'; 2 | 3 | export abstract class IRSegmentBuilder { 4 | /** 5 | * Emits multiple instructions at once 6 | */ 7 | emitBulk(instructions: IRInstruction[]): this { 8 | instructions.forEach(this.emit.bind(this)); 9 | return this; 10 | } 11 | 12 | abstract emit(instruction: IRInstruction): this; 13 | abstract flush(): T; 14 | } 15 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/generator/segments/index.ts: -------------------------------------------------------------------------------- 1 | export * from './IRFlatCodeSegmentBuilder'; 2 | export * from './IRDataSegmentBuilder'; 3 | export * from './IRSegmentBuilder'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/guards/index.ts: -------------------------------------------------------------------------------- 1 | export * from './isIRBranchInstruction'; 2 | export * from './isIRLabeledInstruction'; 3 | export * from './isIROutputInstruction'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/guards/isIRBranchInstruction.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IRInstruction, 3 | isIRCallInstruction, 4 | isIRBrInstruction, 5 | isIRJmpInstruction, 6 | isIRLabelInstruction, 7 | isIRRetInstruction, 8 | } from '../instructions'; 9 | 10 | export function isIRBranchInstruction(instruction: IRInstruction): boolean { 11 | return ( 12 | isIRCallInstruction(instruction) || 13 | isIRJmpInstruction(instruction) || 14 | isIRRetInstruction(instruction) || 15 | isIRBrInstruction(instruction) || 16 | isIRLabelInstruction(instruction) 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/guards/isIRLabeledInstruction.ts: -------------------------------------------------------------------------------- 1 | import { IRInstruction } from '../instructions'; 2 | import { IsLabeledInstruction } from '../interfaces'; 3 | 4 | export function isIRLabeledInstruction( 5 | instruction: IRInstruction, 6 | ): instruction is IsLabeledInstruction { 7 | return 'name' in instruction; 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/guards/isIROutputInstruction.ts: -------------------------------------------------------------------------------- 1 | import { IRInstruction } from '../instructions'; 2 | import { IsOutputInstruction } from '../interfaces'; 3 | 4 | export function isIROutputInstruction( 5 | instruction: IRInstruction, 6 | ): instruction is IsOutputInstruction { 7 | return instruction && 'outputVar' in instruction; 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/index.ts: -------------------------------------------------------------------------------- 1 | export * from './safeBuildIRCode'; 2 | export * from './optimizer'; 3 | export * from './dump/IRResultView'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/instructions/IRCommentInstruction.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | 3 | import { IROpcode } from '../constants'; 4 | import { IRInstruction } from './IRInstruction'; 5 | 6 | export function isIRCommentInstruction( 7 | instruction: IRInstruction, 8 | ): instruction is IRCommentInstruction { 9 | return instruction.opcode === IROpcode.COMMENT; 10 | } 11 | 12 | /** 13 | * Comment instruction 14 | */ 15 | export class IRCommentInstruction extends IRInstruction { 16 | constructor(readonly comment: string) { 17 | super(IROpcode.COMMENT); 18 | } 19 | 20 | override getDisplayName(): string { 21 | return chalk.greenBright(`# ${this.comment}`); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/instructions/IRFnEndDeclInstruction.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | 3 | import { IROpcode } from '../constants'; 4 | import { IRInstruction } from './IRInstruction'; 5 | 6 | export function isIRFnEndDeclInstruction( 7 | instruction: IRInstruction, 8 | ): instruction is IRFnEndDeclInstruction { 9 | return instruction.opcode === IROpcode.FN_DECL_END; 10 | } 11 | 12 | /** 13 | * Instruction that indicates end of declaration (it is not RET) 14 | */ 15 | export class IRFnEndDeclInstruction extends IRInstruction { 16 | constructor() { 17 | super(IROpcode.FN_DECL_END); 18 | } 19 | 20 | override getDisplayName(): string { 21 | return chalk.bold.yellowBright('end-def'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/interfaces/HasLabeledBranches.ts: -------------------------------------------------------------------------------- 1 | import type { IRLabelInstruction } from '../instructions/IRLabelInstruction'; 2 | 3 | export interface HasLabeledBranches { 4 | ofLabels(labels: IRLabelInstruction[]): this; 5 | getLabels(): IRLabelInstruction[]; 6 | } 7 | 8 | export function isWithLabeledBranches( 9 | instruction: any, 10 | ): instruction is HasLabeledBranches { 11 | return instruction && 'ofLabels' in instruction; 12 | } 13 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/interfaces/IsLabeledInstruction.ts: -------------------------------------------------------------------------------- 1 | import type { IRInstruction } from '../instructions/IRInstruction'; 2 | 3 | export type IsLabeledInstruction = IRInstruction & { 4 | name: string; 5 | }; 6 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/interfaces/IsOutputInstruction.ts: -------------------------------------------------------------------------------- 1 | import type { IRInstruction } from '../instructions/IRInstruction'; 2 | import type { IRVariable } from '../variables'; 3 | 4 | export type IsOutputInstruction = IRInstruction & { 5 | outputVar?: IRVariable; 6 | }; 7 | 8 | export function isOutputInstruction( 9 | instruction: IRInstruction, 10 | ): instruction is IsOutputInstruction { 11 | return 'outputVar' in instruction; 12 | } 13 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './HasLabeledBranches'; 2 | export * from './IsLabeledInstruction'; 3 | export * from './IsOutputInstruction'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/iterator/index.ts: -------------------------------------------------------------------------------- 1 | export * from './IRBlockIterator'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/optimizer/block/index.ts: -------------------------------------------------------------------------------- 1 | export * from './optimizeInstructionsBlock'; 2 | export * from './optimizeInstructionsList'; 3 | export * from './phases'; 4 | export * from './utils'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/optimizer/block/optimizeInstructionsBlock.ts: -------------------------------------------------------------------------------- 1 | import { IRInstructionsBlock } from '../../instructions'; 2 | import { optimizeInstructionsList } from './optimizeInstructionsList'; 3 | 4 | export function optimizeInstructionsBlock( 5 | block: IRInstructionsBlock, 6 | ): IRInstructionsBlock { 7 | return block.mapInstructions(optimizeInstructionsList); 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/optimizer/block/phases/index.ts: -------------------------------------------------------------------------------- 1 | export * from './concatConstantStoreInstructions'; 2 | export * from './dropConstantBranchInstructions'; 3 | export * from './dropConstantLabelOffsetsArgs'; 4 | export * from './dropDeadStoreInstructions'; 5 | export * from './dropInstructionsWithOrphanOutputs'; 6 | export * from './dropOrConcatConstantInstructions'; 7 | export * from './dropRedundantAddressInstructions'; 8 | export * from './dropRedundantLabelInstructions'; 9 | export * from './dropRedundantLoadInstructions'; 10 | export * from './dropUselessBranchJmps'; 11 | export * from './flipMathInstructionsOperands'; 12 | export * from './foldAddressOffsetsInstructions'; 13 | export * from './reassignPhiInstructions'; 14 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/optimizer/block/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dropConstantInstructionArgs'; 2 | export * from './tryConcatMathInstructions'; 3 | export * from './tryEvalConstArgsBinaryInstruction'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/optimizer/constants/types.ts: -------------------------------------------------------------------------------- 1 | export type IROptimizerConfig = { 2 | enabled?: boolean; 3 | }; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/optimizer/index.ts: -------------------------------------------------------------------------------- 1 | export * from './optimizeIRResult'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/optimizer/optimizeIRResult.ts: -------------------------------------------------------------------------------- 1 | import { IRScopeGeneratorResult } from '../generator/emitters'; 2 | import { IROptimizerConfig } from './constants/types'; 3 | import { optimizeCodeSegment } from './segment/optimizeCodeSegment'; 4 | 5 | export function optimizeIRResult( 6 | { enabled }: IROptimizerConfig, 7 | ir: IRScopeGeneratorResult, 8 | ): IRScopeGeneratorResult { 9 | if (!enabled) { 10 | return ir; 11 | } 12 | 13 | const { segments } = ir; 14 | return { 15 | ...ir, 16 | segments: { 17 | ...ir.segments, 18 | code: optimizeCodeSegment(segments.code), 19 | }, 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/optimizer/segment/optimizeCodeSegment.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | import { IRFlatCodeSegmentBuilderResult } from '../../generator'; 4 | import { optimizeInstructionsBlock } from '../block'; 5 | 6 | export function optimizeCodeSegment( 7 | segment: IRFlatCodeSegmentBuilderResult, 8 | ): IRFlatCodeSegmentBuilderResult { 9 | return { 10 | ...segment, 11 | functions: R.mapObjIndexed( 12 | fn => ({ 13 | ...fn, 14 | block: optimizeInstructionsBlock(fn.block), 15 | }), 16 | segment.functions, 17 | ), 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/utils/getBiggerIRArg.ts: -------------------------------------------------------------------------------- 1 | import { IRInstructionTypedArg } from '../variables'; 2 | 3 | export const getBiggerIRArg = (a: T, b: T): T => 4 | a.type.getByteSize() > b.type.getByteSize() ? a : b; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/utils/getSmallerIRArg.ts: -------------------------------------------------------------------------------- 1 | import { IRInstructionTypedArg } from '../variables'; 2 | 3 | export const getSmallerIRArg = (a: T, b: T): T => 4 | a.type.getByteSize() < b.type.getByteSize() ? a : b; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/utils/getTypeOffsetByteSize.ts: -------------------------------------------------------------------------------- 1 | import { CType } from 'frontend/analyze'; 2 | import { getTypeAtOffset } from './getTypeAtOffset'; 3 | 4 | export const getTypeOffsetByteSize = (type: CType, offset: number) => { 5 | return getTypeAtOffset(type, offset).getByteSize(); 6 | }; 7 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './checkIfVirtualGlobalArrayPtr'; 2 | export * from './checkIfVirtualLocalArrayPtr'; 3 | export * from './getBiggerIRArg'; 4 | export * from './getSmallerIRArg'; 5 | export * from './getTypeAtOffset'; 6 | export * from './getTypeOffsetByteSize'; 7 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/variables/IRInstructionArg.ts: -------------------------------------------------------------------------------- 1 | import { IRInstructionTypedArg } from './IRInstructionTypedArg'; 2 | import { IRLabel } from './IRLabel'; 3 | 4 | export type IRInstructionArg = IRInstructionTypedArg | IRLabel; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/variables/IRInstructionTypedArg.ts: -------------------------------------------------------------------------------- 1 | import { IRConstant } from './IRConstant'; 2 | import { IRVariable } from './IRVariable'; 3 | 4 | export type IRInstructionTypedArg = IRVariable | IRConstant; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/variables/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './prefixes'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/variables/constants/prefixes.ts: -------------------------------------------------------------------------------- 1 | export const COMPILER_GEN_PREFIX = '%'; 2 | export const TMP_VAR_PREFIX = `${COMPILER_GEN_PREFIX}t`; 3 | export const TMP_FN_RETURN_VAR_PREFIX = `${COMPILER_GEN_PREFIX}out`; 4 | export const CONST_VAR_PREFIX = 'c'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/ir/variables/index.ts: -------------------------------------------------------------------------------- 1 | export * from './IRConstant'; 2 | export * from './IRInstructionArg'; 3 | export * from './IRInstructionTypedArg'; 4 | export * from './IRLabel'; 5 | export * from './IRVariable'; 6 | export * from './constants'; 7 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCAlignmentSpecifier.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 5 | import { ASTCConstantExpression } from './ASTCConstantExpression'; 6 | import { ASTCTypeName } from './ASTCTypeName'; 7 | 8 | @walkOverFields({ 9 | fields: ['specifiers', 'expression'], 10 | }) 11 | export class ASTCAlignmentSpecifier extends ASTCCompilerNode { 12 | constructor( 13 | loc: NodeLocation, 14 | readonly typename: ASTCTypeName, 15 | readonly expression?: ASTCConstantExpression, 16 | ) { 17 | super(ASTCCompilerKind.AlignmentSpecifier, loc); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCArgumentsExpressionList.ts: -------------------------------------------------------------------------------- 1 | import { NodeLocation } from '@ts-cc/grammar'; 2 | import { ASTCCompilerNode, ASTCCompilerKind } from './ASTCCompilerNode'; 3 | import { ASTCExpression } from './ASTCExpression'; 4 | 5 | export class ASTCArgumentsExpressionList extends ASTCExpression { 6 | constructor(loc: NodeLocation, assignments: ASTCCompilerNode[]) { 7 | super(loc, assignments, ASTCCompilerKind.ArgumentsExpressionList); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCBlockItemsList.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | import { IsEmpty } from '@ts-cc/core'; 4 | import { NodeLocation } from '@ts-cc/grammar'; 5 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 6 | import { IsNewScopeASTNode } from '../../analyze/interfaces'; 7 | import { CScopeTree } from '../../analyze'; 8 | 9 | export class ASTCBlockItemsList 10 | extends ASTCCompilerNode 11 | implements IsEmpty, IsNewScopeASTNode 12 | { 13 | scope?: CScopeTree; 14 | 15 | constructor(loc: NodeLocation, items: ASTCCompilerNode[]) { 16 | super(ASTCCompilerKind.BlockItemList, loc, items); 17 | } 18 | 19 | isEmpty() { 20 | return R.isEmpty(this.children); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCBreakStatement.ts: -------------------------------------------------------------------------------- 1 | import { NodeLocation } from '@ts-cc/grammar'; 2 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 3 | 4 | export class ASTCBreakStatement extends ASTCCompilerNode { 5 | constructor(loc: NodeLocation) { 6 | super(ASTCCompilerKind.BreakStmt, loc); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCCastExpression.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCTypeName } from './ASTCTypeName'; 5 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 6 | 7 | @walkOverFields({ 8 | fields: ['typeName', 'expression'], 9 | }) 10 | export class ASTCCastExpression extends ASTCCompilerNode { 11 | constructor( 12 | loc: NodeLocation, 13 | readonly typeName?: ASTCTypeName, 14 | readonly expression?: ASTCCompilerNode, 15 | ) { 16 | super(ASTCCompilerKind.CastExpression, loc); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCConditionalExpression.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 5 | 6 | @walkOverFields({ 7 | fields: ['logicalExpression', 'trueExpression', 'falseExpression'], 8 | }) 9 | export class ASTCConditionalExpression extends ASTCCompilerNode { 10 | constructor( 11 | loc: NodeLocation, 12 | readonly logicalExpression: ASTCCompilerNode, 13 | readonly trueExpression?: ASTCCompilerNode, 14 | readonly falseExpression?: ASTCCompilerNode, 15 | ) { 16 | super(ASTCCompilerKind.ConditionalExpression, loc); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCConstantExpression.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 5 | 6 | /** 7 | * Expressions that can be evaluated during compile time 8 | */ 9 | @walkOverFields({ 10 | fields: ['expression'], 11 | }) 12 | export class ASTCConstantExpression extends ASTCCompilerNode { 13 | constructor( 14 | loc: NodeLocation, 15 | readonly expression: ASTCCompilerNode, 16 | ) { 17 | super(ASTCCompilerKind.ConstantExpression, loc); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCContinueStatement.ts: -------------------------------------------------------------------------------- 1 | import { NodeLocation } from '@ts-cc/grammar'; 2 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 3 | 4 | export class ASTCContinueStatement extends ASTCCompilerNode { 5 | constructor(loc: NodeLocation) { 6 | super(ASTCCompilerKind.ContinueStmt, loc); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCDeclaration.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCDeclarationSpecifier } from './ASTCDeclarationSpecifier'; 5 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 6 | import { ASTCInitDeclaratorList } from './ASTCInitDeclaratorList'; 7 | 8 | @walkOverFields({ 9 | fields: ['specifier', 'initList'], 10 | }) 11 | export class ASTCDeclaration extends ASTCCompilerNode { 12 | constructor( 13 | loc: NodeLocation, 14 | readonly specifier: ASTCDeclarationSpecifier, 15 | readonly initList: ASTCInitDeclaratorList, 16 | ) { 17 | super(ASTCCompilerKind.Declaration, loc); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCDeclarationsList.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { IsEmpty } from '@ts-cc/core'; 5 | 6 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 7 | import { ASTCDeclaration } from './ASTCDeclaration'; 8 | 9 | export class ASTCDeclarationsList 10 | extends ASTCCompilerNode 11 | implements IsEmpty 12 | { 13 | constructor(loc: NodeLocation, items: ASTCDeclaration[]) { 14 | super(ASTCCompilerKind.DeclarationsList, loc, items); 15 | } 16 | 17 | isEmpty() { 18 | return R.isEmpty(this.children); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCDesignatorList.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { IsEmpty } from '@ts-cc/core'; 5 | 6 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 7 | import { ASTCDesignator } from './ASTCDesignator'; 8 | 9 | export class ASTCDesignatorList 10 | extends ASTCCompilerNode 11 | implements IsEmpty 12 | { 13 | constructor(loc: NodeLocation, items: ASTCDesignator[]) { 14 | super(ASTCCompilerKind.DesignatorList, loc, items); 15 | } 16 | 17 | isEmpty() { 18 | return R.isEmpty(this.children); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCExpression.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | import { NodeLocation } from '@ts-cc/grammar'; 3 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 4 | 5 | export function isASTCExpressionNode(node: ASTCCompilerNode): node is ASTCExpression { 6 | return node.kind === ASTCCompilerKind.Expression; 7 | } 8 | 9 | @walkOverFields({ 10 | fields: ['assignments'], 11 | }) 12 | export class ASTCExpression extends ASTCCompilerNode { 13 | constructor( 14 | loc: NodeLocation, 15 | readonly assignments: ASTCCompilerNode[], 16 | kind: ASTCCompilerKind = ASTCCompilerKind.Expression, 17 | ) { 18 | super(kind, loc); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCExpressionStatement.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 5 | 6 | export function isASTCExpressionStmtNode( 7 | node: ASTCCompilerNode, 8 | ): node is ASTCExpressionStatement { 9 | return node.kind === ASTCCompilerKind.ExpressionStmt; 10 | } 11 | 12 | @walkOverFields({ 13 | fields: ['expression'], 14 | }) 15 | export class ASTCExpressionStatement extends ASTCCompilerNode { 16 | constructor( 17 | loc: NodeLocation, 18 | readonly expression?: ASTCCompilerNode, 19 | ) { 20 | super(ASTCCompilerKind.ExpressionStmt, loc); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCGotoStatement.ts: -------------------------------------------------------------------------------- 1 | import { dumpAttributesToString } from '@ts-cc/core'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { Token } from '@ts-cc/lexer'; 5 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 6 | 7 | export class ASTCGotoStatement extends ASTCCompilerNode { 8 | constructor( 9 | loc: NodeLocation, 10 | readonly name: Token, 11 | ) { 12 | super(ASTCCompilerKind.GotoStmt, loc); 13 | } 14 | 15 | toString() { 16 | const { kind, name } = this; 17 | 18 | return dumpAttributesToString(kind, { 19 | name: name.text, 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCIfStatement.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 5 | 6 | @walkOverFields({ 7 | fields: ['logicalExpression', 'trueExpression', 'falseExpression'], 8 | }) 9 | export class ASTCIfStatement extends ASTCCompilerNode { 10 | constructor( 11 | loc: NodeLocation, 12 | readonly logicalExpression: ASTCCompilerNode, 13 | readonly trueExpression: ASTCCompilerNode, 14 | readonly falseExpression?: ASTCCompilerNode, 15 | ) { 16 | super(ASTCCompilerKind.IfStmt, loc); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCInitDeclarator.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 5 | import { ASTCDeclarator } from './ASTCDeclarator'; 6 | import { ASTCInitializer } from './ASTCInitializer'; 7 | 8 | @walkOverFields({ 9 | fields: ['declarator', 'initializer'], 10 | }) 11 | export class ASTCInitDeclarator extends ASTCCompilerNode { 12 | constructor( 13 | loc: NodeLocation, 14 | readonly declarator: ASTCDeclarator, 15 | readonly initializer: ASTCInitializer, 16 | ) { 17 | super(ASTCCompilerKind.InitDeclarator, loc); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCInitDeclaratorList.ts: -------------------------------------------------------------------------------- 1 | import { NodeLocation } from '@ts-cc/grammar'; 2 | import { ASTCInitDeclarator } from './ASTCInitDeclarator'; 3 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 4 | 5 | export class ASTCInitDeclaratorList extends ASTCCompilerNode { 6 | constructor(loc: NodeLocation, items: ASTCInitDeclarator[]) { 7 | super(ASTCCompilerKind.InitDeclaratorList, loc, items); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCLabelStatement.ts: -------------------------------------------------------------------------------- 1 | import { dumpAttributesToString } from '@ts-cc/core'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { Token } from '@ts-cc/lexer'; 5 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 6 | 7 | export class ASTCLabelStatement extends ASTCCompilerNode { 8 | constructor( 9 | loc: NodeLocation, 10 | readonly name: Token, 11 | ) { 12 | super(ASTCCompilerKind.LabelStmt, loc); 13 | } 14 | 15 | toString() { 16 | const { kind, name } = this; 17 | 18 | return dumpAttributesToString(kind, { 19 | name: name.text, 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCParametersList.ts: -------------------------------------------------------------------------------- 1 | import { NodeLocation } from '@ts-cc/grammar'; 2 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 3 | import { ASTCParameterDeclaration } from './ASTCParameterDeclaration'; 4 | 5 | export class ASTCParametersList extends ASTCCompilerNode { 6 | constructor(loc: NodeLocation, items: ASTCParameterDeclaration[]) { 7 | super(ASTCCompilerKind.ParametersList, loc, items); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCPointer.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 5 | import { ASTCTypeQualifiersList } from './ASTCTypeQualifiersList'; 6 | 7 | /** 8 | * @see 9 | * ASTCAbstractDeclarator 10 | */ 11 | @walkOverFields({ 12 | fields: ['typeQualifierList', 'pointer'], 13 | }) 14 | export class ASTCPointer extends ASTCCompilerNode { 15 | constructor( 16 | loc: NodeLocation, 17 | readonly typeQualifierList?: ASTCTypeQualifiersList, 18 | readonly pointer?: ASTCPointer, 19 | ) { 20 | super(ASTCCompilerKind.Pointer, loc); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCReturnStatement.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 5 | 6 | @walkOverFields({ 7 | fields: ['expression'], 8 | }) 9 | export class ASTCReturnStatement extends ASTCCompilerNode { 10 | constructor( 11 | loc: NodeLocation, 12 | readonly expression?: ASTCCompilerNode, 13 | ) { 14 | super(ASTCCompilerKind.ReturnStmt, loc); 15 | } 16 | 17 | hasExpression() { 18 | return !!this.expression; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCStmt.ts: -------------------------------------------------------------------------------- 1 | import { NodeLocation } from '@ts-cc/grammar'; 2 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 3 | 4 | export class ASTCStmt extends ASTCCompilerNode { 5 | constructor(loc: NodeLocation, children: ASTCCompilerNode[]) { 6 | super(ASTCCompilerKind.Stmt, loc, children); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCStructDeclarationList.ts: -------------------------------------------------------------------------------- 1 | import { NodeLocation } from '@ts-cc/grammar'; 2 | import { ASTCStructDeclaration } from './ASTCStructDeclaration'; 3 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 4 | 5 | export class ASTCStructDeclarationList extends ASTCCompilerNode { 6 | constructor(loc: NodeLocation, items: ASTCStructDeclaration[]) { 7 | super(ASTCCompilerKind.StructDeclarationList, loc, items); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCStructDeclarator.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 5 | import { ASTCDeclarator } from './ASTCDeclarator'; 6 | import { ASTCConstantExpression } from './ASTCConstantExpression'; 7 | 8 | @walkOverFields({ 9 | fields: ['declarator', 'expression'], 10 | }) 11 | export class ASTCStructDeclarator extends ASTCCompilerNode { 12 | constructor( 13 | loc: NodeLocation, 14 | readonly declarator: ASTCDeclarator, 15 | readonly expression?: ASTCConstantExpression, 16 | ) { 17 | super(ASTCCompilerKind.StructDeclarator, loc); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCStructDeclaratorList.ts: -------------------------------------------------------------------------------- 1 | import { NodeLocation } from '@ts-cc/grammar'; 2 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 3 | import { ASTCStructDeclarator } from './ASTCStructDeclarator'; 4 | 5 | export class ASTCStructDeclaratorList extends ASTCCompilerNode { 6 | constructor(loc: NodeLocation, items: ASTCStructDeclarator[]) { 7 | super(ASTCCompilerKind.StructDeclaratorList, loc, items); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCSwitchStatement.ts: -------------------------------------------------------------------------------- 1 | import { walkOverFields } from '@ts-cc/grammar'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 5 | 6 | @walkOverFields({ 7 | fields: ['expression', 'statement'], 8 | }) 9 | export class ASTCSwitchStatement extends ASTCCompilerNode { 10 | constructor( 11 | loc: NodeLocation, 12 | readonly expression: ASTCCompilerNode, 13 | public statement: ASTCCompilerNode, 14 | ) { 15 | super(ASTCCompilerKind.SwitchStmt, loc); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCTranslationUnit.ts: -------------------------------------------------------------------------------- 1 | import { NodeLocation } from '@ts-cc/grammar'; 2 | import { ASTCCompilerKind, ASTCCompilerNode } from './ASTCCompilerNode'; 3 | 4 | export class ASTCTranslationUnit extends ASTCCompilerNode { 5 | constructor(loc: NodeLocation, children: ASTCCompilerNode[]) { 6 | super(ASTCCompilerKind.TranslationUnit, loc, children); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCUnionSpecifier.ts: -------------------------------------------------------------------------------- 1 | import { Token } from '@ts-cc/lexer'; 2 | import { NodeLocation } from '@ts-cc/grammar'; 3 | import { ASTCCompilerKind } from './ASTCCompilerNode'; 4 | import { ASTCStructSpecifier } from './ASTCStructSpecifier'; 5 | import { ASTCStructDeclarationList } from './ASTCStructDeclarationList'; 6 | 7 | export class ASTCUnionSpecifier extends ASTCStructSpecifier { 8 | constructor(loc: NodeLocation, items: ASTCStructDeclarationList, name?: Token) { 9 | super(loc, items, name, ASTCCompilerKind.UnionSpecifier); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/ASTCValueNode.ts: -------------------------------------------------------------------------------- 1 | import { ValueNode } from '@ts-cc/grammar'; 2 | import { Token } from '@ts-cc/lexer'; 3 | import { ASTCCompilerKind } from './ASTCCompilerNode'; 4 | 5 | /** 6 | * Holds constant numeric values 7 | */ 8 | export class ASTCValueNode extends ValueNode< 9 | T, 10 | ASTCCompilerKind 11 | > {} 12 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/asm/ASTCAsmClobberOperand.ts: -------------------------------------------------------------------------------- 1 | import { dumpAttributesToString } from '@ts-cc/core'; 2 | 3 | import { NodeLocation } from '@ts-cc/grammar'; 4 | import { ASTCCompilerKind, ASTCCompilerNode } from '../ASTCCompilerNode'; 5 | 6 | export class ASTCAsmClobberOperand extends ASTCCompilerNode { 7 | constructor( 8 | loc: NodeLocation, 9 | readonly name: string, 10 | ) { 11 | super(ASTCCompilerKind.AsmStmtClobberOperand, loc); 12 | } 13 | 14 | toString() { 15 | const { kind, name } = this; 16 | 17 | return dumpAttributesToString(kind, { 18 | name, 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/ast/asm/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ASTCAsmClobberOperand'; 2 | export * from './ASTCAsmStatement'; 3 | export * from './ASTCAsmStmtInputConstraint'; 4 | export * from './ASTCAsmStmtInputOperand'; 5 | export * from './ASTCAsmStmtOutputConstraint'; 6 | export * from './ASTCAsmStmtOutputOperand'; 7 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/dump/index.ts: -------------------------------------------------------------------------------- 1 | export * from './serializeTypedTreeToString'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/dump/serializeTypedTreeToString.ts: -------------------------------------------------------------------------------- 1 | import { dumpAttributesToString } from '@ts-cc/core'; 2 | import { TreePrintVisitor } from '@ts-cc/grammar'; 3 | 4 | import { ASTCCompilerNode } from '../ast'; 5 | import { isNewScopeASTNode } from '../../analyze/interfaces'; 6 | 7 | export function serializeTypedTreeToString(ast: ASTCCompilerNode): string { 8 | return TreePrintVisitor.serializeToString(ast, { 9 | formatterFn: node => 10 | dumpAttributesToString(node.toString(), { 11 | type: node.type?.toString(), 12 | scoped: isNewScopeASTNode(node) || null, 13 | }), 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/index.ts: -------------------------------------------------------------------------------- 1 | export * from './generateTree'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/declarations/externalDeclaration.ts: -------------------------------------------------------------------------------- 1 | import { ASTCTreeNode } from '../../../ast'; 2 | import { CGrammar } from '../shared'; 3 | 4 | import { functionDefinition } from '../definitions/functionDefinition'; 5 | import { declaration } from './declaration'; 6 | 7 | /** 8 | * external_declaration 9 | * : function_definition 10 | * | declaration 11 | * ; 12 | */ 13 | export function externalDeclaration(grammar: CGrammar): ASTCTreeNode { 14 | const { g } = grammar; 15 | 16 | return g.or({ 17 | functionDefinition: () => functionDefinition(grammar), 18 | declaration: () => declaration(grammar), 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/declarations/index.ts: -------------------------------------------------------------------------------- 1 | export * from './abstractDeclarator'; 2 | export * from './declaration'; 3 | export * from './declarationList'; 4 | export * from './declarator'; 5 | export * from './designation'; 6 | export * from './directAbstractDeclarator'; 7 | export * from './directDeclarator'; 8 | export * from './enumDeclator'; 9 | export * from './externalDeclaration'; 10 | export * from './initDeclarator'; 11 | export * from './initializer'; 12 | export * from './parameterDeclaration'; 13 | export * from './pointer'; 14 | export * from './staticAssertDeclaration'; 15 | export * from './structDeclaration'; 16 | export * from './structDeclarationList'; 17 | export * from './structDeclarator'; 18 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/definitions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './functionDefinition'; 2 | export * from './translationUnit'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/expressions/constantExpression.ts: -------------------------------------------------------------------------------- 1 | import { ASTCConstantExpression } from '../../../ast'; 2 | import { CGrammar } from '../shared'; 3 | 4 | import { conditionalExpression } from './conditionalExpression'; 5 | 6 | /** 7 | * Fetch constant expression 8 | */ 9 | export function constantExpression(grammar: CGrammar): ASTCConstantExpression { 10 | const expr = conditionalExpression(grammar); 11 | 12 | return new ASTCConstantExpression(expr.loc, expr); 13 | } 14 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/expressions/expression.ts: -------------------------------------------------------------------------------- 1 | import { ASTCExpression, ASTCCompilerNode } from '../../../ast'; 2 | import { CGrammar } from '../shared'; 3 | import { fetchSplittedProductionsList } from '../utils'; 4 | 5 | /** 6 | * Fetch expression 7 | */ 8 | export function expression(grammar: CGrammar): ASTCExpression { 9 | const { g, assignmentExpression } = grammar; 10 | const assignments = fetchSplittedProductionsList({ 11 | g, 12 | prodFn: assignmentExpression, 13 | }); 14 | 15 | return new ASTCExpression(assignments[0].loc, assignments); 16 | } 17 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/expressions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './assignmentExpression'; 2 | export * from './castExpression'; 3 | export * from './constantExpression'; 4 | export * from './conditionalExpression'; 5 | export * from './logicalExpression'; 6 | export * from './bitwiseExpression'; 7 | export * from './equalityExpression'; 8 | export * from './relationalExpression'; 9 | export * from './shiftExpression'; 10 | export * from './additiveExpression'; 11 | export * from './multiplicativeExpression'; 12 | export * from './expression'; 13 | export * from './postfixExpression'; 14 | export * from './unaryExpression'; 15 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './statements'; 2 | export * from './expressions'; 3 | export * from './declarations'; 4 | export * from './definitions'; 5 | export * from './specifiers'; 6 | export * from './shared'; 7 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/parameters/index.ts: -------------------------------------------------------------------------------- 1 | export * from './parameterTypeList'; 2 | export * from './parameterList'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/specifiers/functionSpecifier.ts: -------------------------------------------------------------------------------- 1 | import { CCOMPILER_FUNCTION_SPECIFIERS, CFunctionSpecifier } from '#constants'; 2 | 3 | import { CGrammar } from '../shared'; 4 | 5 | /** 6 | * function_specifier 7 | * : INLINE 8 | * | NORETURN 9 | * ; 10 | */ 11 | export function matchFunctionSpecifier({ g }: CGrammar): CFunctionSpecifier { 12 | const specifier = g.identifier(CCOMPILER_FUNCTION_SPECIFIERS); 13 | 14 | return specifier.text as CFunctionSpecifier; 15 | } 16 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/specifiers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './alignmentSpecifier'; 2 | export * from './declarationSpecifiers'; 3 | export * from './functionSpecifier'; 4 | export * from './qualifiersSpecifiers'; 5 | export * from './storageClassSpecifier'; 6 | export * from './structSpecifier'; 7 | export * from './typeQualifier'; 8 | export * from './typeQualifiers'; 9 | export * from './typeSpecifier'; 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/specifiers/storageClassSpecifier.ts: -------------------------------------------------------------------------------- 1 | import { CCOMPILER_STORAGE_CLASS_SPECIFIERS, CStorageClassSpecifier } from '#constants'; 2 | 3 | import { CGrammar } from '../shared'; 4 | 5 | export function matchStorageClassSpecifier({ g }: CGrammar): CStorageClassSpecifier { 6 | const specifier = g.identifier(CCOMPILER_STORAGE_CLASS_SPECIFIERS); 7 | 8 | return specifier.text as CStorageClassSpecifier; 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/specifiers/typeQualifier.ts: -------------------------------------------------------------------------------- 1 | import { CCOMPILER_TYPE_QUALIFIERS, CTypeQualifier } from '#constants'; 2 | 3 | import { CGrammar } from '../shared'; 4 | 5 | export function matchTypeQualifier({ g }: CGrammar): CTypeQualifier { 6 | const qualifier = g.identifier(CCOMPILER_TYPE_QUALIFIERS); 7 | 8 | return qualifier.text as CTypeQualifier; 9 | } 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/statements/asm/asmClobberOperand.ts: -------------------------------------------------------------------------------- 1 | import { NodeLocation } from '@ts-cc/grammar'; 2 | import { TokenKind, TokenType } from '@ts-cc/lexer'; 3 | import { ASTCAsmClobberOperand } from 'frontend/parser/ast'; 4 | 5 | import { CGrammar } from '../../shared'; 6 | 7 | export function asmClobberOperand(grammar: CGrammar): ASTCAsmClobberOperand { 8 | const { g } = grammar; 9 | 10 | const literalToken = g.match({ 11 | type: TokenType.QUOTE, 12 | kind: TokenKind.DOUBLE_QUOTE, 13 | }); 14 | 15 | return new ASTCAsmClobberOperand( 16 | NodeLocation.fromTokenLoc(literalToken.loc), 17 | literalToken.text, 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/statements/asm/asmSymbolicName.ts: -------------------------------------------------------------------------------- 1 | import { CGrammar } from '../../shared'; 2 | 3 | /** 4 | * [asmSymbolicName] 5 | */ 6 | export function asmSymbolicName(grammar: CGrammar): string { 7 | const { g } = grammar; 8 | 9 | g.terminal('['); 10 | 11 | const symbolicName = g.match(); 12 | 13 | g.terminal(']'); 14 | 15 | return symbolicName.text; 16 | } 17 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/statements/asm/index.ts: -------------------------------------------------------------------------------- 1 | export * from './asmStatement'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/statements/index.ts: -------------------------------------------------------------------------------- 1 | export * from './asm'; 2 | export * from './compoundExpressionStatement'; 3 | export * from './compoundStatement'; 4 | export * from './expressionStatement'; 5 | export * from './iterationStatement'; 6 | export * from './jumpStatement'; 7 | export * from './labeledStatement'; 8 | export * from './selectionStatement'; 9 | export * from './statement'; 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './typename'; 2 | export * from './stringLiteral'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/types/typename.ts: -------------------------------------------------------------------------------- 1 | import { ASTCTypeName } from 'frontend/parser/ast'; 2 | import { CGrammar } from '../shared'; 3 | 4 | /** 5 | * type_name 6 | * : specifier_qualifier_list abstract_declarator 7 | * | specifier_qualifier_list 8 | * ; 9 | */ 10 | export function typename(grammar: CGrammar): ASTCTypeName { 11 | const { g, abstractDeclarator, qualifiersSpecifiers } = grammar; 12 | 13 | const specifierList = qualifiersSpecifiers(); 14 | const declaratorNode = g.try(abstractDeclarator); 15 | 16 | return new ASTCTypeName(specifierList.loc, specifierList, declaratorNode); 17 | } 18 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/utils/CReducePostfixOperatorVisitor.ts: -------------------------------------------------------------------------------- 1 | import { ReducePostfixOperatorsVisitor } from '@ts-cc/grammar'; 2 | import { ASTCCompilerKind } from '../../../ast/ASTCCompilerNode'; 3 | 4 | export class CReducePostfixOperatorsVisitor extends ReducePostfixOperatorsVisitor { 5 | constructor() { 6 | super(ASTCCompilerKind.BinaryOperator); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/grammar/matchers/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CReducePostfixOperatorVisitor'; 2 | export * from './createLeftRecursiveOperatorMatcher'; 3 | export * from './fetchSplittedProductionsList'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lexer/clexer'; 2 | export * from './grammar'; 3 | export * from './ast'; 4 | export * from './dump'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/parser/lexer/parsers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './cCommentParser'; 2 | export * from './cMergeNumbersTokens'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/ast/ASTCIncludeNode.ts: -------------------------------------------------------------------------------- 1 | import { NodeLocation } from '@ts-cc/grammar'; 2 | 3 | import { CInterpreterContext, CInterpreterSourcePath } from '../interpreter'; 4 | 5 | import { 6 | ASTCPreprocessorKind, 7 | ASTCPreprocessorTreeNode, 8 | } from './ASTCPreprocessorTreeNode'; 9 | 10 | export class ASTCIncludeNode extends ASTCPreprocessorTreeNode { 11 | constructor( 12 | loc: NodeLocation, 13 | readonly path: CInterpreterSourcePath, 14 | ) { 15 | super(ASTCPreprocessorKind.Include, loc); 16 | } 17 | 18 | override exec(ctx: CInterpreterContext): void { 19 | ctx.includeFile(this.path); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/ast/ASTCStmtNode.ts: -------------------------------------------------------------------------------- 1 | import { NodeLocation } from '@ts-cc/grammar'; 2 | 3 | import { CInterpreterContext } from '../interpreter'; 4 | import { 5 | ASTCPreprocessorKind, 6 | ASTCPreprocessorTreeNode, 7 | } from './ASTCPreprocessorTreeNode'; 8 | 9 | export class ASTCStmtNode extends ASTCPreprocessorTreeNode { 10 | constructor(loc: NodeLocation, children: ASTCPreprocessorTreeNode[]) { 11 | super(ASTCPreprocessorKind.Stmt, loc, children); 12 | } 13 | 14 | override exec(ctx: CInterpreterContext): void { 15 | for (const child of this.children) { 16 | child.exec(ctx); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/ast/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ASTCBinaryOpNode'; 2 | export * from './ASTCCodeBlockNode'; 3 | export * from './ASTCDefineNode'; 4 | export * from './ASTCElifDefNode'; 5 | export * from './ASTCElifNode'; 6 | export * from './ASTCElifNotDefNode'; 7 | export * from './ASTCExpressionNode'; 8 | export * from './ASTCIfDefNode'; 9 | export * from './ASTCIfNode'; 10 | export * from './ASTCIfNotDefNode'; 11 | export * from './ASTCIncludeNode'; 12 | export * from './ASTCPreprocessorTreeNode'; 13 | export * from './ASTCStmtNode'; 14 | export * from './ASTCValueNode'; 15 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/grammar/CPreprocessorIdentifiers.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | import { $enum } from 'ts-enum-util'; 3 | 4 | import type { IdentifiersMap } from '@ts-cc/lexer'; 5 | 6 | export enum CPreprocessorIdentifier { 7 | DEFINE = '#define', 8 | IF_DEF = '#ifdef', 9 | IF_NOT_DEF = '#ifndef', 10 | IF = '#if', 11 | ELSE = '#else', 12 | ELIF = '#elif', 13 | ELIF_DEF = '#elifdef', 14 | ELIF_NOT_DEF = '#elifndef', 15 | ENDIF = '#endif', 16 | INCLUDE = '#include', 17 | } 18 | 19 | export const C_PREPROCESSOR_IDENTIFIERS_MAP: IdentifiersMap = R.fromPairs( 20 | $enum(CPreprocessorIdentifier) 21 | .getValues() 22 | .map(value => [value, value]), 23 | ); 24 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/grammar/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CPreprocessorError'; 2 | export * from './CPreprocessorGrammar'; 3 | export * from './CPreprocessorIdentifiers'; 4 | export * from './matchers'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/grammar/matchers/expressions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './logicExpression'; 2 | export * from './mathExpression'; 3 | export * from './relationExpression'; 4 | export * from './utils'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/grammar/matchers/expressions/utils/PreprocessorReducePostifxOperatorsVisitor.ts: -------------------------------------------------------------------------------- 1 | import { ReducePostfixOperatorsVisitor } from '@ts-cc/grammar'; 2 | import { ASTCPreprocessorKind } from 'frontend/preprocessor/ast'; 3 | 4 | export class PreprocessorReducePostfixOperatorsVisitor extends ReducePostfixOperatorsVisitor { 5 | constructor() { 6 | super(ASTCPreprocessorKind.BinaryOperator); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/grammar/matchers/expressions/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './createLeftRecursiveOperatorMatcher'; 2 | export * from './PreprocessorReducePostifxOperatorsVisitor'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/grammar/matchers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './codeBlockMatcher'; 2 | export * from './defineMatcher'; 3 | export * from './elifDefMatcher'; 4 | export * from './elifMatcher'; 5 | export * from './elifNotDefMatcher'; 6 | export * from './expressions'; 7 | export * from './ifDefMatcher'; 8 | export * from './ifFalseStmtMatcher'; 9 | export * from './ifMatcher'; 10 | export * from './ifNotDefMatcher'; 11 | export * from './includeMatcher'; 12 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/index.ts: -------------------------------------------------------------------------------- 1 | export * from './grammar'; 2 | export * from './preprocess'; 3 | export * from './interpreter'; 4 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/interpreter/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ExpressionResultTreeVisitor'; 2 | export * from './evalTokens'; 3 | export * from './execMacro'; 4 | export * from './interpret'; 5 | export * from './types'; 6 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/interpreter/types/CInterpreterIncludeResolver.ts: -------------------------------------------------------------------------------- 1 | import type { Either } from 'fp-ts/Either'; 2 | import { CPreprocessorError } from 'frontend/preprocessor/grammar'; 3 | 4 | export type CInterpreterSourcePath = { 5 | system: boolean; 6 | filename: string; 7 | }; 8 | 9 | export type CInterpreterSourceFile = { 10 | absolutePath: string; 11 | content: string; 12 | }; 13 | 14 | export type CInterpreterIncludeResolver = { 15 | read: ( 16 | currentFilePath: string, 17 | ) => ( 18 | path: CInterpreterSourcePath, 19 | ) => Either; 20 | }; 21 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/interpreter/types/CPreprocessorConfig.ts: -------------------------------------------------------------------------------- 1 | import type { CInterpreterIncludeResolver } from './CInterpreterIncludeResolver'; 2 | 3 | export type CPreprocessorConfig = { 4 | currentFilePath?: string; 5 | fsIncludeResolver?: CInterpreterIncludeResolver; 6 | }; 7 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/interpreter/types/CPreprocessorInterpretable.ts: -------------------------------------------------------------------------------- 1 | import type { CInterpreterContext } from './CInterpreterContext'; 2 | 3 | export interface CPreprocessorInterpretable { 4 | exec(interpreter: CInterpreterContext): void; 5 | } 6 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/interpreter/types/CPreprocessorMacro.ts: -------------------------------------------------------------------------------- 1 | import type { Token } from '@ts-cc/lexer'; 2 | import type { ASTCDefineArg } from '../../ast'; 3 | 4 | export type CPreprocessorMacroArgTokens = Token[]; 5 | 6 | export type CPreprocessorMacro = { 7 | args: ASTCDefineArg[]; 8 | expression: Token[]; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/interpreter/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CInterpreterContext'; 2 | export * from './CInterpreterIncludeResolver'; 3 | export * from './CPreprocessorConfig'; 4 | export * from './CPreprocessorInterpretable'; 5 | export * from './CPreprocessorMacro'; 6 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/preprocess.ts: -------------------------------------------------------------------------------- 1 | import * as E from 'fp-ts/Either'; 2 | import { pipe } from 'fp-ts/function'; 3 | 4 | import type { Token } from '@ts-cc/lexer'; 5 | 6 | import { CPreprocessorError, CPreprocessorErrorCode } from './grammar'; 7 | import { interpret, type CPreprocessorConfig } from './interpreter'; 8 | 9 | export const safePreprocess = 10 | (config: CPreprocessorConfig) => 11 | (tokens: Token[]): E.Either => { 12 | try { 13 | return pipe(tokens, interpret(config), E.right); 14 | } catch (e) { 15 | e.code = e.code ?? CPreprocessorErrorCode.SYNTAX_ERROR; 16 | 17 | return E.left([e]); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './isPreprocessorIdentifierLikeToken'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/preprocessor/utils/isPreprocessorIdentifierLikeToken.ts: -------------------------------------------------------------------------------- 1 | import { Token } from '@ts-cc/lexer'; 2 | 3 | export const isPreprocessorIdentifierLikeToken = (token: Token) => 4 | !!token.text && token.text[0] === '#'; 5 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/frontend/utils/createCCompilerTimings.ts: -------------------------------------------------------------------------------- 1 | import { createTiming } from '@ts-cc/core'; 2 | 3 | /** 4 | * Create pack that measures 5 | */ 6 | export const createCCompilerTimings = () => 7 | createTiming({ 8 | lexer: 0, 9 | preprocessor: 0, 10 | ast: 0, 11 | analyze: 0, 12 | ir: 0, 13 | codegen: 0, 14 | }); 15 | 16 | export type CCompilerTimer = ReturnType; 17 | export type CCompilerTimings = ReturnType< 18 | ReturnType['unwrap'] 19 | >; 20 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/fs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CInternalCompilerFsResolver'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/fs/kernel/index.ts: -------------------------------------------------------------------------------- 1 | import { GRAPHICS_MODE_HEADER } from './graphicsMode.h'; 2 | import { TEXT_MODE_HEADER } from './textMode.h'; 3 | 4 | export const KERNEL_HEADERS_FILES = { 5 | 'kernel/textmode.h': TEXT_MODE_HEADER, 6 | 'kernel/graphics.h': GRAPHICS_MODE_HEADER, 7 | }; 8 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/fs/std/alloca.h.ts: -------------------------------------------------------------------------------- 1 | export const ALLOCA_CONTENT_HEADER = /* c */ ` 2 | #ifndef ALLOCA_H 3 | #define ALLOCA_H 4 | 5 | #define alloca(total_bytes) __builtin_alloca(total_bytes) 6 | 7 | #endif 8 | `; 9 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/fs/std/index.ts: -------------------------------------------------------------------------------- 1 | import { ALLOCA_CONTENT_HEADER } from './alloca.h'; 2 | import { STD_ARG_CONTENT_HEADER } from './stdarg.h'; 3 | import { STD_BOOL_CONTENT_HEADER } from './stdbool.h'; 4 | import { STD_IO_CONTENT_HEADER } from './stdio.h'; 5 | import { STRING_CONTENT_HEADER } from './string.h'; 6 | 7 | export const STD_HEADERS_FILES = { 8 | 'stdarg.h': STD_ARG_CONTENT_HEADER, 9 | 'stdio.h': STD_IO_CONTENT_HEADER, 10 | 'stdbool.h': STD_BOOL_CONTENT_HEADER, 11 | 'string.h': STRING_CONTENT_HEADER, 12 | 'alloca.h': ALLOCA_CONTENT_HEADER, 13 | }; 14 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/fs/std/stdarg.h.ts: -------------------------------------------------------------------------------- 1 | export const STD_ARG_CONTENT_HEADER = /* c */ ` 2 | #ifndef STDARG_H 3 | #define STDARG_H 4 | 5 | #define va_list struct __builtin_va_list 6 | #define va_start(ap, type) __builtin_va_start(&ap, &type) 7 | #define va_end(ap) __builtin_va_end(&ap) 8 | #define va_arg(ap, type) __builtin_va_arg(&ap, sizeof(type)) 9 | 10 | #endif 11 | `; 12 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/fs/std/stdbool.h.ts: -------------------------------------------------------------------------------- 1 | export const STD_BOOL_CONTENT_HEADER = /* c */ ` 2 | #ifndef STDBOOL_H 3 | #define STDBOOL_H 4 | 5 | typedef char bool; 6 | 7 | #define true 1 8 | #define false 0 9 | 10 | #endif 11 | `; 12 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/fs/std/string.h.ts: -------------------------------------------------------------------------------- 1 | export const STRING_CONTENT_HEADER = /* c */ ` 2 | #ifndef STRING_H 3 | #define STRING_H 4 | 5 | int strlen(const char* str) { 6 | for (int i = 0;;++i) { 7 | if (*(str + i) == 0) { 8 | return i; 9 | } 10 | } 11 | 12 | return -1; 13 | } 14 | 15 | #endif 16 | `; 17 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './frontend'; 2 | export * from './constants'; 3 | export * from './arch'; 4 | export * from './ccompiler'; 5 | export * from './output'; 6 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/output/CBinaryObjectOutput.ts: -------------------------------------------------------------------------------- 1 | import { Identity } from '@ts-cc/core'; 2 | 3 | export type CBinaryLabel = { 4 | name: string; 5 | offset: number; 6 | }; 7 | 8 | export type CBinaryLabelsMap = Record; 9 | 10 | type CBinaryObjectOutputDescriptor = { 11 | srcFile: string; 12 | binary: number[]; 13 | externLabels: { 14 | size: number; 15 | map: CBinaryLabelsMap; 16 | }; 17 | }; 18 | 19 | export class CBinaryObjectOutput extends Identity {} 20 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/src/output/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CBinaryObjectOutput'; 2 | export * from './CCompilerOutput'; 3 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/tests/analyze/enums.test.ts: -------------------------------------------------------------------------------- 1 | import './utils'; 2 | 3 | describe('Enum typecheck', () => { 4 | test('anonymous enums have resolveable entries in current scope', () => { 5 | expect(/* cpp */ ` 6 | enum { 7 | ONE = 1, 8 | TWO = 2, 9 | }; 10 | 11 | int sum() { 12 | return ONE + TWO; 13 | } 14 | `).not.toHaveCompilerError(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/tests/analyze/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './analyzeMatcher'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/tests/codegen/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './asmMatcher'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/tests/ir/statements/constants.test.ts: -------------------------------------------------------------------------------- 1 | import '../utils'; 2 | 3 | describe('Constants IR', () => { 4 | test('enum variables are optimized', () => { 5 | expect(/* cpp */ ` 6 | enum { 7 | ONE = 1, 8 | TWO = 2, 9 | }; 10 | 11 | int sum() { 12 | return ONE + TWO; 13 | } 14 | `).toCompiledIRBeEqual(/* ruby */ ` 15 | # --- Block sum --- 16 | def sum(): [ret: int2B] 17 | ret %3: int2B 18 | end-def 19 | `); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/tests/ir/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './irMatcher'; 2 | -------------------------------------------------------------------------------- /packages/compiler-pico-c/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["src/"], 4 | "compilerOptions": { 5 | "baseUrl": "src", 6 | "module": "CommonJS", 7 | "paths": { 8 | "#constants": ["constants"], 9 | "#constants/*": ["constants/*"] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/compiler-rpn/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: ../../.eslintrc.yml 2 | -------------------------------------------------------------------------------- /packages/compiler-rpn/jest.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/extensions, import/no-default-export */ 2 | import { fileURLToPath } from 'node:url'; 3 | import { dirname } from 'path'; 4 | import { createJestConfig } from '../../config/jest.shared.config.mjs'; 5 | 6 | export default createJestConfig({ 7 | rootDir: dirname(fileURLToPath(import.meta.url)), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/compiler-rpn/rollup.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-default-export, import/extensions */ 2 | import { createPackageRollupConfig } from '../../config/rollup.shared.config.mjs'; 3 | 4 | export default createPackageRollupConfig(); 5 | -------------------------------------------------------------------------------- /packages/compiler-rpn/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './rpn'; 2 | export * from './utils'; 3 | -------------------------------------------------------------------------------- /packages/compiler-rpn/src/rpn.ts: -------------------------------------------------------------------------------- 1 | import { MathExpression } from './utils'; 2 | 3 | /** 4 | * Calculates numeric value of phrase 5 | */ 6 | export const rpn = MathExpression.evaluate; 7 | -------------------------------------------------------------------------------- /packages/compiler-rpn/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './MathExpression'; 2 | export * from './MathOperators'; 3 | export * from './MathError'; 4 | -------------------------------------------------------------------------------- /packages/compiler-rpn/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["src/"], 4 | "compilerOptions": { 5 | "baseUrl": "src", 6 | "module": "CommonJS" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/x86-assembler/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: ../../.eslintrc.yml 2 | -------------------------------------------------------------------------------- /packages/x86-assembler/jest.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/extensions, import/no-default-export */ 2 | import { fileURLToPath } from 'node:url'; 3 | import { dirname } from 'path'; 4 | import { createJestConfig } from '../../config/jest.shared.config.mjs'; 5 | 6 | export default createJestConfig({ 7 | rootDir: dirname(fileURLToPath(import.meta.url)), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/x86-assembler/rollup.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-default-export, import/extensions */ 2 | import { createPackageRollupConfig } from '../../config/rollup.shared.config.mjs'; 3 | 4 | export default createPackageRollupConfig(); 5 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/assets/index.ts: -------------------------------------------------------------------------------- 1 | export * from './binaryInstructionsDefs'; 2 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/constants/SegmentedAddress.ts: -------------------------------------------------------------------------------- 1 | export class SegmentedAddress { 2 | constructor( 3 | public offset: number, 4 | public segment: number, 5 | ) {} 6 | 7 | toString() { 8 | const { offset, segment } = this; 9 | 10 | return `${offset.toString(16)}:${segment.toString(16)}`; 11 | } 12 | 13 | static ofExtendedFlatAddress(num: number) { 14 | return new SegmentedAddress(num & 0xffff, (num >> 0x10) & 0xffff); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './MemoryRegion'; 2 | export * from './instructionSetSchema'; 3 | export * from './x86'; 4 | export * from './x86rm'; 5 | export * from './SegmentedAddress'; 6 | export * from './x86sib'; 7 | export * from './x86utils'; 8 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/constants/x86sib.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Scale index byte, used in addressing in 32mode 3 | */ 4 | export class SibByte { 5 | constructor( 6 | public scale: number, 7 | public index: number, 8 | public base: number, 9 | ) {} 10 | 11 | get byte() { 12 | const { scale, index, base } = this; 13 | 14 | return (scale & 0b111) | ((index & 0b111) << 0x3) | ((base & 0b11) << 0x6); 15 | } 16 | 17 | /** 18 | * @see {@link http://www.swansontec.com/sintel.html} 19 | */ 20 | static ofByte(byte: number) { 21 | return new SibByte( 22 | (byte & 0xc0) >> 0x6, // scale 23 | (byte & 0x38) >> 0x3, // index 24 | byte & 0x7, // base 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './asm'; 2 | export * from './assets'; 3 | export * from './constants'; 4 | export * from './parser'; 5 | export * from './preprocessor'; 6 | export * from './shared'; 7 | export * from './types'; 8 | export * from './utils'; 9 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/ast/critical/ASTExpression.ts: -------------------------------------------------------------------------------- 1 | import type * as E from 'fp-ts/Either'; 2 | 3 | export enum ASTExpressionParserError { 4 | UNRESOLVED_LABEL, 5 | } 6 | 7 | export type ASTExpressionParserResult = E.Either; 8 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/ast/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ASTAsmNode'; 2 | export * from './ASTAsmParser'; 3 | export * from './ast'; 4 | export * from './types'; 5 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/ast/instruction/args/ASTInstructionRegisterArg.ts: -------------------------------------------------------------------------------- 1 | import { InstructionArgType } from '../../../../types'; 2 | import { RegisterSchema } from '../../../../constants'; 3 | import { ASTInstructionArg } from './ASTInstructionArg'; 4 | 5 | /** 6 | * Instruction arg that contains register 7 | */ 8 | export class ASTInstructionRegisterArg extends ASTInstructionArg { 9 | constructor(schema: RegisterSchema, byteSize: number) { 10 | super(InstructionArgType.REGISTER, schema, byteSize); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/ast/instruction/args/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ASTInstructionRegisterArg'; 2 | export * from './ASTInstructionNumberArg'; 3 | export * from './ASTInstructionMemPtrArg'; 4 | export * from './ASTInstructionMemSegmentedArg'; 5 | export * from './ASTInstructionArg'; 6 | export * from './ASTInstructionArgMatchers'; 7 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/ast/instruction/args/matchers/farSegPointer.ts: -------------------------------------------------------------------------------- 1 | import { X86BitsMode } from '../../../../../constants'; 2 | import { InstructionArgType } from '../../../../../types'; 3 | import { ASTInstructionArg } from '../ASTInstructionArg'; 4 | 5 | export function farSegPointer(arg: ASTInstructionArg, maxByteSize: X86BitsMode): boolean { 6 | return arg.type === InstructionArgType.SEGMENTED_MEMORY && arg.byteSize <= maxByteSize; 7 | } 8 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/ast/instruction/args/matchers/imm.ts: -------------------------------------------------------------------------------- 1 | import { X86BitsMode } from '../../../../../constants'; 2 | import { InstructionArgType } from '../../../../../types'; 3 | import { ASTInstructionArg } from '../ASTInstructionArg'; 4 | 5 | /** Numbers */ 6 | export function imm(arg: ASTInstructionArg, maxByteSize: X86BitsMode): boolean { 7 | return ( 8 | arg.type === InstructionArgType.LABEL || 9 | (arg.type === InstructionArgType.NUMBER && arg.byteSize <= maxByteSize) 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/ast/instruction/args/matchers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './farSegPointer'; 2 | export * from './imm'; 3 | export * from './immCanBeImplicitSignExtendedToByte'; 4 | export * from './indirectFarSegPointer'; 5 | export * from './mem'; 6 | export * from './moffs'; 7 | export * from './nearPointer'; 8 | export * from './reg'; 9 | export * from './relLabel'; 10 | export * from './sreg'; 11 | export * from './x87'; 12 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/ast/instruction/args/matchers/indirectFarSegPointer.ts: -------------------------------------------------------------------------------- 1 | import { InstructionArgType, BranchAddressingType } from '../../../../../types'; 2 | import { ASTInstruction } from '../../ASTInstruction'; 3 | import { ASTInstructionArg } from '../ASTInstructionArg'; 4 | 5 | export function indirectFarSegPointer( 6 | arg: ASTInstructionArg, 7 | instruction: ASTInstruction, 8 | ): boolean { 9 | const { branchAddressingType } = instruction; 10 | 11 | return ( 12 | arg.type === InstructionArgType.MEMORY && 13 | (branchAddressingType === BranchAddressingType.FAR || branchAddressingType === null) 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/ast/instruction/args/matchers/moffs.ts: -------------------------------------------------------------------------------- 1 | import { X86BitsMode } from '../../../../../constants'; 2 | import { InstructionArgType } from '../../../../../types'; 3 | 4 | import { ASTInstructionArg } from '../ASTInstructionArg'; 5 | import { ASTInstructionMemPtrArg } from '../ASTInstructionMemPtrArg'; 6 | 7 | export function moffs(arg: ASTInstructionArg, maxByteSize: X86BitsMode): boolean { 8 | if (arg.type !== InstructionArgType.MEMORY) { 9 | return false; 10 | } 11 | 12 | const memArg = arg; 13 | return ( 14 | memArg.isDisplacementOnly() && memArg.addressDescription.dispByteSize <= maxByteSize 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/ast/instruction/args/matchers/sreg.ts: -------------------------------------------------------------------------------- 1 | import { X86BitsMode } from '../../../../../constants'; 2 | import { ASTInstructionArg } from '../ASTInstructionArg'; 3 | import { reg } from './reg'; 4 | 5 | export function sreg(arg: ASTInstructionArg, byteSize: X86BitsMode): boolean { 6 | return reg(arg, byteSize, true); 7 | } 8 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/ast/instruction/utils/isTokenInstructionBeginning.ts: -------------------------------------------------------------------------------- 1 | import { TokenType, Token } from '@ts-cc/lexer'; 2 | import { InstructionPrefix, COMPILER_INSTRUCTIONS_SET } from '../../../../constants'; 3 | 4 | /** 5 | * Returns true if token might be beginning of instruction 6 | */ 7 | export function isTokenInstructionBeginning(token: Token): boolean { 8 | if ( 9 | token.type !== TokenType.KEYWORD || 10 | (!COMPILER_INSTRUCTIONS_SET[token.lowerText] && !InstructionPrefix[token.upperText]) 11 | ) { 12 | return false; 13 | } 14 | 15 | return true; 16 | } 17 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/ast/types.ts: -------------------------------------------------------------------------------- 1 | export enum ASTNodeKind { 2 | INSTRUCTION, 3 | LABEL, 4 | DEFINE, 5 | EQU, 6 | COMPILER_OPTION, 7 | TIMES, 8 | } 9 | 10 | /** 11 | * User for resolve labels in AST 12 | */ 13 | export type BinaryLabelsOffsets = Map; 14 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/compiler/index.ts: -------------------------------------------------------------------------------- 1 | export * from './BinaryBlob'; 2 | export * from './BinaryPassResults'; 3 | export * from './X86Compiler'; 4 | export * from './compile'; 5 | export * from './utils'; 6 | export * from './view'; 7 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/compiler/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './findMatchingMemAddressingRMByte'; 2 | export * from './findMatchingSregPrefix'; 3 | export * from './rpnTokens'; 4 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/compiler/view/index.ts: -------------------------------------------------------------------------------- 1 | export * from './BinaryView'; 2 | export * from './TableBinaryView'; 3 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ast'; 2 | export * from './compiler'; 3 | export * from './lexer'; 4 | export * from './utils'; 5 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/lexer/index.ts: -------------------------------------------------------------------------------- 1 | export * from './asmLexer'; 2 | export * from './tokens'; 3 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/lexer/tokens/index.ts: -------------------------------------------------------------------------------- 1 | export * from './SizeOverrideToken'; 2 | export * from './BranchAddressingTypeToken'; 3 | export * from './RegisterToken'; 4 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/utils/externalLinkerLabel.ts: -------------------------------------------------------------------------------- 1 | const EXTERNAL_LINKER_SYMBOL_SUFFIX = '@plt'; 2 | 3 | export const markLabelAsLinkerExternalSymbol = (label: string) => 4 | `${label}${EXTERNAL_LINKER_SYMBOL_SUFFIX}`; 5 | 6 | export const isExternalLinkerSymbol = (label: string) => 7 | label.endsWith(EXTERNAL_LINKER_SYMBOL_SUFFIX); 8 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './assignLabelsToTokens'; 2 | export * from './fetchInstructionTokensArgsList'; 3 | export * from './getByteSizeArgPrefixName'; 4 | export * from './isJumpInstruction'; 5 | export * from './isPossibleLabelToken'; 6 | export * from './isReservedKeyword'; 7 | export * from './isX87Instruction'; 8 | export * from './externalLinkerLabel'; 9 | export * from './toStringArgsList'; 10 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/utils/isJumpInstruction.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Used to detect if instruction wants to consume some bytes, 3 | * if so - it will popably consume at least 2 imm bytes 4 | * (due to IP size) 5 | */ 6 | export function isJumpInstruction(opcode: string): boolean { 7 | return opcode[0] === 'j' || opcode === 'call' || opcode === 'loop'; 8 | } 9 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/utils/isPossibleLabelToken.ts: -------------------------------------------------------------------------------- 1 | import { TokenType, Token, TokenKind } from '@ts-cc/lexer'; 2 | 3 | /** 4 | * Returns true if token might be label 5 | */ 6 | export function isPossibleLabelToken(token: Token): boolean { 7 | return ( 8 | (token.type === TokenType.KEYWORD && !token.kind) || // 2+2 9 | (token.type === TokenType.BRACKET && token.kind === TokenKind.PARENTHES_BRACKET) // (2+2) 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/utils/isReservedKeyword.ts: -------------------------------------------------------------------------------- 1 | import { COMPILER_INSTRUCTIONS_SET } from '../../constants/instructionSetSchema'; 2 | import { COMPILER_REGISTERS_SET } from '../../constants/x86'; 3 | 4 | import { TIMES_TOKEN_NAME } from '../ast/critical/ASTTimes'; 5 | import { EQU_TOKEN_NAME } from '../ast/critical/ASTEqu'; 6 | import { tokenDefSize } from '../ast/def/ASTDef'; 7 | 8 | /** 9 | * Check if string phrase is asm language syntax 10 | */ 11 | export function isReservedKeyword(token: string): boolean { 12 | return !!( 13 | COMPILER_INSTRUCTIONS_SET[token] || 14 | COMPILER_REGISTERS_SET[token] || 15 | token === TIMES_TOKEN_NAME || 16 | token === EQU_TOKEN_NAME || 17 | tokenDefSize(token) 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/utils/isX87Instruction.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Used to detect if instruction is from X87, generally prefixed with F 3 | */ 4 | export function isX87Instruction(opcode: string): boolean { 5 | return opcode[0] === 'f'; 6 | } 7 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/parser/utils/toStringArgsList.ts: -------------------------------------------------------------------------------- 1 | import * as R from 'ramda'; 2 | 3 | /** 4 | * Used in string serializers 5 | */ 6 | export function toStringArgsList(prefix: string, args: any[]): string { 7 | const formattedArgs = R.map(R.toString, args); 8 | 9 | return R.toLower(`${prefix} ${R.join(', ', formattedArgs)}`); 10 | } 11 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/preprocessor/matchers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './mathExpression'; 2 | export * from './logicExpression'; 3 | export * from './relationExpression'; 4 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/preprocessor/matchers/utils/PreprocessorReducePostifxOperatorsVisitor.ts: -------------------------------------------------------------------------------- 1 | import { ReducePostfixOperatorsVisitor } from '@ts-cc/grammar'; 2 | import { ASTPreprocessorKind } from '../../constants'; 3 | 4 | export class PreprocessorReducePostfixOperatorsVisitor extends ReducePostfixOperatorsVisitor { 5 | constructor() { 6 | super(ASTPreprocessorKind.BinaryOperator); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/preprocessor/matchers/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './createLeftRecursiveOperatorMatcher'; 2 | export * from './PreprocessorReducePostifxOperatorsVisitor'; 3 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/preprocessor/nodes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ASTPreprocessorMacro'; 2 | export * from './ASTPreprocessorSyntaxLine'; 3 | export * from './ASTPreprocessorDefine'; 4 | export * from './ASTPreprocessorUndef'; 5 | export * from './ASTPreprocessorExpression'; 6 | export * from './ASTPreprocessorIF'; 7 | export * from './ASTPreprocessorIFDef'; 8 | export * from './ASTPreprocessorBinaryOpNode'; 9 | export * from './ASTPreprocessorStmt'; 10 | export * from './ASTPreprocessorValueNode'; 11 | export * from './ASTPreprocessorCriticalEQU'; 12 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/shared/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ParserError'; 2 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/utils/createAssemblerTimings.ts: -------------------------------------------------------------------------------- 1 | import { createTiming } from '@ts-cc/core'; 2 | 3 | /** 4 | * Create pack that measures 5 | */ 6 | export function createAssemblerTimings() { 7 | return createTiming({ 8 | preprocessor: 0, 9 | lexer: 0, 10 | ast: 0, 11 | compiler: 0, 12 | }); 13 | } 14 | 15 | export type AssemblerTimings = ReturnType< 16 | ReturnType['unwrap'] 17 | >; 18 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/utils/getSignedNumber.ts: -------------------------------------------------------------------------------- 1 | import { BINARY_MASKS } from '@ts-cc/core'; 2 | import type { X86BitsMode } from '../constants'; 3 | 4 | /** 5 | * Convert signed byte number to normal 6 | */ 7 | export const getSignedNumber = (num: number, bits: X86BitsMode = 0x1): number => { 8 | const sign = (num >> (0x8 * bits - 0x1)) & 0x1; 9 | if (sign) { 10 | num -= BINARY_MASKS[bits] + 0x1; 11 | } 12 | return num; 13 | }; 14 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './createAssemblerTimings'; 2 | export * from './getSignedNumber'; 3 | export * from './signExtend'; 4 | export * from './toUnsignedNumber'; 5 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/utils/signExtend.ts: -------------------------------------------------------------------------------- 1 | import { BINARY_MASKS, getMSbit } from '@ts-cc/core'; 2 | import type { X86BitsMode } from '../constants'; 3 | 4 | export const signExtend = ( 5 | num: number, 6 | bits: X86BitsMode, 7 | targetBits: X86BitsMode, 8 | ): number => { 9 | if (targetBits <= bits) { 10 | return num; 11 | } 12 | 13 | const msbit = getMSbit(num, bits); 14 | const mask = msbit ? 0xff : 0x0; 15 | let output = num & BINARY_MASKS[bits]; 16 | 17 | for (let i = bits; i < targetBits; ++i) { 18 | output |= mask << (i * 8); 19 | } 20 | 21 | return output; 22 | }; 23 | -------------------------------------------------------------------------------- /packages/x86-assembler/src/utils/toUnsignedNumber.ts: -------------------------------------------------------------------------------- 1 | import { BINARY_MASKS } from '@ts-cc/core'; 2 | import type { X86BitsMode } from '../constants'; 3 | 4 | /** 5 | * Convert signed byte number to unsigned 6 | */ 7 | export const toUnsignedNumber = (num: number, bits: X86BitsMode = 0x1): number => { 8 | const up = BINARY_MASKS[bits]; 9 | if (num > up) { 10 | return num - up - 0x1; 11 | } 12 | 13 | if (num < 0x0) { 14 | return up + num + 0x1; 15 | } 16 | 17 | return num; 18 | }; 19 | -------------------------------------------------------------------------------- /packages/x86-assembler/tests/asm/modrm.asm: -------------------------------------------------------------------------------- 1 | ;= test: handle 16bit unsigned offset and various mod rm encoding 2 | ;= bin: 2effafff003b87fc05ff2604fac6010fc6010f 3 | [bits 16] 4 | [org 0x7C00] 5 | jmp far [cs:bx+0xFF] 6 | cmp ax, [bx-64004] 7 | jmp [0xf9fe + 0x06] 8 | mov byte [bx+di], 0xF 9 | mov byte [di+bx], 0xF 10 | 11 | ;= test: advanced math with brackets in modrm 12 | ;= bin: 8d45088d45088b4548 13 | [bits 16] 14 | [org 0x7C00] 15 | lea ax,[di+(0x04*2)] 16 | lea ax, [di+(0x4*2)] 17 | mov ax, [di+(0x4*2+(8*8))] 18 | -------------------------------------------------------------------------------- /packages/x86-assembler/tests/asm/prefixes.asm: -------------------------------------------------------------------------------- 1 | ;= test: segment prefixes 2 | ;= bin: 2ea464a426a43ea464c54704 3 | use16 4 | org 0x7C00 5 | 6 | cs movsb 7 | fs movsb 8 | es movsb 9 | ds movsb 10 | lds ax, [fs:bx+0x4] 11 | -------------------------------------------------------------------------------- /packages/x86-assembler/tests/asm/times.asm: -------------------------------------------------------------------------------- 1 | ;= test: calc correct instruction size in times with label 2 | ;= bin: d906117cd906117c9090909090909090f40000f942 3 | [org 7c00h] 4 | 5 | abc: 6 | times 2 fld dword [val_dd] 7 | times $-abc nop 8 | hlt 9 | 10 | val_dd: dd 124.5 11 | 12 | ;= test: proper size of output 13 | ;= bin: 000000000055aa 14 | [org 7c00h] 15 | 16 | times 5-($-$$) db 0 17 | times 5-($-$$) db 0 18 | db 0x55 19 | db 0xaa 20 | -------------------------------------------------------------------------------- /packages/x86-assembler/tests/compilerOptions.test.ts: -------------------------------------------------------------------------------- 1 | import { unsafeAsm } from '../src/asm'; 2 | 3 | describe('compiler options', () => { 4 | it('square brackets', () => { 5 | const compileResult = unsafeAsm()(` 6 | [bits 16] 7 | [org 0x7C00] 8 | `); 9 | 10 | expect(compileResult.compiler).toMatchObject({ 11 | mode: 0x2, 12 | origin: 0x7c00, 13 | }); 14 | }); 15 | 16 | it('no brackets', () => { 17 | const compileResult = unsafeAsm()(` 18 | bits 16 19 | org 0b01110 20 | `); 21 | 22 | expect(compileResult.compiler).toMatchObject({ 23 | mode: 0x2, 24 | origin: 0b01110, 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/x86-assembler/tests/utils/types.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.asm'; 2 | -------------------------------------------------------------------------------- /packages/x86-assembler/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["src/"], 4 | "compilerOptions": { 5 | "baseUrl": "src", 6 | "module": "CommonJS" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/x86-cpu/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: ../../.eslintrc.yml 2 | -------------------------------------------------------------------------------- /packages/x86-cpu/jest.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/extensions, import/no-default-export */ 2 | import { fileURLToPath } from 'node:url'; 3 | import { dirname } from 'path'; 4 | import { createJestConfig } from '../../config/jest.shared.config.mjs'; 5 | 6 | export default createJestConfig({ 7 | rootDir: dirname(fileURLToPath(import.meta.url)), 8 | }); 9 | -------------------------------------------------------------------------------- /packages/x86-cpu/rollup.config.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-default-export, import/extensions */ 2 | import { createPackageRollupConfig } from '../../config/rollup.shared.config.mjs'; 3 | 4 | export default createPackageRollupConfig(); 5 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/X86Unit.ts: -------------------------------------------------------------------------------- 1 | import { X86CPU } from './X86CPU'; 2 | 3 | /** 4 | * CPU Part 5 | */ 6 | export abstract class X86Unit { 7 | protected cpu: X86CPU; 8 | 9 | constructor(cpu: X86CPU) { 10 | this.cpu = cpu; 11 | this.init(cpu); 12 | } 13 | 14 | getCPU(): X86CPU { 15 | return this.cpu; 16 | } 17 | 18 | /** 19 | * Inits whole unit 20 | * 21 | * @todo 22 | * Add release method? 23 | */ 24 | protected abstract init(cpu: X86CPU): void; 25 | } 26 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './x86'; 2 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/devices/BIOS/asm/index.ts: -------------------------------------------------------------------------------- 1 | export * from './fakeBIOS'; 2 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/devices/Video/Renderers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './utils/VGACanvasRenderer'; 2 | export * from './utils/VGAPixBufCanvasRenderer'; 3 | 4 | export * from './VGATextModeCanvasRenderer'; 5 | export * from './VGAGraphicsModeCanvasRenderer'; 6 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/devices/Video/index.ts: -------------------------------------------------------------------------------- 1 | export * from './VGA'; 2 | export * from './HTML/VGARenderLoopDriver'; 3 | export * from './VGAConstants'; 4 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/devices/index.ts: -------------------------------------------------------------------------------- 1 | export * from './BIOS/BIOS'; 2 | export * from './PIT/PIT'; 3 | export * from './Video'; 4 | export * from './Keyboard'; 5 | export * from './CMOS'; 6 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/guards/index.ts: -------------------------------------------------------------------------------- 1 | export * from './isIntegerReg'; 2 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/guards/isIntegerReg.ts: -------------------------------------------------------------------------------- 1 | import { X86RegName } from '@ts-cc/x86-assembler'; 2 | import { X86_REGISTER_NAMES } from '../constants/x86'; 3 | 4 | export const isIntegerX86Reg = (reg: X86RegName) => X86_REGISTER_NAMES.includes(reg); 5 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/helpers/binaryToFloppy35Buffer.ts: -------------------------------------------------------------------------------- 1 | import { Buffer } from 'buffer'; 2 | 3 | const FLOPPY35_BYTE_SIZE = 1474560; 4 | 5 | /** 6 | * Converts array of numbers to floppy image 7 | */ 8 | export function binaryToFloppy35Buffer(binary: number[]): Buffer { 9 | const buffer = Buffer.alloc(FLOPPY35_BYTE_SIZE); 10 | Buffer.from(binary).copy(buffer, 0, 0, binary.length); 11 | 12 | return buffer; 13 | } 14 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './binaryToFloppy35Buffer'; 2 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Logger'; 2 | export * from './X86ALU'; 3 | export * from './X86CPU'; 4 | export * from './X86IO'; 5 | export * from './X86InstructionSet'; 6 | export * from './X86Stack'; 7 | export * from './X86Unit'; 8 | export * from './constants'; 9 | export * from './devices'; 10 | export * from './guards'; 11 | export * from './helpers'; 12 | export * from './memory'; 13 | export * from './parts'; 14 | export * from './x87'; 15 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/memory/index.ts: -------------------------------------------------------------------------------- 1 | export * from './VirtualMemBlockDriver'; 2 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/parts/X86Port.ts: -------------------------------------------------------------------------------- 1 | import { X86BitsMode } from '@ts-cc/x86-assembler'; 2 | 3 | export interface X86Port { 4 | set?(bits?: number, mode?: X86BitsMode): void; 5 | get?(bits?: number): number; 6 | } 7 | 8 | export type X86PortsSet = { 9 | [key: number]: X86Port; 10 | }; 11 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/parts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './X86AbstractCPU'; 2 | export * from './X86AbstractDevice'; 3 | export * from './X86Interrupt'; 4 | export * from './X86Port'; 5 | export * from './X86Regs'; 6 | export * from './X86RAM'; 7 | -------------------------------------------------------------------------------- /packages/x86-cpu/src/x87/index.ts: -------------------------------------------------------------------------------- 1 | export * from './X87'; 2 | export * from './X87Error'; 3 | export * from './X87Regs'; 4 | -------------------------------------------------------------------------------- /packages/x86-cpu/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["src/"], 4 | "compilerOptions": { 5 | "baseUrl": "src", 6 | "module": "CommonJS" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | tabWidth: 2, 3 | singleQuote: true, 4 | printWidth: 90, 5 | trailingComma: 'all', 6 | arrowParens: 'avoid', 7 | customAttributes: ['className'], 8 | endingPosition: 'absolute', 9 | customFunctions: ['clsx'], 10 | plugins: [ 11 | 'prettier-plugin-tailwindcss', 12 | 'prettier-plugin-classnames', 13 | 'prettier-plugin-merge', 14 | ], 15 | }; 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react", 4 | "target": "ES2021", 5 | "module": "CommonJS", 6 | "declaration": true, 7 | "declarationMap": true, 8 | "resolveJsonModule": true, 9 | "esModuleInterop": true, 10 | "experimentalDecorators": true, 11 | "downlevelIteration": true, 12 | "skipLibCheck": true, 13 | "baseUrl": "./" 14 | }, 15 | "include": ["**/*.ts", "**/*.tsx"], 16 | "exclude": ["node_modules/**/*"] 17 | } 18 | --------------------------------------------------------------------------------