aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.clang-format236
-rw-r--r--Makefile2
-rw-r--r--main.c251
-rw-r--r--program.input1
-rw-r--r--types.h32
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
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..e02a9f2
--- /dev/null
+++ b/main.c
@@ -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
diff --git a/types.h b/types.h
new file mode 100644
index 0000000..37cc4ed
--- /dev/null
+++ b/types.h
@@ -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