diff --git a/packages/compiler-pico-c/src/frontend/preprocessor/interpreter/createInterpreterContext.ts b/packages/compiler-pico-c/src/frontend/preprocessor/interpreter/createInterpreterContext.ts index 51f64c95..643e4899 100644 --- a/packages/compiler-pico-c/src/frontend/preprocessor/interpreter/createInterpreterContext.ts +++ b/packages/compiler-pico-c/src/frontend/preprocessor/interpreter/createInterpreterContext.ts @@ -11,6 +11,7 @@ import { clexer } from '../../parser/lexer/clexer'; import { evalTokens } from './evalTokens'; import { ExpressionResultTreeVisitor } from './ExpressionResultTreeVisitor'; +import { CInternalCompilerFsResolver } from '../../../fs'; import { CPreprocessorError, CPreprocessorErrorCode } from '../grammar'; export type CInterpreterScope = { @@ -39,14 +40,14 @@ export const createInterpreterContext = ({ defineMacro: (name: string, macro: CPreprocessorMacro) => { scope.macros[name] = macro; }, + appendFinalTokens: finalTokens => { reduced.push(...finalTokens); }, - evalExpression: expression => { - const visitor = new ExpressionResultTreeVisitor(ctx); - return visitor.visit(expression).value; - }, + evalExpression: expression => + new ExpressionResultTreeVisitor(ctx).visit(expression).value, + includeFile: path => { if (!fsIncludeResolver) { throw new CPreprocessorError( @@ -59,7 +60,13 @@ export const createInterpreterContext = ({ pipe( E.Do, E.bind('resolverOutput', () => - fsIncludeResolver.read(currentFilePath)(path), + pipe( + new CInternalCompilerFsResolver().read()(path), + E.fold( + () => fsIncludeResolver.read(currentFilePath)(path), + E.right, + ), + ), ), E.bindW('tokens', ({ resolverOutput }) => clexer({})(resolverOutput.content), diff --git a/packages/compiler-pico-c/src/fs/CInternalCompilerFsResolver.ts b/packages/compiler-pico-c/src/fs/CInternalCompilerFsResolver.ts new file mode 100644 index 00000000..be38cdf7 --- /dev/null +++ b/packages/compiler-pico-c/src/fs/CInternalCompilerFsResolver.ts @@ -0,0 +1,47 @@ +import * as E from 'fp-ts/Either'; + +import { + CPreprocessorError, + CPreprocessorErrorCode, +} from '../frontend/preprocessor/grammar/CPreprocessorError'; + +import type { + CInterpreterIncludeResolver, + CInterpreterSourceFile, + CInterpreterSourcePath, +} from '../frontend/preprocessor'; + +import { STD_ARG_CONTENT_HEADER } from './stdarg.h'; + +export class CInternalCompilerFsResolver + implements CInterpreterIncludeResolver +{ + read = + () => + ( + path: CInterpreterSourcePath, + ): E.Either => { + const vfsFile = CInternalCompilerFsResolver.FILES[path.filename]; + + if (!path.system || !vfsFile) { + return E.left( + new CPreprocessorError( + CPreprocessorErrorCode.CANNOT_INCLUDE_FILE, + null, + { + name: path.filename, + }, + ), + ); + } + + return E.right({ + absolutePath: path.filename, + content: vfsFile, + }); + }; + + private static FILES = { + 'stdarg.h': STD_ARG_CONTENT_HEADER, + }; +} diff --git a/packages/compiler-pico-c/src/fs/index.ts b/packages/compiler-pico-c/src/fs/index.ts new file mode 100644 index 00000000..f12ab3a1 --- /dev/null +++ b/packages/compiler-pico-c/src/fs/index.ts @@ -0,0 +1,2 @@ +export * from './CInternalCompilerFsResolver'; +export * from './stdarg.h'; diff --git a/packages/compiler-pico-c/src/fs/stdarg.h.ts b/packages/compiler-pico-c/src/fs/stdarg.h.ts new file mode 100644 index 00000000..5e9801d0 --- /dev/null +++ b/packages/compiler-pico-c/src/fs/stdarg.h.ts @@ -0,0 +1,5 @@ +export const STD_ARG_CONTENT_HEADER = /* c */ ` + #define va_start(v, l) __builtin_va_start(v, l) + #define va_end(v) __builtin_va_end(v) + #define va_arg(v,l) __builtin_va_arg(v, l) +`;