diff options
| -rw-r--r-- | .clang-format | 236 | ||||
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | main.c | 251 | ||||
| -rw-r--r-- | program.input | 1 | ||||
| -rw-r--r-- | types.h | 32 |
5 files changed, 522 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..c5aaf5f --- /dev/null +++ b/.clang-format @@ -0,0 +1,236 @@ +--- +Language: C +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: Right +AlignConsecutiveAssignments: + Enabled: true + AcrossEmptyLines: true + AcrossComments: true + AlignCompound: true + AlignFunctionPointers: true + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: true + AcrossEmptyLines: true + AcrossComments: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseColons: false +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowBreakBeforeNoexceptSpecifier: Never +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: AllDefinitions +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAdjacentStringLiterals: true +BreakAfterAttributes: Leave +BreakAfterJavaFieldAnnotations: false +BreakArrays: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Attach +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 2 +ContinuationIndentWidth: 2 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +KeepEmptyLinesAtEOF: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +PackConstructorInitializers: BinPack +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakScopeResolution: 500 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +PPIndentWidth: -1 +QualifierAlignment: Leave +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterPlacementOperator: true + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE +... + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2709a32 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +frontend: main.c + clang -g -Og -O0 -Wall -Werror -pedantic -Wextra -std=c99 -lc main.c -o frontend @@ -0,0 +1,251 @@ +#include "types.h" +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +typedef struct Token { + // identifying tag + enum TokenType { + t_error, + t_size, + t_multiply, + t_divide, + t_add, + t_subtract, + t_whitespace, + t_newline, + t_number, + } type; + + // change to offset + size, or line + col -- alleviated by helper structure of + // ptrs to each newline + union Data { + i32 number; + } data; +} Token_t; + +// Should also add helper structure with pointers to each line + +static isize f_read(FILE* stream, char** dst); +static i64 f_size(FILE* stream); +static void l_print_token(Token_t token); +static Token_t* l_read(char* text, isize text_length, Token_t* dst); + +int +main(int argc, char* argv[]) { + if (argc == 2) { + FILE* f = NULL; + char* contents = NULL; + isize content_length = -1; + Token_t* tokens = NULL; + + f = fopen(argv[1], "r"); + if (f == NULL) { + fprintf(stdout, "! Failed to open file: %s\n", argv[1]); + } + + if (f != NULL) { + content_length = f_read(f, &contents); + if (content_length > 0) { + printf("%s:%ld\n%s\n", argv[1], content_length, contents); + } + fclose(f); + } + + if (content_length > 0) { + tokens = l_read(contents, strlen(contents), NULL); + free(contents); + } + + if (tokens != NULL) { + printf("%d tokens\n", tokens[0].data.number); + for (int t = 0; t < tokens[0].data.number; t++) { + l_print_token(tokens[t]); + } + } + } + return 0; +} + +/* Copies the contents of the file stream to *dst. + * @param stream An open file stream. + * @param dst** Destination buffer. If *dst is NULL allocates a buffer the size + * of stream using malloc. + * @return The number of bytes copied into dst. + * @error returns -1 on error. + */ +static isize +f_read(FILE* stream, char** dst) { + i64 file_sz = f_size(stream); + + if (dst == NULL) { + fprintf(stderr, "! Got NULL ptr\n"); + } + + if (dst != NULL && *dst == NULL && file_sz > 0) { + *dst = (char*)malloc(file_sz * sizeof(char)); + } + + if (dst != NULL && *dst == NULL && file_sz > 0) { + fprintf(stderr, "! Failed to allocate %ld bytes\n", file_sz * sizeof(char)); + } + + isize bytes_read = -1; + if (dst != NULL && *dst != NULL && file_sz > 0) { + bytes_read = fread(*dst, sizeof(char), file_sz, stream); + } + + if (bytes_read < file_sz) { + fprintf(stderr, "! Failed to read file, read %ld out of %ld bytes\n", + bytes_read, file_sz); + } + + return bytes_read; +} + +/* Returns the size in bytes and rewinds the stream. + * @param stream An open file stream. + * @return the size of the file in bytes. + * @error Returns -1 on error. + */ +static i64 +f_size(FILE* stream) { + // Could ftell and rewind to previous position, but scratch that + i64 size = -1; + i32 error = fseek(stream, 0, SEEK_END); + + if (error) { + // TODO: handle pipes (check errno == ESPIPE) + fprintf(stderr, "! Failed to seek file: %s\n", strerror(errno)); + } else { + size = ftell(stream); + rewind(stream); + } + return size; +} + +static void +l_print_token(Token_t token) { + switch (token.type) { + case t_error: + fputs(" error ", stdout); + break; + case t_size: + printf(" [%d] ", token.data.number); + break; + case t_multiply: + fputs(" * ", stdout); + break; + case t_divide: + fputs(" / ", stdout); + break; + case t_add: + fputs(" + ", stdout); + break; + case t_subtract: + fputs(" - ", stdout); + break; + case t_number: + printf("%d", token.data.number); + break; + default: + break; + } +} + +/* Reads text and parses it into an array of tokens + * @param text A buffer holding the input text + * @return a pointer to dst + * @error Returns NULL on error. + */ +static Token_t* +l_read(char* text, isize text_length, Token_t* dst) { + if (text_length > 0 && dst == NULL) { + dst = (Token_t*)malloc(text_length * sizeof(Token_t)); + } + + if (text_length > 0 && dst == NULL) { + fprintf(stderr, "! Failed to allocate %ld bytes\n", + text_length * sizeof(Token_t)); + } + + if (text_length > 0 && dst != NULL) { + isize i = 0; + isize t = 1; + i32 error = 0; + + dst[0].type = t_size; + dst[0].data.number = 0; + + // TODO: rewrite to + // if token != last-token + // dst = token,line,col + // last-token = token + // t++; + // while (last-token != error) + do { + switch (text[i]) { + // case t_size: + // break; + case '*': + dst[t].type = t_multiply; + t++; + break; + case '/': + dst[t].type = t_divide; + t++; + break; + case t_add: + dst[t].type = t_add; + t++; + break; + case '-': + dst[t].type = t_subtract; + t++; + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + dst[t].type = t_number; + dst[t].data.number = text[i] - '0'; + t++; + break; + case '+': + dst[t].type = t_add; + t++; + break; + + case ' ': + case '\t': + dst[t].type = t_whitespace; + t++; + break; + + case '\n': + dst[t].type = t_newline; + t++; + break; + + default: + dst[t].type = t_error; + t++; + error = 1; + break; + } + i++; + } while (!error && i < text_length); + + dst[0].data.number = t; + } + + return dst; +} diff --git a/program.input b/program.input new file mode 100644 index 0000000..b43bef7 --- /dev/null +++ b/program.input @@ -0,0 +1 @@ +2 + 2 * 2 @@ -0,0 +1,32 @@ +#ifndef TYPES_H +#define TYPES_H + +#include <stdbool.h> +#include <stdint.h> + +/* Signed */ +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; + +/* Unsigned */ +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +/* floating points */ +typedef float f32; +typedef double f64; + +/* sizes */ +#if __x86_64__ || __ppc64__ || _WIN64 +typedef u64 usize; +typedef i64 isize; +#else +typedef u32 usize; +typedef i32 isize; +#endif + +#endif |
