Browse Source

Compiles and build completely

master
Ludovic 'Archivist' Lagouardette 1 year ago
parent
commit
f1a96d849b
13 changed files with 642 additions and 129 deletions
  1. +213
    -0
      .clang-format
  2. +172
    -0
      .clang-tidy
  3. +48
    -0
      .idea/codeStyles/Project.xml
  4. +5
    -0
      .idea/codeStyles/codeStyleConfig.xml
  5. +7
    -0
      .idea/inspectionProfiles/Project_Default.xml
  6. +8
    -1
      CMakeLists.txt
  7. +2
    -2
      include/molasses/generator_primitives.h
  8. +42
    -23
      include/molasses/parser_primitives.h
  9. +1
    -4
      prototypes/molasses/basic_file.mol
  10. +1
    -9
      prototypes/molasses/first_rountrip.mol
  11. +80
    -50
      src/main.cpp
  12. +14
    -12
      src/molasses/generator_primitives_x86_64_linux.cpp
  13. +49
    -28
      src/molasses/parser_primitives.cpp

+ 213
- 0
.clang-format View File

@ -0,0 +1,213 @@
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: BlockIndent
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignEscapedNewlines: Right
AlignOperands: DontAlign
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakArrays: true
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
QualifierAlignment: Leave
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
PackConstructorInitializers: BinPack
BasedOnStyle: ''
ConstructorInitializerAllOnOneLineOrOnePerLine: false
AllowAllConstructorInitializersOnNextLine: true
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
IndentCaseLabels: true
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: BeforeHash
IndentExternBlock: AfterExternBlock
IndentRequiresClause: true
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertBraces: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
LambdaBodyIndentation: Signature
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0
PointerAlignment: Left
PPIndentWidth: -1
ReferenceAlignment: Pointer
ReflowComments: false
RemoveBracesLLVM: false
RequiresClausePosition: OwnLine
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: Never
SpaceBeforeParensOptions:
AfterControlStatements: false
AfterForeachMacros: false
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: false
AfterOverloadedOperator: false
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: c++20
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME

+ 172
- 0
.clang-tidy View File

@ -0,0 +1,172 @@
---
InheritParentConfig: false
Checks: '-*,
bugprone-argument-comment,
bugprone-assert-side-effect,
bugprone-bad-signal-to-kill-thread,
bugprone-branch-clone,
bugprone-copy-constructor-init,
bugprone-dangling-handle,
bugprone-dynamic-static-initializers,
bugprone-fold-init-type,
bugprone-forward-declaration-namespace,
bugprone-forwarding-reference-overload,
bugprone-inaccurate-erase,
bugprone-incorrect-roundings,
bugprone-integer-division,
bugprone-lambda-function-name,
bugprone-macro-parentheses,
bugprone-macro-repeated-side-effects,
bugprone-misplaced-operator-in-strlen-in-alloc,
bugprone-misplaced-pointer-arithmetic-in-alloc,
bugprone-misplaced-widening-cast,
bugprone-move-forwarding-reference,
bugprone-multiple-statement-macro,
bugprone-no-escape,
bugprone-not-null-terminated-result,
bugprone-parent-virtual-call,
bugprone-posix-return,
bugprone-reserved-identifier,
bugprone-sizeof-container,
bugprone-sizeof-expression,
bugprone-spuriously-wake-up-functions,
bugprone-string-constructor,
bugprone-string-integer-assignment,
bugprone-string-literal-with-embedded-nul,
bugprone-suspicious-enum-usage,
bugprone-suspicious-include,
bugprone-suspicious-memory-comparison,
bugprone-suspicious-memset-usage,
bugprone-suspicious-missing-comma,
bugprone-suspicious-semicolon,
bugprone-suspicious-string-compare,
bugprone-swapped-arguments,
bugprone-terminating-continue,
bugprone-throw-keyword-missing,
bugprone-too-small-loop-variable,
bugprone-undefined-memory-manipulation,
bugprone-undelegated-constructor,
bugprone-unhandled-self-assignment,
bugprone-unused-raii,
bugprone-unused-return-value,
bugprone-use-after-move,
bugprone-virtual-near-miss,
cert-dcl21-cpp,
cert-dcl58-cpp,
cert-err34-c,
cert-err52-cpp,
cert-err60-cpp,
cert-flp30-c,
cert-msc50-cpp,
cert-msc51-cpp,
cert-str34-c,
cppcoreguidelines-interfaces-global-init,
cppcoreguidelines-narrowing-conversions,
cppcoreguidelines-pro-type-member-init,
cppcoreguidelines-pro-type-static-cast-downcast,
cppcoreguidelines-slicing,
google-default-arguments,
google-explicit-constructor,
google-runtime-operator,
hicpp-exception-baseclass,
hicpp-multiway-paths-covered,
misc-misplaced-const,
misc-new-delete-overloads,
misc-no-recursion,
misc-non-copyable-objects,
misc-throw-by-value-catch-by-reference,
misc-unconventional-assign-operator,
misc-uniqueptr-reset-release,
modernize-avoid-bind,
modernize-concat-nested-namespaces,
modernize-deprecated-headers,
modernize-deprecated-ios-base-aliases,
modernize-loop-convert,
modernize-make-shared,
modernize-make-unique,
modernize-pass-by-value,
modernize-raw-string-literal,
modernize-redundant-void-arg,
modernize-replace-auto-ptr,
modernize-replace-disallow-copy-and-assign-macro,
modernize-replace-random-shuffle,
modernize-return-braced-init-list,
modernize-shrink-to-fit,
modernize-unary-static-assert,
modernize-use-auto,
modernize-use-bool-literals,
modernize-use-emplace,
modernize-use-equals-default,
modernize-use-equals-delete,
modernize-use-nodiscard,
modernize-use-noexcept,
modernize-use-nullptr,
modernize-use-override,
modernize-use-transparent-functors,
modernize-use-uncaught-exceptions,
mpi-buffer-deref,
mpi-type-mismatch,
openmp-use-default-none,
performance-faster-string-find,
performance-for-range-copy,
performance-implicit-conversion-in-loop,
performance-inefficient-algorithm,
performance-inefficient-string-concatenation,
performance-inefficient-vector-operation,
performance-move-const-arg,
performance-move-constructor-init,
performance-no-automatic-move,
performance-noexcept-move-constructor,
performance-trivially-destructible,
performance-type-promotion-in-math-fn,
performance-unnecessary-copy-initialization,
performance-unnecessary-value-param,
portability-simd-intrinsics,
readability-avoid-const-params-in-decls,
readability-const-return-type,
readability-container-size-empty,
readability-convert-member-functions-to-static,
readability-delete-null-pointer,
readability-deleted-default,
readability-inconsistent-declaration-parameter-name,
readability-make-member-function-const,
readability-misleading-indentation,
readability-misplaced-array-index,
readability-non-const-parameter,
readability-redundant-control-flow,
readability-redundant-declaration,
readability-identifier-naming,
readability-redundant-function-ptr-dereference,
readability-redundant-smartptr-get,
readability-redundant-string-cstr,
readability-redundant-string-init,
readability-simplify-subscript-expr,
readability-static-accessed-through-instance,
readability-static-definition-in-anonymous-namespace,
readability-string-compare,
readability-uniqueptr-delete-release,
readability-use-anyofallof'
CheckOptions:
- {key: readability-identifier-naming.NamespaceCase, value: lower_case }
- {key: readability-identifier-naming.AbstractClassCase, value: lower_case }
- {key: readability-identifier-naming.ClassCase, value: lower_case }
- {key: readability-identifier-naming.ClassMemberCase, value: lower_case }
- {key: readability-identifier-naming.ClassMethodCase, value: lower_case }
- {key: readability-identifier-naming.ClassConstantCase, value: lower_case }
- {key: readability-identifier-naming.ConstantParameterCase, value: lower_case }
- {key: readability-identifier-naming.ConstantMemberCase, value: lower_case }
- {key: readability-identifier-naming.ConstexprFunctionCase, value: lower_case }
- {key: readability-identifier-naming.ConstantPointerParameterCase, value: lower_case }
- {key: readability-identifier-naming.TemplateParameterCase, value: CamelCase }
- {key: readability-identifier-naming.VirtualMethodCase, value: lower_case }
- {key: readability-identifier-naming.TypedefCase, value: lower_case }
- {key: readability-identifier-naming.StructCase, value: lower_case }
- {key: readability-identifier-naming.FunctionCase, value: lower_case }
- {key: readability-identifier-naming.MethodCase, value: lower_case }
- {key: readability-identifier-naming.MemberCase, value: lower_case }
- {key: readability-identifier-naming.ParameterCase, value: lower_case }
- {key: readability-identifier-naming.VariableCase, value: lower_case }
- {key: readability-identifier-naming.LocalVariableCase, value: lower_case }
- {key: readability-identifier-naming.GlobalConstantCase, value: lower_case }
- {key: readability-identifier-naming.ConstexprVariableCase, value: lower_case }
- {key: readability-identifier-naming.EnumConstantCase, value: lower_case }

+ 48
- 0
.idea/codeStyles/Project.xml View File

@ -0,0 +1,48 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="LINE_SEPARATOR" value="&#10;" />
<Objective-C-extensions>
<rules>
<rule entity="NAMESPACE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="MACRO" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="CLASS" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="STRUCT" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="ENUM" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="UNION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="CLASS_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="STRUCT_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="CLASS_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="STRUCT_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="GLOBAL_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="PARAMETER" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="LOCAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
</rules>
</Objective-C-extensions>
<Objective-C-extensions>
<rules>
<rule entity="NAMESPACE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="MACRO" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="CLASS" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="STRUCT" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="ENUM" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="UNION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="CLASS_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="STRUCT_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="CLASS_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="STRUCT_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="GLOBAL_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="PARAMETER" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
<rule entity="LOCAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" />
</rules>
</Objective-C-extensions>
<clangFormatSettings>
<option name="ENABLED" value="true" />
</clangFormatSettings>
</code_scheme>
</component>

+ 5
- 0
.idea/codeStyles/codeStyleConfig.xml View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

+ 7
- 0
.idea/inspectionProfiles/Project_Default.xml View File

@ -0,0 +1,7 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="OCInconsistentNaming" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="UnconstrainedVariableType" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

+ 8
- 1
CMakeLists.txt View File

@ -7,4 +7,11 @@ set(CMAKE_CXX_STANDARD 20)
include_directories(include)
add_executable(sugar src/main.cpp src/molasses/lexer.cpp src/molasses/generator_primitives_x86_64_linux.cpp include/molasses/lexer.h src/molasses/parser_primitives.cpp include/molasses/parser_primitives.h include/molasses/generator_primitives.h)
add_executable(sugar
src/main.cpp
src/molasses/lexer.cpp
src/molasses/generator_primitives_x86_64_linux.cpp
include/molasses/lexer.h
src/molasses/parser_primitives.cpp
include/molasses/parser_primitives.h
include/molasses/generator_primitives.h)

+ 2
- 2
include/molasses/generator_primitives.h View File

@ -6,11 +6,11 @@ namespace molasses {
std::vector<std::string> generate_return();
std::vector<std::string> generate_label(std::string target);
std::vector<std::string> generate_label(k">const std::string& target);
std::vector<std::string> generate_push_int32(int32_t target);
std::vector<std::string> generate_call(std::string target);
std::vector<std::string> generate_call(k">const std::string& target);
std::vector<std::string> generate_enter();
}

+ 42
- 23
include/molasses/parser_primitives.h View File

@ -11,10 +11,17 @@
enum class architecture_t {
x86_64
x86_64_linux,
x86_linux
};
constexpr architecture_t architecture = architecture_t::x86_64;
#if defined(__x86_64__) && __linux__
constexpr architecture_t architecture = architecture_t::x86_64_linux;
constexpr size_t architecture_ptr_size = 8;
#elif defined(__i386) || defined(__i386__) || defined(i386) && __linux__
constexpr architecture_t architecture = architecture_t::x86_linux;
constexpr size_t architecture_ptr_size = 4;
#endif
namespace molasses {
struct type {
@ -113,44 +120,56 @@ namespace molasses {
return lhs.name() <=> rhs.name();
}
struct TypeInputError : std::runtime_error {
TypeInputError() : std::runtime_error("Bad type provided") {}
struct type_input_error : std::runtime_error {
type_input_error() : std::runtime_error("Bad type provided") {}
// TODO: Better error message
};
struct ValueMissingError : std::runtime_error {
ValueMissingError() : std::runtime_error("Expected value, none provided") {}
struct value_missing_error : std::runtime_error {
value_missing_error() : std::runtime_error("Expected value, none provided") {}
// TODO: Better error message
};
struct ProcedureStackError : std::runtime_error {
ProcedureStackError() : std::runtime_error("Expected the stack to look like the return stack upon completion") {}
struct procedure_stack_error : std::runtime_error {
procedure_stack_error() : std::runtime_error("Expected the stack to look like the return stack upon completion") {}
// TODO: Better error message
};
struct UnexpectedTokenError : std::runtime_error {
UnexpectedTokenError() : std::runtime_error("An unexpected token has been encountered") {}
struct unexpected_token_error : std::runtime_error {
unexpected_token_error() : std::runtime_error("An unexpected token has been encountered") {}
// TODO: Better error message
};
struct ExpectingTokenError : std::runtime_error {
ExpectingTokenError() : std::runtime_error("An expected token has not been encountered before the end of the input") {}
// TODO: Better error message
};
struct UnknownTokenError : std::runtime_error {
UnknownTokenError() : std::runtime_error("An unknown token has not been encountered") {}
struct expecting_token_error : std::runtime_error {
expecting_token_error() : std::runtime_error("An expected token has not been encountered before the end of the input") {}
// TODO: Better error message
};
struct unknown_token_error : std::runtime_error {
unknown_token_error() : std::runtime_error("An unknown token has not been encountered") {}
// TODO: Better error message
};
struct type_expected_with_modifier_error : std::runtime_error {
type_expected_with_modifier_error() : std::runtime_error("A type is expected before a modifier") {}
// TODO: Better error message
};
std::vector<std::string> operator>>(std::vector<std::string> current_stack, const operation& next_op);
std::optional<int32_t> try_parse_int32(const std::string& str);
struct parser_context {
std::vector<std::shared_ptr<type>> types;
std::vector<std::shared_ptr<operation>> operations;
struct parser_context {
std::vector<std::shared_ptr<type>> types;
std::vector<std::shared_ptr<operation>> operations;
std::vector<std::shared_ptr<procedure_operation>> procedures;
[[nodiscard]] std::shared_ptr<type> lookup_type(const std::string&) const;
[[nodiscard]] std::shared_ptr<operation> lookup_operation(const std::string&) const;
};
[[nodiscard]] std::shared_ptr<type> lookup_type(const std::string&) const;
[[nodiscard]] std::shared_ptr<operation> lookup_operation(const std::string&) const;
};
struct generate_context {
lexed_output lexer;
parser_context parser;
std::vector<std::shared_ptr<procedure_operation>> procedures;
};
parser_context parse(parser_context, const lexed_output&);
generate_context parse(parser_context, const lexed_output&);
std::vector<std::string> generate(generate_context);
parser_context register_integers(parser_context);
parser_context register_i32_operations(parser_context);

+ 1
- 4
prototypes/molasses/basic_file.mol View File

@ -1,7 +1,4 @@
__PROC__ procedure_name
i16 i8
__PROC__ main
__--__
i32
__DO__
i32 __CAST__ __SWAP__ i32 __CAST__ *
__END__

+ 1
- 9
prototypes/molasses/first_rountrip.mol View File

@ -6,12 +6,4 @@ __DO__
__LET__ size, ptr, fd
size ptr __CAST_I64__ fd 1_i64 __SYSCALL4__
__END_LET__
__END__
proc __DEREF_I64_PTR__
i64 ptr
--
i64
DO
END
__END__

+ 80
- 50
src/main.cpp View File

@ -1,55 +1,85 @@
#include "molasses/lexer.h"
#include "molasses/parser_primitives.h"
#include <cstring>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <sstream>
#include <stack>
#include <string>
#include <variant>
int main() {
/*
molasses::lexed_output initial;
initial.dictionary[1] = "+";
{
auto v = molasses::lex("hello hello potato 128 hello 128 +");
auto v2 = molasses::lex("salad hello potato 129 hello 128");
for (auto symbol: v.symbols) {
std::cout << "v: " << symbol << " - " << v.dictionary.at(symbol) << "\n";
}
std::cout << "\n";
for (auto symbol: v2.symbols) {
std::cout << "v2: " << symbol << " - " << v2.dictionary.at(symbol) << "\n";
}
auto v_merged = molasses::concatenate(initial, molasses::concatenate(v, v2));
std::cout << "\n";
for (auto symbol: v_merged.symbols) {
std::cout << "v_merged: " << symbol << " - " << v_merged.dictionary.at(symbol) << "\n";
}
}
auto v = molasses::lex("1 2 +");
molasses::parser_context ctx;
ctx = molasses::register_integers(ctx);
ctx.operations.emplace_back(std::make_shared<molasses::primitive_operation>(std::string{"+"}, std::vector<std::string>({"i32", "i32"}), std::vector<std::string>({"i32"})));
if(molasses::type_check(ctx, v, v.symbols, {}, {"i32"})) {
std::cout << "Checks out\n";
}*/
/*
auto lexed = molasses::lex("__PROC__ sum\n"
"i32 i32\n"
"__--__\n"
"i32\n"
"__DO__\n"
"+\n"
"__END__");*/
auto lexed = molasses::lex("__PROC__ main\n"
"__--__\n"
"__DO__\n"
"__END__");
molasses::parser_context ctx;
ctx = molasses::register_integers(ctx);
ctx = molasses::register_i32_operations(ctx);
molasses::parse(ctx, lexed);
using compile_element = std::variant<molasses::lexed_output, molasses::generate_context, std::string>;
int main(int argc, char** argv) {
std::vector<std::string> arguments;
while(argc > 1) {
argv++;
arguments.emplace_back(*argv, strlen(*argv));
argc--;
}
std::stack<compile_element> compile_stack;
for(auto elem : arguments) {
if(elem == "generate") {
if(std::holds_alternative<std::string>(compile_stack.top())) {
auto filename = std::get<std::string>(compile_stack.top());
compile_stack.pop();
if(std::holds_alternative<molasses::generate_context>(compile_stack.top())) {
auto generator = std::get<molasses::generate_context>(compile_stack.top());
compile_stack.pop();
auto assembler = molasses::generate(generator);
std::ofstream output(filename+".s");
for(const auto& line : assembler) {
output << line;
}
compile_stack.emplace(filename);
} else throw std::runtime_error("generate expects a parsed output");
} else throw std::runtime_error("generate expects a filename");
} else if(elem == "parse") {
molasses::parser_context ctx;
ctx = molasses::register_integers(ctx);
ctx = molasses::register_i32_operations(ctx);
if(std::holds_alternative<molasses::lexed_output>(compile_stack.top())) {
auto lexer = std::get<molasses::lexed_output>(compile_stack.top());
compile_stack.pop();
auto generator = molasses::parse(ctx, lexer);
compile_stack.emplace(generator);
} else throw std::runtime_error("parse expects a lexed output");
} else if(elem == "lex") {
if(std::holds_alternative<std::string>(compile_stack.top())) {
auto filename = std::get<std::string>(compile_stack.top());
compile_stack.pop();
if(not std::filesystem::exists(filename)) throw std::runtime_error("file "+filename+" does not exist");
std::ifstream t(filename);
std::stringstream buffer;
buffer << t.rdbuf();
auto lexed = molasses::lex(buffer.str());
compile_stack.emplace(lexed);
} else throw std::runtime_error("lex expects a filename");
} else if(elem == "merge") {
if(std::holds_alternative<molasses::lexed_output>(compile_stack.top())) {
auto lexer_1 = std::get<molasses::lexed_output>(compile_stack.top());
compile_stack.pop();
if(std::holds_alternative<molasses::lexed_output>(compile_stack.top())) {
auto lexer_2 = std::get<molasses::lexed_output>(compile_stack.top());
compile_stack.pop();
compile_stack.emplace(molasses::concatenate(lexer_1, lexer_2));
} else throw std::runtime_error("merge expects 2 lexed outputs");
} else throw std::runtime_error("merge expects 2 lexed outputs");
} else if(elem == "assemble") {
if(std::holds_alternative<std::string>(compile_stack.top())) {
auto filename = std::get<std::string>(compile_stack.top());
compile_stack.pop();
std::stringstream compile; compile << "clang -c " << filename << ".s -o " << filename << ".o";
std::stringstream link; link << "ld -e _start " << filename << ".o -o " << filename;
std::cout << compile.str() << std::endl;
system(compile.str().c_str());
std::cout << link.str() << std::endl;
system(link.str().c_str());
} else throw std::runtime_error("assemble expects an assembly file");
} else compile_stack.emplace(elem);
}
}

+ 14
- 12
src/molasses/generator_primitives_x86_64_linux.cpp View File

@ -2,7 +2,8 @@
#include "molasses/generator_primitives.h"
namespace molasses {
parser_context register_integers(parser_context ctx) requires (architecture == architecture_t::x86_64) {
parser_context register_integers(parser_context ctx)
requires (architecture == architecture_t::x86_64_linux) {
ctx.types.push_back(std::make_shared<primitive_type>("i8", 1));
ctx.types.push_back(std::make_shared<primitive_type>("i16", 2));
ctx.types.push_back(std::make_shared<primitive_type>("i32", 4));
@ -15,7 +16,8 @@ namespace molasses {
return ctx;
}
parser_context register_i32_operations(parser_context ctx) requires (architecture == architecture_t::x86_64) {
parser_context register_i32_operations(parser_context ctx)
requires (architecture == architecture_t::x86_64_linux) {
ctx.operations.emplace_back(
std::make_shared<molasses::primitive_operation>(
std::string{"+"},
@ -168,29 +170,29 @@ namespace molasses {
return ctx;
}
std::vector<std::string> generate_call(std::string target)
requires (architecture == architecture_t::x86_64) {
std::vector<std::string> generate_call(k">const std::string& target)
requires (architecture == architecture_t::x86_64_linux) {
return {
" call "+target+"\n",
};
}
std::vector<std::string> generate_push_int32(int32_t target)
requires (architecture == architecture_t::x86_64) {
requires (architecture == architecture_t::x86_64_linux) {
return {
" pushq $" +std::to_string(target)+ "\n"
};
}
std::vector<std::string> generate_label(std::string target)
requires (architecture == architecture_t::x86_64) {
std::vector<std::string> generate_label(k">const std::string& target)
requires (architecture == architecture_t::x86_64_linux) {
return {
target+":\n"
};
}
std::vector<std::string> generate_return()
requires (architecture == architecture_t::x86_64) {
requires (architecture == architecture_t::x86_64_linux) {
return {
" // Return to caller\n",
" addq $-8, %r10\n",
@ -200,7 +202,7 @@ namespace molasses {
}
std::vector<std::string> generate_enter()
requires (architecture == architecture_t::x86_64) {
requires (architecture == architecture_t::x86_64_linux) {
return {
" // Prepare the function stack\n",
" popq (%r10)\n"
@ -209,7 +211,7 @@ namespace molasses {
}
std::vector<std::string> initialize_stack()
requires (architecture == architecture_t::x86_64) {
requires (architecture == architecture_t::x86_64_linux) {
std::vector<std::string> operations = {
"code:\n",
" .skip 1000000\n",
@ -230,11 +232,11 @@ namespace molasses {
" call initialize_callstack\n"
};
for(auto op : generate_call("main")) {
for(const auto& op : generate_call("main")) {
operations.push_back(op);
}
for(auto op : std::vector<std::string>{
for(const auto& op : std::vector<std::string>{
" movq $0, %rdi\n",
" movq $60, %rax\n",
" syscall\n"

+ 49
- 28
src/molasses/parser_primitives.cpp View File

@ -10,14 +10,14 @@ namespace molasses {
auto args = next_op.argument_types();
while(not (args.empty() or current_stack.empty())) {
if(current_stack.back() != args.back()) {
throw TypeInputError();
throw type_input_error();
} else {
args.pop_back();
current_stack.pop_back();
}
}
if(not args.empty()) {
throw ValueMissingError();
throw value_missing_error();
}
}
{
@ -78,7 +78,7 @@ namespace molasses {
return type_stack == execution_output;
}
parser_context parse(parser_context ctx, const lexed_output& lexer_data) {
generate_context parse(parser_context ctx, const lexed_output& lexer_data) {
enum op : int {
DO_KW = 1,
SEPARATOR_KW,
@ -96,14 +96,34 @@ namespace molasses {
std::vector<std::shared_ptr<procedure_operation>> parsed_procedures;
auto register_pointer_type = [&](std::string full_ptr_type_name) -> void {
if(auto type = ctx.lookup_type(full_ptr_type_name); !type) {
ctx.types.push_back(std::make_shared<primitive_type>(std::move(full_ptr_type_name), architecture_ptr_size));
}
};
auto compact_type_modifiers = [&](const std::vector<std::string>& type_info) -> std::vector<std::string> {
std::vector<std::string> ret_val;
for(auto elem : type_info) {
if(elem == "ptr") {
if(ret_val.empty()) throw type_expected_with_modifier_error();
ret_val.back() += " ptr";
register_pointer_type(ret_val.back());
} else {
ret_val.push_back(elem);
}
}
return ret_val;
};
auto parse_proc = [&](auto it) -> std::pair<typeof(it), std::shared_ptr<procedure_operation>> {
#define CHECK_FOR_UNEXPECTED_STREAM_END \
if(it == tokens.symbols.end()) { \
throw ExpectingTokenError(); \
throw expecting_token_error(); \
}
if(*it != PROC_KW) {
throw UnexpectedTokenError();
throw unexpected_token_error();
}
++it;
CHECK_FOR_UNEXPECTED_STREAM_END;
@ -112,10 +132,6 @@ namespace molasses {
++it;
CHECK_FOR_UNEXPECTED_STREAM_END;
if(it == tokens.symbols.end()) {
throw ExpectingTokenError();
}
// Process arguments list
std::vector<std::string> argument_types;
while(*it != SEPARATOR_KW) {
@ -125,6 +141,7 @@ namespace molasses {
}
++it;
CHECK_FOR_UNEXPECTED_STREAM_END;
argument_types = compact_type_modifiers(argument_types);
// Process return types list
std::vector<std::string> return_types;
@ -135,6 +152,7 @@ namespace molasses {
}
++it;
CHECK_FOR_UNEXPECTED_STREAM_END;
return_types = compact_type_modifiers(return_types);
// Process return types list
std::vector<symbol> body;
@ -160,27 +178,15 @@ namespace molasses {
for(auto& proc : parsed_procedures) {
if(not type_check(ctx, tokens, proc->_body, proc->_args, proc->_rets)) {
throw ProcedureStackError();
throw procedure_stack_error();
}
}
std::vector<std::string> generated;
for(auto instr : initialize_stack()) {
generated.push_back(instr);
}
for(auto proc : parsed_procedures) {
for(auto instr : proc->generate(ctx, tokens)) {
generated.push_back(instr);
}
}
for(auto line : generated) {
std::cout << line;
}
return ctx;
return {
tokens,
ctx,
parsed_procedures
};
}
std::vector<std::string> procedure_operation::generate(const parser_context& ctx, const lexed_output& lexer_data) const {
@ -201,7 +207,7 @@ namespace molasses {
ops.push_back(instruction);
}
} else {
throw UnknownTokenError();
throw unknown_token_error();
}
}
@ -215,4 +221,19 @@ namespace molasses {
std::vector<std::string> procedure_operation::emit(const parser_context& ctx) const {
return generate_call(name());
}
std::vector<std::string> generate(generate_context ctx) {
std::vector<std::string> generated;
for(auto instr : initialize_stack()) {
generated.push_back(instr);
}
for(auto proc : ctx.procedures) {
for(auto instr : proc->generate(ctx.parser, ctx.lexer)) {
generated.push_back(instr);
}
}
return generated;
}
}

Loading…
Cancel
Save