diff options
| Commit | 6e19bb560d474736d45f5be011ff0830c7019991 (patch) | |
|---|---|---|
| Author | 2018-11-05 23:34:00 +0200 | |
| Committer | 2018-11-05 23:34:00 +0200 | |
| Files | 42d29cf1c4e6a535ba526f434debaac3a70df2c6 | |
| IPL-6e19bb560d474736d45f5be011ff0830c7019991.tar IPL-6e19bb560d474736d45f5be011ff0830c7019991.tar.gz IPL-6e19bb560d474736d45f5be011ff0830c7019991.zip | ||
Squashed 'spasm/' content from commit 08ee95d
git-subtree-dir: spasm
git-subtree-split: 08ee95d89054ba0d33697d613799a0a013aedf89
46 files changed, 7390 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..b34a670 --- /dev/null +++ b/.clang-format @@ -0,0 +1,148 @@ +--- +Language: Cpp +# BasedOnStyle: Chromium +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: false +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Allman +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^<ext/.*\.h>' + Priority: 2 + - Regex: '^<.*\.h>' + Priority: 1 + - Regex: '^<.*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseLabels: true +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + CanonicalDelimiter: '' + BasedOnStyle: google +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 8 +UseTab: Never +... + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/doc/Doxyfile b/doc/Doxyfile new file mode 100644 index 0000000..e7e3eb3 --- /dev/null +++ b/doc/Doxyfile @@ -0,0 +1,1252 @@ +# Doxyfile 1.5.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = spasm + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.0.1 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command <command> <input-file>, where <command> is the value of +# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../src + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/solution/Makefile b/solution/Makefile new file mode 100644 index 0000000..665d251 --- /dev/null +++ b/solution/Makefile @@ -0,0 +1,46 @@ +# GNU Make solution makefile autogenerated by GENie +# Type "make help" for usage help + +ifndef config + config=debug64 +endif +export config + +PROJECTS := spasm sprt sprun + +.PHONY: all clean help $(PROJECTS) + +all: $(PROJECTS) + +sprt: + @echo "==== Building sprt ($(config)) ====" + @${MAKE} --no-print-directory -C . -f sprt.make + +spasm: + @echo "==== Building spasm ($(config)) ====" + @${MAKE} --no-print-directory -C . -f spasm.make + +sprun: sprt + @echo "==== Building sprun ($(config)) ====" + @${MAKE} --no-print-directory -C . -f sprun.make + +clean: + @${MAKE} --no-print-directory -C . -f sprt.make clean + @${MAKE} --no-print-directory -C . -f spasm.make clean + @${MAKE} --no-print-directory -C . -f sprun.make clean + +help: + @echo "Usage: make [config=name] [target]" + @echo "" + @echo "CONFIGURATIONS:" + @echo " debug64" + @echo " release64" + @echo "" + @echo "TARGETS:" + @echo " all (default)" + @echo " clean" + @echo " sprt" + @echo " spasm" + @echo " sprun" + @echo "" + @echo "For more information, see https://github.com/bkaradzic/genie" diff --git a/solution/genie.lua b/solution/genie.lua new file mode 100644 index 0000000..b3bb00f --- /dev/null +++ b/solution/genie.lua @@ -0,0 +1,54 @@ +solution 'spasm' + configurations {'Debug', 'Release'} + platforms { 'x64' } + flags { + 'FatalWarnings', + 'ExtraWarnings', + 'Cpp14', + 'Symbols', + } + + defines { + '_SCL_SECURE_NO_WARNINGS', + } + + local root = '../build/' + + configuration 'Debug' + targetdir(root .. 'bin/Debug') + objdir(root .. 'obj/Debug') + + configuration 'Release' + flags 'OptimizeSpeed' + targetdir(root .. 'bin/Release') + objdir(root .. 'obj/Release') + configuration '*' + + project 'sprt' + kind 'StaticLib' + language 'C++' + uuid(os.uuid('sprt')) + files '../src/*.cpp' + removefiles '../src/main.cpp' + files '../src/*.h' + + project 'spasm' + kind 'ConsoleApp' + language 'C++' + uuid(os.uuid('spasm')) + files '../src/asm/*.cpp' + removefiles { + '../src/asm/lexdump.cpp', + '../src/asm/lexdump3.cpp', + } + files '../src/asm/*.h' + + project 'sprun' + kind 'ConsoleApp' + language 'C++' + uuid(os.uuid('sprun')) + files '../src/main.cpp' + links 'sprt' + + -- include '../test' + startproject 'sprun' diff --git a/solution/spasm.make b/solution/spasm.make new file mode 100644 index 0000000..4d90252 --- /dev/null +++ b/solution/spasm.make @@ -0,0 +1,197 @@ +# GNU Make project makefile autogenerated by GENie +ifndef config + config=debug64 +endif + +ifndef verbose + SILENT = @ +endif + +SHELLTYPE := msdos +ifeq (,$(ComSpec)$(COMSPEC)) + SHELLTYPE := posix +endif +ifeq (/bin,$(findstring /bin,$(SHELL))) + SHELLTYPE := posix +endif +ifeq (/bin,$(findstring /bin,$(MAKESHELL))) + SHELLTYPE := posix +endif + +ifeq (posix,$(SHELLTYPE)) + MKDIR = $(SILENT) mkdir -p "$(1)" + COPY = $(SILENT) cp -fR "$(1)" "$(2)" + RM = $(SILENT) rm -f "$(1)" +else + MKDIR = $(SILENT) mkdir "$(subst /,\\,$(1))" 2> nul || exit 0 + COPY = $(SILENT) copy /Y "$(subst /,\\,$(1))" "$(subst /,\\,$(2))" + RM = $(SILENT) del /F "$(subst /,\\,$(1))" 2> nul || exit 0 +endif + +CC = gcc +CXX = g++ +AR = ar + +ifndef RESCOMP + ifdef WINDRES + RESCOMP = $(WINDRES) + else + RESCOMP = windres + endif +endif + +MAKEFILE = spasm.make + +ifeq ($(config),debug64) + OBJDIR = ../build/obj/Debug/x64/Debug/spasm + TARGETDIR = ../build/bin/Debug + TARGET = $(TARGETDIR)/spasm + DEFINES += -D_SCL_SECURE_NO_WARNINGS + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES) + ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 + ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 + ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 -std=c++14 + ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 + ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 -std=c++14 + ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) + ALL_LDFLAGS += $(LDFLAGS) -m64 + LDDEPS += + LIBS += $(LDDEPS) + EXTERNAL_LIBS += + LINKOBJS = $(OBJECTS) + LINKCMD = $(CXX) -o $(TARGET) $(LINKOBJS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS) + OBJECTS := \ + $(OBJDIR)/src/asm/assembler.o \ + $(OBJDIR)/src/asm/bytecode.o \ + $(OBJDIR)/src/asm/lexer.o \ + $(OBJDIR)/src/asm/main.o \ + $(OBJDIR)/src/asm/symbol.o \ + $(OBJDIR)/src/asm/token.o \ + $(OBJDIR)/src/asm/tokenizer.o \ + + define PREBUILDCMDS + endef + define PRELINKCMDS + endef + define POSTBUILDCMDS + endef +endif + +ifeq ($(config),release64) + OBJDIR = ../build/obj/Release/x64/Release/spasm + TARGETDIR = ../build/bin/Release + TARGET = $(TARGETDIR)/spasm + DEFINES += -D_SCL_SECURE_NO_WARNINGS + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES) + ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 + ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 + ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 -std=c++14 + ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 + ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 -std=c++14 + ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) + ALL_LDFLAGS += $(LDFLAGS) -m64 + LDDEPS += + LIBS += $(LDDEPS) + EXTERNAL_LIBS += + LINKOBJS = $(OBJECTS) + LINKCMD = $(CXX) -o $(TARGET) $(LINKOBJS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS) + OBJECTS := \ + $(OBJDIR)/src/asm/assembler.o \ + $(OBJDIR)/src/asm/bytecode.o \ + $(OBJDIR)/src/asm/lexer.o \ + $(OBJDIR)/src/asm/main.o \ + $(OBJDIR)/src/asm/symbol.o \ + $(OBJDIR)/src/asm/token.o \ + $(OBJDIR)/src/asm/tokenizer.o \ + + define PREBUILDCMDS + endef + define PRELINKCMDS + endef + define POSTBUILDCMDS + endef +endif + +OBJDIRS := \ + $(OBJDIR) \ + $(OBJDIR)/src/asm \ + +RESOURCES := \ + +.PHONY: clean prebuild prelink + +all: $(OBJDIRS) $(TARGETDIR) prebuild prelink $(TARGET) + @: + +$(TARGET): $(GCH) $(OBJECTS) $(LDDEPS) $(EXTERNAL_LIBS) $(RESOURCES) | $(TARGETDIR) $(OBJDIRS) + @echo Linking spasm + $(SILENT) $(LINKCMD) + $(POSTBUILDCMDS) + +$(TARGETDIR): + @echo Creating $(TARGETDIR) + -$(call MKDIR,$(TARGETDIR)) + +$(OBJDIRS): + @echo Creating $(@) + -$(call MKDIR,$@) + +clean: + @echo Cleaning spasm +ifeq (posix,$(SHELLTYPE)) + $(SILENT) rm -f $(TARGET) + $(SILENT) rm -rf $(OBJDIR) +else + $(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET)) + $(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR)) +endif + +prebuild: + $(PREBUILDCMDS) + +prelink: + $(PRELINKCMDS) + +ifneq (,$(PCH)) +$(GCH): $(PCH) $(MAKEFILE) | $(OBJDIR) + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) -x c++-header $(DEFINES) $(INCLUDES) -o "$@" -c "$<" + +$(GCH_OBJC): $(PCH) $(MAKEFILE) | $(OBJDIR) + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_OBJCPPFLAGS) -x objective-c++-header $(DEFINES) $(INCLUDES) -o "$@" -c "$<" +endif + +$(OBJDIR)/src/asm/assembler.o: ../src/asm/assembler.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src/asm + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<" + +$(OBJDIR)/src/asm/bytecode.o: ../src/asm/bytecode.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src/asm + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<" + +$(OBJDIR)/src/asm/lexer.o: ../src/asm/lexer.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src/asm + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<" + +$(OBJDIR)/src/asm/main.o: ../src/asm/main.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src/asm + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<" + +$(OBJDIR)/src/asm/symbol.o: ../src/asm/symbol.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src/asm + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<" + +$(OBJDIR)/src/asm/token.o: ../src/asm/token.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src/asm + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<" + +$(OBJDIR)/src/asm/tokenizer.o: ../src/asm/tokenizer.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src/asm + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<" + +-include $(OBJECTS:%.o=%.d) +ifneq (,$(PCH)) + -include $(OBJDIR)/$(notdir $(PCH)).d + -include $(OBJDIR)/$(notdir $(PCH))_objc.d +endif diff --git a/solution/spasm.sln b/solution/spasm.sln new file mode 100644 index 0000000..1f36001 --- /dev/null +++ b/solution/spasm.sln @@ -0,0 +1,37 @@ +
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sprun", "sprun.vcxproj", "{FD605F10-6975-87C1-32F7-2A219ECA83F2}"
+ ProjectSection(ProjectDependencies) = postProject
+ {AE0A9E7C-9A41-9F0D-432E-85102F441B0F} = {AE0A9E7C-9A41-9F0D-432E-85102F441B0F}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sprt", "sprt.vcxproj", "{AE0A9E7C-9A41-9F0D-432E-85102F441B0F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spasm", "spasm.vcxproj", "{69185F10-D52C-87C1-9EAE-2A210A8283F2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FD605F10-6975-87C1-32F7-2A219ECA83F2}.Debug|x64.ActiveCfg = Debug|x64
+ {FD605F10-6975-87C1-32F7-2A219ECA83F2}.Debug|x64.Build.0 = Debug|x64
+ {FD605F10-6975-87C1-32F7-2A219ECA83F2}.Release|x64.ActiveCfg = Release|x64
+ {FD605F10-6975-87C1-32F7-2A219ECA83F2}.Release|x64.Build.0 = Release|x64
+ {AE0A9E7C-9A41-9F0D-432E-85102F441B0F}.Debug|x64.ActiveCfg = Debug|x64
+ {AE0A9E7C-9A41-9F0D-432E-85102F441B0F}.Debug|x64.Build.0 = Debug|x64
+ {AE0A9E7C-9A41-9F0D-432E-85102F441B0F}.Release|x64.ActiveCfg = Release|x64
+ {AE0A9E7C-9A41-9F0D-432E-85102F441B0F}.Release|x64.Build.0 = Release|x64
+ {69185F10-D52C-87C1-9EAE-2A210A8283F2}.Debug|x64.ActiveCfg = Debug|x64
+ {69185F10-D52C-87C1-9EAE-2A210A8283F2}.Debug|x64.Build.0 = Debug|x64
+ {69185F10-D52C-87C1-9EAE-2A210A8283F2}.Release|x64.ActiveCfg = Release|x64
+ {69185F10-D52C-87C1-9EAE-2A210A8283F2}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ EndGlobalSection
+EndGlobal
diff --git a/solution/spasm.vcxproj b/solution/spasm.vcxproj new file mode 100644 index 0000000..801feb8 --- /dev/null +++ b/solution/spasm.vcxproj @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{69185F10-D52C-87C1-9EAE-2A210A8283F2}</ProjectGuid>
+ <RootNamespace>spasm</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>..\build\bin\Debug\</OutDir>
+ <IntDir>..\build\obj\Debug\x64\Debug\spasm\</IntDir>
+ <TargetName>spasm</TargetName>
+ <TargetExt>.exe</TargetExt>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>..\build\bin\Release\</OutDir>
+ <IntDir>..\build\obj\Release\x64\Release\spasm\</IntDir>
+ <TargetName>spasm</TargetName>
+ <TargetExt>.exe</TargetExt>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)spasm.compile.pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)spasm.pdb</ProgramDatabaseFile>
+ <OutputFile>$(OutDir)spasm.exe</OutputFile>
+ <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)spasm.compile.pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)spasm.pdb</ProgramDatabaseFile>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <OutputFile>$(OutDir)spasm.exe</OutputFile>
+ <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\asm\assembler.cpp">
+ </ClCompile>
+ <ClCompile Include="..\src\asm\bytecode.cpp">
+ </ClCompile>
+ <ClCompile Include="..\src\asm\lexer.cpp">
+ </ClCompile>
+ <ClCompile Include="..\src\asm\main.cpp">
+ </ClCompile>
+ <ClCompile Include="..\src\asm\symbol.cpp">
+ </ClCompile>
+ <ClCompile Include="..\src\asm\token.cpp">
+ </ClCompile>
+ <ClCompile Include="..\src\asm\tokenizer.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/solution/spasm.vcxproj.filters b/solution/spasm.vcxproj.filters new file mode 100644 index 0000000..77f6487 --- /dev/null +++ b/solution/spasm.vcxproj.filters @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="src">
+ <UniqueIdentifier>{2DAB880B-99B4-887C-2230-9F7C8E38947C}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\asm">
+ <UniqueIdentifier>{6A9848A9-D677-C744-DF8F-521B4BEE2DA6}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\asm\assembler.cpp">
+ <Filter>src\asm</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\asm\bytecode.cpp">
+ <Filter>src\asm</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\asm\lexer.cpp">
+ <Filter>src\asm</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\asm\main.cpp">
+ <Filter>src\asm</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\asm\symbol.cpp">
+ <Filter>src\asm</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\asm\token.cpp">
+ <Filter>src\asm</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\asm\tokenizer.cpp">
+ <Filter>src\asm</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
diff --git a/solution/spasm.vcxproj.user b/solution/spasm.vcxproj.user new file mode 100644 index 0000000..99820f1 --- /dev/null +++ b/solution/spasm.vcxproj.user @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ <LocalDebuggerCommandArguments></LocalDebuggerCommandArguments>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ <LocalDebuggerCommandArguments></LocalDebuggerCommandArguments>
+ </PropertyGroup>
+</Project>
diff --git a/solution/sprt.make b/solution/sprt.make new file mode 100644 index 0000000..8d85739 --- /dev/null +++ b/solution/sprt.make @@ -0,0 +1,178 @@ +# GNU Make project makefile autogenerated by GENie +ifndef config + config=debug64 +endif + +ifndef verbose + SILENT = @ +endif + +SHELLTYPE := msdos +ifeq (,$(ComSpec)$(COMSPEC)) + SHELLTYPE := posix +endif +ifeq (/bin,$(findstring /bin,$(SHELL))) + SHELLTYPE := posix +endif +ifeq (/bin,$(findstring /bin,$(MAKESHELL))) + SHELLTYPE := posix +endif + +ifeq (posix,$(SHELLTYPE)) + MKDIR = $(SILENT) mkdir -p "$(1)" + COPY = $(SILENT) cp -fR "$(1)" "$(2)" + RM = $(SILENT) rm -f "$(1)" +else + MKDIR = $(SILENT) mkdir "$(subst /,\\,$(1))" 2> nul || exit 0 + COPY = $(SILENT) copy /Y "$(subst /,\\,$(1))" "$(subst /,\\,$(2))" + RM = $(SILENT) del /F "$(subst /,\\,$(1))" 2> nul || exit 0 +endif + +CC = gcc +CXX = g++ +AR = ar + +ifndef RESCOMP + ifdef WINDRES + RESCOMP = $(WINDRES) + else + RESCOMP = windres + endif +endif + +MAKEFILE = sprt.make + +ifeq ($(config),debug64) + OBJDIR = ../build/obj/Debug/x64/Debug/sprt + TARGETDIR = ../build/bin/Debug + TARGET = $(TARGETDIR)/libsprt.a + DEFINES += -D_SCL_SECURE_NO_WARNINGS + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES) + ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 + ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 + ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 -std=c++14 + ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 + ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 -std=c++14 + ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) + ALL_LDFLAGS += $(LDFLAGS) -m64 + LDDEPS += + LIBS += $(LDDEPS) + EXTERNAL_LIBS += + LINKOBJS = $(OBJECTS) + LINKCMD = $(AR) -rcs $(TARGET) + OBJECTS := \ + $(OBJDIR)/src/dstack.o \ + $(OBJDIR)/src/frames.o \ + $(OBJDIR)/src/spasm.o \ + + define PREBUILDCMDS + endef + define PRELINKCMDS + endef + define POSTBUILDCMDS + endef +endif + +ifeq ($(config),release64) + OBJDIR = ../build/obj/Release/x64/Release/sprt + TARGETDIR = ../build/bin/Release + TARGET = $(TARGETDIR)/libsprt.a + DEFINES += -D_SCL_SECURE_NO_WARNINGS + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES) + ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 + ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 + ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 -std=c++14 + ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 + ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 -std=c++14 + ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) + ALL_LDFLAGS += $(LDFLAGS) -m64 + LDDEPS += + LIBS += $(LDDEPS) + EXTERNAL_LIBS += + LINKOBJS = $(OBJECTS) + LINKCMD = $(AR) -rcs $(TARGET) + OBJECTS := \ + $(OBJDIR)/src/dstack.o \ + $(OBJDIR)/src/frames.o \ + $(OBJDIR)/src/spasm.o \ + + define PREBUILDCMDS + endef + define PRELINKCMDS + endef + define POSTBUILDCMDS + endef +endif + +OBJDIRS := \ + $(OBJDIR) \ + $(OBJDIR)/src \ + +RESOURCES := \ + +.PHONY: clean prebuild prelink + +all: $(OBJDIRS) $(TARGETDIR) prebuild prelink $(TARGET) + @: + +$(TARGET): $(GCH) $(OBJECTS) $(LDDEPS) $(EXTERNAL_LIBS) $(RESOURCES) | $(TARGETDIR) $(OBJDIRS) + @echo Archiving sprt +ifeq (posix,$(SHELLTYPE)) + $(SILENT) rm -f $(TARGET) +else + $(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET)) +endif + $(SILENT) $(LINKCMD) $(LINKOBJS) + $(POSTBUILDCMDS) + +$(TARGETDIR): + @echo Creating $(TARGETDIR) + -$(call MKDIR,$(TARGETDIR)) + +$(OBJDIRS): + @echo Creating $(@) + -$(call MKDIR,$@) + +clean: + @echo Cleaning sprt +ifeq (posix,$(SHELLTYPE)) + $(SILENT) rm -f $(TARGET) + $(SILENT) rm -rf $(OBJDIR) +else + $(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET)) + $(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR)) +endif + +prebuild: + $(PREBUILDCMDS) + +prelink: + $(PRELINKCMDS) + +ifneq (,$(PCH)) +$(GCH): $(PCH) $(MAKEFILE) | $(OBJDIR) + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) -x c++-header $(DEFINES) $(INCLUDES) -o "$@" -c "$<" + +$(GCH_OBJC): $(PCH) $(MAKEFILE) | $(OBJDIR) + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_OBJCPPFLAGS) -x objective-c++-header $(DEFINES) $(INCLUDES) -o "$@" -c "$<" +endif + +$(OBJDIR)/src/dstack.o: ../src/dstack.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<" + +$(OBJDIR)/src/frames.o: ../src/frames.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<" + +$(OBJDIR)/src/spasm.o: ../src/spasm.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<" + +-include $(OBJECTS:%.o=%.d) +ifneq (,$(PCH)) + -include $(OBJDIR)/$(notdir $(PCH)).d + -include $(OBJDIR)/$(notdir $(PCH))_objc.d +endif diff --git a/solution/sprt.vcxproj b/solution/sprt.vcxproj new file mode 100644 index 0000000..760d501 --- /dev/null +++ b/solution/sprt.vcxproj @@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{AE0A9E7C-9A41-9F0D-432E-85102F441B0F}</ProjectGuid>
+ <RootNamespace>sprt</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>..\build\bin\Debug\</OutDir>
+ <IntDir>..\build\obj\Debug\x64\Debug\sprt\</IntDir>
+ <TargetName>sprt</TargetName>
+ <TargetExt>.lib</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>..\build\bin\Release\</OutDir>
+ <IntDir>..\build\obj\Release\x64\Release\sprt\</IntDir>
+ <TargetName>sprt</TargetName>
+ <TargetExt>.lib</TargetExt>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(OutDir)sprt.pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Lib>
+ <OutputFile>$(OutDir)sprt.lib</OutputFile>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Lib>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)sprt.pdb</ProgramDatabaseFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(OutDir)sprt.pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Lib>
+ <OutputFile>$(OutDir)sprt.lib</OutputFile>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Lib>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)sprt.pdb</ProgramDatabaseFile>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\dstack.cpp">
+ </ClCompile>
+ <ClCompile Include="..\src\frames.cpp">
+ </ClCompile>
+ <ClCompile Include="..\src\spasm.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/solution/sprt.vcxproj.filters b/solution/sprt.vcxproj.filters new file mode 100644 index 0000000..c111a28 --- /dev/null +++ b/solution/sprt.vcxproj.filters @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="src">
+ <UniqueIdentifier>{2DAB880B-99B4-887C-2230-9F7C8E38947C}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\dstack.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\frames.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\src\spasm.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
diff --git a/solution/sprt.vcxproj.user b/solution/sprt.vcxproj.user new file mode 100644 index 0000000..99820f1 --- /dev/null +++ b/solution/sprt.vcxproj.user @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ <LocalDebuggerCommandArguments></LocalDebuggerCommandArguments>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ <LocalDebuggerCommandArguments></LocalDebuggerCommandArguments>
+ </PropertyGroup>
+</Project>
diff --git a/solution/sprun.make b/solution/sprun.make new file mode 100644 index 0000000..7b9be59 --- /dev/null +++ b/solution/sprun.make @@ -0,0 +1,161 @@ +# GNU Make project makefile autogenerated by GENie +ifndef config + config=debug64 +endif + +ifndef verbose + SILENT = @ +endif + +SHELLTYPE := msdos +ifeq (,$(ComSpec)$(COMSPEC)) + SHELLTYPE := posix +endif +ifeq (/bin,$(findstring /bin,$(SHELL))) + SHELLTYPE := posix +endif +ifeq (/bin,$(findstring /bin,$(MAKESHELL))) + SHELLTYPE := posix +endif + +ifeq (posix,$(SHELLTYPE)) + MKDIR = $(SILENT) mkdir -p "$(1)" + COPY = $(SILENT) cp -fR "$(1)" "$(2)" + RM = $(SILENT) rm -f "$(1)" +else + MKDIR = $(SILENT) mkdir "$(subst /,\\,$(1))" 2> nul || exit 0 + COPY = $(SILENT) copy /Y "$(subst /,\\,$(1))" "$(subst /,\\,$(2))" + RM = $(SILENT) del /F "$(subst /,\\,$(1))" 2> nul || exit 0 +endif + +CC = gcc +CXX = g++ +AR = ar + +ifndef RESCOMP + ifdef WINDRES + RESCOMP = $(WINDRES) + else + RESCOMP = windres + endif +endif + +MAKEFILE = sprun.make + +ifeq ($(config),debug64) + OBJDIR = ../build/obj/Debug/x64/Debug/sprun + TARGETDIR = ../build/bin/Debug + TARGET = $(TARGETDIR)/sprun + DEFINES += -D_SCL_SECURE_NO_WARNINGS + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES) + ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 + ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 + ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 -std=c++14 + ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 + ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -m64 -std=c++14 + ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) + ALL_LDFLAGS += $(LDFLAGS) -L"../build/bin/Debug" -m64 + LDDEPS += ../build/bin/Debug/libsprt.a + LIBS += $(LDDEPS) + EXTERNAL_LIBS += + LINKOBJS = $(OBJECTS) + LINKCMD = $(CXX) -o $(TARGET) $(LINKOBJS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS) + OBJECTS := \ + $(OBJDIR)/src/main.o \ + + define PREBUILDCMDS + endef + define PRELINKCMDS + endef + define POSTBUILDCMDS + endef +endif + +ifeq ($(config),release64) + OBJDIR = ../build/obj/Release/x64/Release/sprun + TARGETDIR = ../build/bin/Release + TARGET = $(TARGETDIR)/sprun + DEFINES += -D_SCL_SECURE_NO_WARNINGS + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -MP $(DEFINES) $(INCLUDES) + ALL_ASMFLAGS += $(ASMFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 + ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 + ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 -std=c++14 + ALL_OBJCFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 + ALL_OBJCPPFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -Werror -Wall -Wextra -g -O3 -m64 -std=c++14 + ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) + ALL_LDFLAGS += $(LDFLAGS) -L"../build/bin/Release" -m64 + LDDEPS += ../build/bin/Release/libsprt.a + LIBS += $(LDDEPS) + EXTERNAL_LIBS += + LINKOBJS = $(OBJECTS) + LINKCMD = $(CXX) -o $(TARGET) $(LINKOBJS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS) + OBJECTS := \ + $(OBJDIR)/src/main.o \ + + define PREBUILDCMDS + endef + define PRELINKCMDS + endef + define POSTBUILDCMDS + endef +endif + +OBJDIRS := \ + $(OBJDIR) \ + $(OBJDIR)/src \ + +RESOURCES := \ + +.PHONY: clean prebuild prelink + +all: $(OBJDIRS) $(TARGETDIR) prebuild prelink $(TARGET) + @: + +$(TARGET): $(GCH) $(OBJECTS) $(LDDEPS) $(EXTERNAL_LIBS) $(RESOURCES) | $(TARGETDIR) $(OBJDIRS) + @echo Linking sprun + $(SILENT) $(LINKCMD) + $(POSTBUILDCMDS) + +$(TARGETDIR): + @echo Creating $(TARGETDIR) + -$(call MKDIR,$(TARGETDIR)) + +$(OBJDIRS): + @echo Creating $(@) + -$(call MKDIR,$@) + +clean: + @echo Cleaning sprun +ifeq (posix,$(SHELLTYPE)) + $(SILENT) rm -f $(TARGET) + $(SILENT) rm -rf $(OBJDIR) +else + $(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET)) + $(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR)) +endif + +prebuild: + $(PREBUILDCMDS) + +prelink: + $(PRELINKCMDS) + +ifneq (,$(PCH)) +$(GCH): $(PCH) $(MAKEFILE) | $(OBJDIR) + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) -x c++-header $(DEFINES) $(INCLUDES) -o "$@" -c "$<" + +$(GCH_OBJC): $(PCH) $(MAKEFILE) | $(OBJDIR) + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_OBJCPPFLAGS) -x objective-c++-header $(DEFINES) $(INCLUDES) -o "$@" -c "$<" +endif + +$(OBJDIR)/src/main.o: ../src/main.cpp $(GCH) $(MAKEFILE) | $(OBJDIR)/src + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<" + +-include $(OBJECTS:%.o=%.d) +ifneq (,$(PCH)) + -include $(OBJDIR)/$(notdir $(PCH)).d + -include $(OBJDIR)/$(notdir $(PCH))_objc.d +endif diff --git a/solution/sprun.vcxproj b/solution/sprun.vcxproj new file mode 100644 index 0000000..08ee433 --- /dev/null +++ b/solution/sprun.vcxproj @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{FD605F10-6975-87C1-32F7-2A219ECA83F2}</ProjectGuid>
+ <RootNamespace>sprun</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <PreferredToolArchitecture>x64</PreferredToolArchitecture>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>..\build\bin\Debug\</OutDir>
+ <IntDir>..\build\obj\Debug\x64\Debug\sprun\</IntDir>
+ <TargetName>sprun</TargetName>
+ <TargetExt>.exe</TargetExt>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>..\build\bin\Release\</OutDir>
+ <IntDir>..\build\obj\Release\x64\Release\sprun\</IntDir>
+ <TargetName>sprun</TargetName>
+ <TargetExt>.exe</TargetExt>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)sprun.compile.pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)sprun.pdb</ProgramDatabaseFile>
+ <OutputFile>$(OutDir)sprun.exe</OutputFile>
+ <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalOptions> %(AdditionalOptions)</AdditionalOptions>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <PrecompiledHeader></PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ProgramDataBaseFileName>$(IntDir)sprun.compile.pdb</ProgramDataBaseFileName>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)sprun.pdb</ProgramDatabaseFile>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <OutputFile>$(OutDir)sprun.exe</OutputFile>
+ <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\main.cpp">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="sprt.vcxproj">
+ <Project>{AE0A9E7C-9A41-9F0D-432E-85102F441B0F}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/solution/sprun.vcxproj.filters b/solution/sprun.vcxproj.filters new file mode 100644 index 0000000..daeea8c --- /dev/null +++ b/solution/sprun.vcxproj.filters @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="src">
+ <UniqueIdentifier>{2DAB880B-99B4-887C-2230-9F7C8E38947C}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\main.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
diff --git a/solution/sprun.vcxproj.user b/solution/sprun.vcxproj.user new file mode 100644 index 0000000..99820f1 --- /dev/null +++ b/solution/sprun.vcxproj.user @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ <LocalDebuggerCommandArguments></LocalDebuggerCommandArguments>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ <LocalDebuggerCommandArguments></LocalDebuggerCommandArguments>
+ </PropertyGroup>
+</Project>
diff --git a/src/asm/assembler.cpp b/src/asm/assembler.cpp new file mode 100644 index 0000000..25ed377 --- /dev/null +++ b/src/asm/assembler.cpp @@ -0,0 +1,79 @@ +#include <cassert> + +#include "assembler.hpp" +#include "bytecode.hpp" +#include "symbol.hpp" +#include "tokenizer.hpp" + +namespace SpasmImpl +{ +namespace ASM +{ +Assembler::Assembler(Lexer::Tokenizer& tokenizer, Bytecode_Stream& bytecode) + : _tokenizer(&tokenizer), _bytecode(&bytecode) +{ +} + +void Assembler::assemble() +{ + Lexer::Token token = _tokenizer->next_token(); + + while (token.type() != Lexer::Token::endinput) + { + switch (token.type()) + { + case Lexer::Token::ident: + assemble_identifier(token); + break; + case Lexer::Token::label: + token = _tokenizer->next_token(); + assert(token.type() == Lexer::Token::ident); + _symbols.define(token.value_str(), _bytecode->size()); + break; + case Lexer::Token::integer: + case Lexer::Token::xinteger: + _bytecode->push_integer(token.value_int()); + break; + default: + _bytecode->push_opcode((Bytecode_Stream::Opcode_t)token.type()); + } + + token = _tokenizer->next_token(); + } + + Symbol_Table::const_iterator i = _symbols.begin(); + while (i != _symbols.end()) + { + backpatch(i->second); + ++i; + } +} + +void Assembler::backpatch(const Symbol* symbol) +{ + Symbol::Positions_t::const_iterator i = symbol->positions_begin(); + while (i != symbol->positions_end()) + { + _bytecode->set_location(*i, symbol->definition()); + ++i; + } +} + +void Assembler::assemble_identifier(const Lexer::Token& token) +{ + Symbol* symbol = _symbols.insert(token.value_str(), _bytecode->size()); + _bytecode->push_location(symbol->definition()); +} + +bool compile(std::istream& istr, Bytecode_Memory& bytecode) +{ + Lexer::Tokenizer tokenizer(istr); + Assembler assembler(tokenizer, bytecode); + + assembler.assemble(); + + return true; +} + +} // namespace ASM +} // namespace SpasmImpl diff --git a/src/asm/assembler.hpp b/src/asm/assembler.hpp new file mode 100644 index 0000000..d29139b --- /dev/null +++ b/src/asm/assembler.hpp @@ -0,0 +1,36 @@ +#ifndef ASSEMBPLER_HPP +#define ASSEMBPLER_HPP + +#include <iostream> + +#include "bytecode.hpp" +#include "symbol.hpp" +#include "tokenizer.hpp" + +namespace SpasmImpl +{ +namespace ASM +{ +class Assembler +{ + public: + Assembler(Lexer::Tokenizer&, Bytecode_Stream&); + + void assemble(); + + private: + void backpatch(const Symbol*); + void assemble_identifier(const Lexer::Token&); + + Lexer::Tokenizer* _tokenizer; + Bytecode_Stream* _bytecode; + + Symbol_Table _symbols; + +}; // class Assembler + +bool compile(std::istream&, Bytecode_Memory& bytecode); +} // namespace ASM +} // namespace SpasmImpl + +#endif // ASSEMBPLER_HPP diff --git a/src/asm/bytecode.cpp b/src/asm/bytecode.cpp new file mode 100644 index 0000000..27fed2b --- /dev/null +++ b/src/asm/bytecode.cpp @@ -0,0 +1,74 @@ +#include <fstream> +#include <iostream> +#include <string> +#include <vector> + +#include "bytecode.hpp" + +namespace SpasmImpl +{ +namespace ASM +{ +Bytecode_Stream::~Bytecode_Stream() {} + +Bytecode_File::Bytecode_File(const std::string& filename) + : _bytecode(filename.c_str(), std::ios_base::out | std::ios_base::binary) +{ +} + +void Bytecode_File::push_byte(Bytecode_Stream::byte byte) +{ + _bytecode.put(byte); +} + +void Bytecode_File::push_opcode(Bytecode_Stream::Opcode_t opcode) +{ + push_byte(opcode); +} + +void Bytecode_File::push_integer(int number) +{ + for (size_t i = 0; i < sizeof(int); ++i) + push_byte((number >> (i << 3)) & 0xff); +} + +void Bytecode_Memory::push_byte(Bytecode_Stream::byte byte) +{ + _bytecode.push_back(byte); +} + +void Bytecode_Memory::push_opcode(Bytecode_Stream::Opcode_t opcode) +{ + push_byte(opcode); +} + +void Bytecode_Memory::push_integer(int number) +{ + for (size_t i = 0; i < sizeof(int); ++i) + push_byte((number >> (i << 3)) & 0xff); +} + +void Bytecode_Memory::set_location(size_t index, size_t location) +{ + for (size_t i = 0; i < sizeof(size_t); ++i) + _bytecode.at(index + i) = ((location >> (i << 3)) & 0xff); +} + +void Bytecode_Memory::push_location(size_t location) +{ + for (size_t i = 0; i < sizeof(size_t); ++i) + _bytecode.push_back((location >> (i << 3)) & 0xff); +} + +const Bytecode_Memory::Bytecode& Bytecode_Memory::bytecode() const +{ + return _bytecode; +} + +size_t Bytecode_Memory::size() const +{ + return _bytecode.size(); +} + +} // namespace ASM +} // namespace SpasmImpl diff --git a/src/asm/bytecode.hpp b/src/asm/bytecode.hpp new file mode 100644 index 0000000..c08da46 --- /dev/null +++ b/src/asm/bytecode.hpp @@ -0,0 +1,87 @@ +#ifndef BYTECODE_HPP +#define BYTECODE_HPP + +#include <fstream> +#include <iostream> +#include <string> +#include <vector> + +namespace SpasmImpl +{ +namespace ASM +{ +class Bytecode_Stream +{ + public: + typedef unsigned char byte; + enum Opcode_t : byte + { + halt = 0, + push, + pop, + dup, + print, + read, + plus, + minus, + multiply, + divide, + modulus, + gotrue, + gofalse, + go, + call, + ret, + load, + store, + less, + lesseq + }; + + + virtual ~Bytecode_Stream(); + virtual void push_opcode(Opcode_t) = 0; + virtual void push_integer(int) = 0; + virtual void push_location(size_t) = 0; + virtual void set_location(size_t, size_t) = 0; + virtual size_t size() const = 0; +}; // class Bytecode_Stream + +class Bytecode_File : public Bytecode_Stream +{ + public: + Bytecode_File(const std::string&); + + virtual void push_opcode(Opcode_t); + virtual void push_integer(int); + + private: + Bytecode_File(const Bytecode_File&); + Bytecode_File& operator=(const Bytecode_File&); + void push_byte(Bytecode_Stream::byte); + + std::ofstream _bytecode; + +}; // class Bytecode_File + +class Bytecode_Memory : public Bytecode_Stream +{ + public: + virtual void push_opcode(Opcode_t); + virtual void push_integer(int); + virtual void push_location(size_t); + virtual void set_location(size_t, size_t); + virtual size_t size() const; + + typedef std::vector<Bytecode_Stream::byte> Bytecode; + const Bytecode& bytecode() const; + + private: + void push_byte(Bytecode_Stream::byte); + + std::vector<Bytecode_Stream::byte> _bytecode; +}; // class Bytecode_Memory +} // namespace ASM +} // namespace SpasmImpl + +#endif // BYTECODE_HPP diff --git a/src/asm/dfa.dot b/src/asm/dfa.dot new file mode 100644 index 0000000..ff38d77 --- /dev/null +++ b/src/asm/dfa.dot @@ -0,0 +1,180 @@ +/* Generated by re2c 0.16 on Thu Oct 11 01:51:09 2018 */ + +digraph re2c { + +1 -> 2 [label="[0x00]"] +1 -> 4 [label="[0x01-0x08][0x0B-0x1F][!-$][&-)][,][.][:-;][=-@][[-^][`][{-0xFF]"] +1 -> 6 [label="[0x09][ ]"] +1 -> 9 [label="[0x0A]"] +1 -> 11 [label="[%]"] +1 -> 13 [label="[*]"] +1 -> 15 [label="[+]"] +1 -> 17 [label="[-]"] +1 -> 19 [label="[/]"] +1 -> 21 [label="[0]"] +1 -> 23 [label="[1-9]"] +1 -> 25 [label="[<]"] +1 -> 27 [label="[A-Z][_][a-b][e-f][h-k][m-o][q][t-z]"] +1 -> 30 [label="[c]"] +1 -> 31 [label="[d]"] +1 -> 32 [label="[g]"] +1 -> 33 [label="[l]"] +1 -> 34 [label="[p]"] +1 -> 35 [label="[r]"] +1 -> 36 [label="[s]"] +2 -> 3 +3 [label="lexer.re:233"] +4 -> 5 +5 [label="lexer.re:239"] +6 -> 7 +7 -> 8 [label="[0x00-0x08][0x0A-0x1F][!-0xFF]"] +7 -> 6 [label="[0x09][ ]"] +8 [label="lexer.re:220"] +9 -> 10 +10 [label="lexer.re:226"] +11 -> 12 +12 [label="lexer.re:137"] +13 -> 14 +14 [label="lexer.re:123"] +15 -> 16 +16 [label="lexer.re:109"] +17 -> 18 [label="[0x00-/][1-0xFF]"] +17 -> 37 [label="[0]"] +18 [label="lexer.re:116"] +19 -> 20 +20 [label="lexer.re:130"] +21 -> 22 [label="[0x00-W][Y-w][y-0xFF]"] +21 -> 38 [label="[X][x]"] +22 [label="lexer.re:58"] +23 -> 24 +24 -> 22 [label="[0x00-/][:-0xFF]"] +24 -> 23 [label="[0-9]"] +25 -> 26 [label="[0x00-<][>-0xFF]"] +25 -> 40 [label="[=]"] +26 [label="lexer.re:198"] +27 -> 28 +28 -> 29 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +28 -> 27 [label="[0-9][A-Z][_][a-z]"] +29 [label="lexer.re:212"] +30 -> 28 [label="[0x00-`][b-0xFF]"] +30 -> 42 [label="[a]"] +31 -> 28 [label="[0x00-t][v-0xFF]"] +31 -> 43 [label="[u]"] +32 -> 28 [label="[0x00-n][p-0xFF]"] +32 -> 44 [label="[o]"] +33 -> 28 [label="[0x00-`][b-n][p-0xFF]"] +33 -> 46 [label="[a]"] +33 -> 47 [label="[o]"] +34 -> 28 [label="[0x00-n][p-q][s-t][v-0xFF]"] +34 -> 48 [label="[o]"] +34 -> 49 [label="[r]"] +34 -> 50 [label="[u]"] +35 -> 28 [label="[0x00-d][f-0xFF]"] +35 -> 51 [label="[e]"] +36 -> 28 [label="[0x00-s][u-0xFF]"] +36 -> 52 [label="[t]"] +37 -> 22 +38 -> 39 [label="[0x00-/][:-@][G-`][g-0xFF]"] +38 -> 53 [label="[0-9][A-F][a-f]"] +39 -> 22 +40 -> 41 +41 [label="lexer.re:192"] +42 -> 28 [label="[0x00-k][m-0xFF]"] +42 -> 56 [label="[l]"] +43 -> 28 [label="[0x00-o][q-0xFF]"] +43 -> 57 [label="[p]"] +44 -> 45 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +44 -> 27 [label="[0-9][A-Z][_][a-e][g-s][u-z]"] +44 -> 59 [label="[f]"] +44 -> 60 [label="[t]"] +45 [label="lexer.re:158"] +46 -> 28 [label="[0x00-a][c-0xFF]"] +46 -> 61 [label="[b]"] +47 -> 28 [label="[0x00-`][b-0xFF]"] +47 -> 62 [label="[a]"] +48 -> 28 [label="[0x00-o][q-0xFF]"] +48 -> 63 [label="[p]"] +49 -> 28 [label="[0x00-h][j-0xFF]"] +49 -> 65 [label="[i]"] +50 -> 28 [label="[0x00-r][t-0xFF]"] +50 -> 66 [label="[s]"] +51 -> 28 [label="[0x00-`][b-s][u-0xFF]"] +51 -> 67 [label="[a]"] +51 -> 68 [label="[t]"] +52 -> 28 [label="[0x00-n][p-0xFF]"] +52 -> 70 [label="[o]"] +53 -> 54 +54 -> 55 [label="[0x00-/][:-@][G-`][g-0xFF]"] +54 -> 53 [label="[0-9][A-F][a-f]"] +55 [label="lexer.re:66"] +56 -> 28 [label="[0x00-k][m-0xFF]"] +56 -> 71 [label="[l]"] +57 -> 58 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +57 -> 27 [label="[0-9][A-Z][_][a-z]"] +58 [label="lexer.re:88"] +59 -> 28 [label="[0x00-`][b-0xFF]"] +59 -> 73 [label="[a]"] +60 -> 28 [label="[0x00-q][s-0xFF]"] +60 -> 74 [label="[r]"] +61 -> 28 [label="[0x00-d][f-0xFF]"] +61 -> 75 [label="[e]"] +62 -> 28 [label="[0x00-c][e-0xFF]"] +62 -> 76 [label="[d]"] +63 -> 64 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +63 -> 27 [label="[0-9][A-Z][_][a-z]"] +64 [label="lexer.re:81"] +65 -> 28 [label="[0x00-m][o-0xFF]"] +65 -> 78 [label="[n]"] +66 -> 28 [label="[0x00-g][i-0xFF]"] +66 -> 79 [label="[h]"] +67 -> 28 [label="[0x00-c][e-0xFF]"] +67 -> 81 [label="[d]"] +68 -> 69 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +68 -> 27 [label="[0-9][A-Z][_][a-z]"] +69 [label="lexer.re:172"] +70 -> 28 [label="[0x00-q][s-0xFF]"] +70 -> 83 [label="[r]"] +71 -> 72 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +71 -> 27 [label="[0-9][A-Z][_][a-z]"] +72 [label="lexer.re:165"] +73 -> 28 [label="[0x00-k][m-0xFF]"] +73 -> 84 [label="[l]"] +74 -> 28 [label="[0x00-t][v-0xFF]"] +74 -> 85 [label="[u]"] +75 -> 28 [label="[0x00-k][m-0xFF]"] +75 -> 86 [label="[l]"] +76 -> 77 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +76 -> 27 [label="[0-9][A-Z][_][a-z]"] +77 [label="lexer.re:179"] +78 -> 28 [label="[0x00-s][u-0xFF]"] +78 -> 88 [label="[t]"] +79 -> 80 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +79 -> 27 [label="[0-9][A-Z][_][a-z]"] +80 [label="lexer.re:74"] +81 -> 82 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +81 -> 27 [label="[0-9][A-Z][_][a-z]"] +82 [label="lexer.re:95"] +83 -> 28 [label="[0x00-d][f-0xFF]"] +83 -> 90 [label="[e]"] +84 -> 28 [label="[0x00-r][t-0xFF]"] +84 -> 92 [label="[s]"] +85 -> 28 [label="[0x00-d][f-0xFF]"] +85 -> 93 [label="[e]"] +86 -> 87 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +86 -> 27 [label="[0-9][A-Z][_][a-z]"] +87 [label="lexer.re:205"] +88 -> 89 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +88 -> 27 [label="[0-9][A-Z][_][a-z]"] +89 [label="lexer.re:102"] +90 -> 91 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +90 -> 27 [label="[0-9][A-Z][_][a-z]"] +91 [label="lexer.re:186"] +92 -> 28 [label="[0x00-d][f-0xFF]"] +92 -> 95 [label="[e]"] +93 -> 94 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +93 -> 27 [label="[0-9][A-Z][_][a-z]"] +94 [label="lexer.re:144"] +95 -> 96 [label="[0x00-/][:-@][[-^][`][{-0xFF]"] +95 -> 27 [label="[0-9][A-Z][_][a-z]"] +96 [label="lexer.re:151"] +} diff --git a/src/asm/dfa.svg b/src/asm/dfa.svg new file mode 100644 index 0000000..0bd3660 --- /dev/null +++ b/src/asm/dfa.svg @@ -0,0 +1,1367 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by graphviz version 2.38.0 (20140413.2041) + --> +<!-- Title: re2c Pages: 1 --> +<svg width="6745pt" height="935pt" + viewBox="0.00 0.00 6745.30 935.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 931)"> +<title>re2c</title> +<polygon fill="white" stroke="none" points="-4,4 -4,-931 6741.3,-931 6741.3,4 -4,4"/> +<!-- 1 --> +<g id="node1" class="node"><title>1</title> +<ellipse fill="none" stroke="black" cx="1178.3" cy="-909" rx="27" ry="18"/> +<text text-anchor="middle" x="1178.3" y="-905.3" font-family="Times,serif" font-size="14.00">1</text> +</g> +<!-- 2 --> +<g id="node2" class="node"><title>2</title> +<ellipse fill="none" stroke="black" cx="81.2953" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="81.2953" y="-818.3" font-family="Times,serif" font-size="14.00">2</text> +</g> +<!-- 1->2 --> +<g id="edge1" class="edge"><title>1->2</title> +<path fill="none" stroke="black" d="M1151.22,-908.173C1014.84,-908.869 402.367,-909.855 216.295,-873 179.175,-865.648 138.741,-849.503 111.898,-837.537"/> +<polygon fill="black" stroke="black" points="113.207,-834.288 102.654,-833.342 110.314,-840.662 113.207,-834.288"/> +<text text-anchor="middle" x="234.795" y="-861.8" font-family="Times,serif" font-size="14.00">[0x00]</text> +</g> +<!-- 4 --> +<g id="node3" class="node"><title>4</title> +<ellipse fill="none" stroke="black" cx="209.295" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="209.295" y="-818.3" font-family="Times,serif" font-size="14.00">4</text> +</g> +<!-- 1->4 --> +<g id="edge2" class="edge"><title>1->4</title> +<path fill="none" stroke="black" d="M1151.28,-907.762C1011.46,-906.419 373.339,-898.904 289.295,-873 269.015,-866.749 248.77,-854.017 233.72,-842.966"/> +<polygon fill="black" stroke="black" points="235.577,-839.981 225.498,-836.715 231.34,-845.554 235.577,-839.981"/> +<text text-anchor="middle" x="469.795" y="-861.8" font-family="Times,serif" font-size="14.00">[0x01-0x08][0x0B-0x1F][!-$][&-)][,][.][:-;][=-@][[-^][`][{-0xFF]</text> +</g> +<!-- 6 --> +<g id="node4" class="node"><title>6</title> +<ellipse fill="none" stroke="black" cx="309.295" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="309.295" y="-818.3" font-family="Times,serif" font-size="14.00">6</text> +</g> +<!-- 1->6 --> +<g id="edge3" class="edge"><title>1->6</title> +<path fill="none" stroke="black" d="M1151.3,-906.62C1082.97,-902.954 897.716,-891.937 744.295,-873 704.049,-868.032 694.579,-862.654 654.295,-858 531.74,-843.841 499.188,-859.038 377.295,-840 366.18,-838.264 354.224,-835.564 343.484,-832.824"/> +<polygon fill="black" stroke="black" points="344.19,-829.39 333.627,-830.214 342.398,-836.157 344.19,-829.39"/> +<text text-anchor="middle" x="768.795" y="-861.8" font-family="Times,serif" font-size="14.00">[0x09][ ]</text> +</g> +<!-- 9 --> +<g id="node5" class="node"><title>9</title> +<ellipse fill="none" stroke="black" cx="413.295" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="413.295" y="-818.3" font-family="Times,serif" font-size="14.00">9</text> +</g> +<!-- 1->9 --> +<g id="edge4" class="edge"><title>1->9</title> +<path fill="none" stroke="black" d="M1151.37,-906.619C1095.18,-903.408 961.494,-894.055 851.295,-873 826.829,-868.325 821.858,-862.138 797.295,-858 671.702,-836.842 637.783,-854.906 511.295,-840 490.555,-837.556 467.54,-833.627 449.028,-830.162"/> +<polygon fill="black" stroke="black" points="449.454,-826.68 438.975,-828.243 448.142,-833.556 449.454,-826.68"/> +<text text-anchor="middle" x="871.295" y="-861.8" font-family="Times,serif" font-size="14.00">[0x0A]</text> +</g> +<!-- 11 --> +<g id="node6" class="node"><title>11</title> +<ellipse fill="none" stroke="black" cx="547.295" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="547.295" y="-818.3" font-family="Times,serif" font-size="14.00">11</text> +</g> +<!-- 1->11 --> +<g id="edge5" class="edge"><title>1->11</title> +<path fill="none" stroke="black" d="M1151.29,-906.318C1105.54,-902.991 1010.19,-893.991 932.295,-873 915.162,-868.383 912.594,-861.951 895.295,-858 773.293,-830.133 737.916,-859.472 614.295,-840 603.425,-838.288 591.746,-835.621 581.233,-832.903"/> +<polygon fill="black" stroke="black" points="582.139,-829.523 571.574,-830.312 580.325,-836.284 582.139,-829.523"/> +<text text-anchor="middle" x="943.295" y="-861.8" font-family="Times,serif" font-size="14.00">[%]</text> +</g> +<!-- 13 --> +<g id="node7" class="node"><title>13</title> +<ellipse fill="none" stroke="black" cx="650.295" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="650.295" y="-818.3" font-family="Times,serif" font-size="14.00">13</text> +</g> +<!-- 1->13 --> +<g id="edge6" class="edge"><title>1->13</title> +<path fill="none" stroke="black" d="M1151.54,-905.771C1113.82,-902.041 1043.23,-892.889 986.295,-873 972.967,-868.344 971.832,-862.008 958.295,-858 866.776,-830.902 838.919,-852.507 744.295,-840 724.779,-837.42 703.151,-833.578 685.566,-830.198"/> +<polygon fill="black" stroke="black" points="686.212,-826.758 675.726,-828.275 684.869,-833.629 686.212,-826.758"/> +<text text-anchor="middle" x="994.295" y="-861.8" font-family="Times,serif" font-size="14.00">[*]</text> +</g> +<!-- 15 --> +<g id="node8" class="node"><title>15</title> +<ellipse fill="none" stroke="black" cx="780.295" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="780.295" y="-818.3" font-family="Times,serif" font-size="14.00">15</text> +</g> +<!-- 1->15 --> +<g id="edge7" class="edge"><title>1->15</title> +<path fill="none" stroke="black" d="M1151.89,-904.84C1121.17,-900.493 1069.43,-891.065 1028.3,-873 1017.46,-868.241 1017.39,-862.12 1006.3,-858 939.626,-833.242 917.257,-852.775 847.295,-840 836.582,-838.044 825.045,-835.338 814.614,-832.66"/> +<polygon fill="black" stroke="black" points="815.186,-829.191 804.623,-830.021 813.397,-835.959 815.186,-829.191"/> +<text text-anchor="middle" x="1037.3" y="-861.8" font-family="Times,serif" font-size="14.00">[+]</text> +</g> +<!-- 17 --> +<g id="node9" class="node"><title>17</title> +<ellipse fill="none" stroke="black" cx="883.295" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="883.295" y="-818.3" font-family="Times,serif" font-size="14.00">17</text> +</g> +<!-- 1->17 --> +<g id="edge8" class="edge"><title>1->17</title> +<path fill="none" stroke="black" d="M1155.44,-899.339C1137.01,-892.324 1110.44,-882.141 1087.3,-873 1070.79,-866.481 1067.27,-863.174 1050.3,-858 1006,-844.497 953.527,-834.434 919.384,-828.645"/> +<polygon fill="black" stroke="black" points="919.844,-825.173 909.405,-826.986 918.696,-832.079 919.844,-825.173"/> +<text text-anchor="middle" x="1094.3" y="-861.8" font-family="Times,serif" font-size="14.00">[-]</text> +</g> +<!-- 19 --> +<g id="node10" class="node"><title>19</title> +<ellipse fill="none" stroke="black" cx="1217.3" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="1217.3" y="-818.3" font-family="Times,serif" font-size="14.00">19</text> +</g> +<!-- 1->19 --> +<g id="edge9" class="edge"><title>1->19</title> +<path fill="none" stroke="black" d="M1185.81,-891.611C1191.43,-879.382 1199.2,-862.443 1205.62,-848.456"/> +<polygon fill="black" stroke="black" points="1208.81,-849.887 1209.8,-839.339 1202.45,-846.968 1208.81,-849.887"/> +<text text-anchor="middle" x="1206.8" y="-861.8" font-family="Times,serif" font-size="14.00">[/]</text> +</g> +<!-- 21 --> +<g id="node11" class="node"><title>21</title> +<ellipse fill="none" stroke="black" cx="1047.3" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="1047.3" y="-818.3" font-family="Times,serif" font-size="14.00">21</text> +</g> +<!-- 1->21 --> +<g id="edge10" class="edge"><title>1->21</title> +<path fill="none" stroke="black" d="M1159.53,-895.822C1137.25,-881.367 1099.93,-857.149 1074.49,-840.644"/> +<polygon fill="black" stroke="black" points="1076.32,-837.663 1066.03,-835.156 1072.51,-843.535 1076.32,-837.663"/> +<text text-anchor="middle" x="1129.3" y="-861.8" font-family="Times,serif" font-size="14.00">[0]</text> +</g> +<!-- 23 --> +<g id="node12" class="node"><title>23</title> +<ellipse fill="none" stroke="black" cx="1145.3" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="1145.3" y="-818.3" font-family="Times,serif" font-size="14.00">23</text> +</g> +<!-- 1->23 --> +<g id="edge11" class="edge"><title>1->23</title> +<path fill="none" stroke="black" d="M1167.39,-892.157C1163.77,-886.335 1159.98,-879.56 1157.3,-873 1154.32,-865.728 1151.98,-857.547 1150.18,-849.942"/> +<polygon fill="black" stroke="black" points="1153.58,-849.108 1148.05,-840.067 1146.73,-850.579 1153.58,-849.108"/> +<text text-anchor="middle" x="1171.3" y="-861.8" font-family="Times,serif" font-size="14.00">[1-9]</text> +</g> +<!-- 25 --> +<g id="node13" class="node"><title>25</title> +<ellipse fill="none" stroke="black" cx="1329.3" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="1329.3" y="-818.3" font-family="Times,serif" font-size="14.00">25</text> +</g> +<!-- 1->25 --> +<g id="edge12" class="edge"><title>1->25</title> +<path fill="none" stroke="black" d="M1198.35,-896.713C1224.52,-881.979 1270.51,-856.093 1300.43,-839.249"/> +<polygon fill="black" stroke="black" points="1302.16,-842.289 1309.16,-834.334 1298.73,-836.189 1302.16,-842.289"/> +<text text-anchor="middle" x="1272.3" y="-861.8" font-family="Times,serif" font-size="14.00">[<]</text> +</g> +<!-- 27 --> +<g id="node14" class="node"><title>27</title> +<ellipse fill="none" stroke="black" cx="4018.3" cy="-192" rx="27" ry="18"/> +<text text-anchor="middle" x="4018.3" y="-188.3" font-family="Times,serif" font-size="14.00">27</text> +</g> +<!-- 1->27 --> +<g id="edge13" class="edge"><title>1->27</title> +<path fill="none" stroke="black" d="M1205.53,-907.928C1496.58,-907.07 4022.3,-897.481 4022.3,-823 4022.3,-823 4022.3,-823 4022.3,-321.5 4022.3,-279.944 4024.66,-269.488 4022.3,-228 4022.15,-225.435 4021.94,-222.77 4021.7,-220.107"/> +<polygon fill="black" stroke="black" points="4025.17,-219.633 4020.64,-210.056 4018.21,-220.369 4025.17,-219.633"/> +<text text-anchor="middle" x="4120.3" y="-536.3" font-family="Times,serif" font-size="14.00">[A-Z][_][a-b][e-f][h-k][m-o][q][t-z]</text> +</g> +<!-- 30 --> +<g id="node15" class="node"><title>30</title> +<ellipse fill="none" stroke="black" cx="4692.3" cy="-540" rx="27" ry="18"/> +<text text-anchor="middle" x="4692.3" y="-536.3" font-family="Times,serif" font-size="14.00">30</text> +</g> +<!-- 1->30 --> +<g id="edge14" class="edge"><title>1->30</title> +<path fill="none" stroke="black" d="M1205.28,-907.899C1483.81,-906.83 3830.81,-897.135 4139.3,-873 4293.32,-860.949 4483.3,-977.495 4483.3,-823 4483.3,-823 4483.3,-823 4483.3,-626 4483.3,-552.835 4594.56,-541.186 4654.72,-540.235"/> +<polygon fill="black" stroke="black" points="4655,-543.734 4664.97,-540.169 4654.95,-536.734 4655,-543.734"/> +<text text-anchor="middle" x="4491.3" y="-731.3" font-family="Times,serif" font-size="14.00">[c]</text> +</g> +<!-- 31 --> +<g id="node16" class="node"><title>31</title> +<ellipse fill="none" stroke="black" cx="1710.3" cy="-453" rx="27" ry="18"/> +<text text-anchor="middle" x="1710.3" y="-449.3" font-family="Times,serif" font-size="14.00">31</text> +</g> +<!-- 1->31 --> +<g id="edge15" class="edge"><title>1->31</title> +<path fill="none" stroke="black" d="M1205.07,-906.11C1305.95,-898.639 1657.3,-869.294 1657.3,-823 1657.3,-823 1657.3,-823 1657.3,-539 1657.3,-514.713 1673.07,-491.628 1687.41,-475.662"/> +<polygon fill="black" stroke="black" points="1690.34,-477.657 1694.68,-467.993 1685.26,-472.839 1690.34,-477.657"/> +<text text-anchor="middle" x="1665.3" y="-677.3" font-family="Times,serif" font-size="14.00">[d]</text> +</g> +<!-- 32 --> +<g id="node17" class="node"><title>32</title> +<ellipse fill="none" stroke="black" cx="1512.3" cy="-822" rx="27" ry="18"/> +<text text-anchor="middle" x="1512.3" y="-818.3" font-family="Times,serif" font-size="14.00">32</text> +</g> +<!-- 1->32 --> +<g id="edge16" class="edge"><title>1->32</title> +<path fill="none" stroke="black" d="M1203.13,-901.681C1261.94,-886.713 1409.87,-849.066 1477.54,-831.846"/> +<polygon fill="black" stroke="black" points="1478.47,-835.219 1487.3,-829.361 1476.75,-828.435 1478.47,-835.219"/> +<text text-anchor="middle" x="1373.3" y="-861.8" font-family="Times,serif" font-size="14.00">[g]</text> +</g> +<!-- 33 --> +<g id="node18" class="node"><title>33</title> +<ellipse fill="none" stroke="black" cx="5282.3" cy="-627" rx="27" ry="18"/> +<text text-anchor="middle" x="5282.3" y="-623.3" font-family="Times,serif" font-size="14.00">33</text> +</g> +<!-- 1->33 --> +<g id="edge17" class="edge"><title>1->33</title> +<path fill="none" stroke="black" d="M1205.44,-907.941C1512.55,-907.249 4325.11,-900.175 4497.3,-873 4799.56,-825.296 5145.96,-685.73 5250.7,-641.565"/> +<polygon fill="black" stroke="black" points="5252.23,-644.718 5260.08,-637.595 5249.5,-638.273 5252.23,-644.718"/> +<text text-anchor="middle" x="4904.8" y="-774.8" font-family="Times,serif" font-size="14.00">[l]</text> +</g> +<!-- 34 --> +<g id="node19" class="node"><title>34</title> +<ellipse fill="none" stroke="black" cx="2838.3" cy="-627" rx="27" ry="18"/> +<text text-anchor="middle" x="2838.3" y="-623.3" font-family="Times,serif" font-size="14.00">34</text> +</g> +<!-- 1->34 --> +<g id="edge18" class="edge"><title>1->34</title> +<path fill="none" stroke="black" d="M1205.42,-907.369C1280.07,-905.354 1494.75,-897.682 1671.3,-873 2123.84,-809.731 2663.57,-673.429 2803.71,-637.069"/> +<polygon fill="black" stroke="black" points="2804.67,-640.434 2813.47,-634.53 2802.91,-633.66 2804.67,-640.434"/> +<text text-anchor="middle" x="2235.3" y="-774.8" font-family="Times,serif" font-size="14.00">[p]</text> +</g> +<!-- 35 --> +<g id="node20" class="node"><title>35</title> +<ellipse fill="none" stroke="black" cx="4380.3" cy="-540" rx="27" ry="18"/> +<text text-anchor="middle" x="4380.3" y="-536.3" font-family="Times,serif" font-size="14.00">35</text> +</g> +<!-- 1->35 --> +<g id="edge19" class="edge"><title>1->35</title> +<path fill="none" stroke="black" d="M1205.63,-908.077C1480.46,-908.797 3740.86,-913.457 4036.3,-873 4121.96,-861.27 4224.3,-909.46 4224.3,-823 4224.3,-823 4224.3,-823 4224.3,-626 4224.3,-571.949 4297.4,-552.068 4343.52,-544.903"/> +<polygon fill="black" stroke="black" points="4344.07,-548.36 4353.48,-543.486 4343.08,-541.43 4344.07,-548.36"/> +<text text-anchor="middle" x="4231.3" y="-731.3" font-family="Times,serif" font-size="14.00">[r]</text> +</g> +<!-- 36 --> +<g id="node21" class="node"><title>36</title> +<ellipse fill="none" stroke="black" cx="6491.3" cy="-627" rx="27" ry="18"/> +<text text-anchor="middle" x="6491.3" y="-623.3" font-family="Times,serif" font-size="14.00">36</text> +</g> +<!-- 1->36 --> +<g id="edge20" class="edge"><title>1->36</title> +<path fill="none" stroke="black" d="M1205.65,-907.908C1506.63,-906.875 4196.57,-897.001 4549.3,-873 5323.74,-820.304 6262.28,-666.589 6455.5,-634.082"/> +<polygon fill="black" stroke="black" points="6456.13,-637.527 6465.41,-632.413 6454.96,-630.624 6456.13,-637.527"/> +<text text-anchor="middle" x="5537.8" y="-774.8" font-family="Times,serif" font-size="14.00">[s]</text> +</g> +<!-- 3 --> +<g id="node22" class="node"><title>3</title> +<ellipse fill="none" stroke="black" cx="53.2953" cy="-735" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="53.2953" y="-731.3" font-family="Times,serif" font-size="14.00">lexer.re:233</text> +</g> +<!-- 2->3 --> +<g id="edge21" class="edge"><title>2->3</title> +<path fill="none" stroke="black" d="M75.7634,-804.207C71.8771,-792.409 66.5963,-776.378 62.1308,-762.822"/> +<polygon fill="black" stroke="black" points="65.3646,-761.452 58.9115,-753.049 58.716,-763.642 65.3646,-761.452"/> +</g> +<!-- 5 --> +<g id="node23" class="node"><title>5</title> +<ellipse fill="none" stroke="black" cx="178.295" cy="-735" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="178.295" y="-731.3" font-family="Times,serif" font-size="14.00">lexer.re:239</text> +</g> +<!-- 4->5 --> +<g id="edge22" class="edge"><title>4->5</title> +<path fill="none" stroke="black" d="M203.171,-804.207C198.868,-792.409 193.021,-776.378 188.077,-762.822"/> +<polygon fill="black" stroke="black" points="191.228,-761.245 184.513,-753.049 184.651,-763.643 191.228,-761.245"/> +</g> +<!-- 7 --> +<g id="node24" class="node"><title>7</title> +<ellipse fill="none" stroke="black" cx="276.295" cy="-735" rx="27" ry="18"/> +<text text-anchor="middle" x="276.295" y="-731.3" font-family="Times,serif" font-size="14.00">7</text> +</g> +<!-- 6->7 --> +<g id="edge23" class="edge"><title>6->7</title> +<path fill="none" stroke="black" d="M299.622,-804.987C296.36,-799.15 292.893,-792.407 290.295,-786 287.315,-778.649 284.729,-770.443 282.619,-762.839"/> +<polygon fill="black" stroke="black" points="285.957,-761.771 280.044,-752.98 279.185,-763.54 285.957,-761.771"/> +</g> +<!-- 10 --> +<g id="node26" class="node"><title>10</title> +<ellipse fill="none" stroke="black" cx="374.295" cy="-735" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="374.295" y="-731.3" font-family="Times,serif" font-size="14.00">lexer.re:226</text> +</g> +<!-- 9->10 --> +<g id="edge26" class="edge"><title>9->10</title> +<path fill="none" stroke="black" d="M405.776,-804.611C400.29,-792.655 392.738,-776.196 386.407,-762.397"/> +<polygon fill="black" stroke="black" points="389.41,-760.55 382.059,-752.92 383.048,-763.469 389.41,-760.55"/> +</g> +<!-- 12 --> +<g id="node27" class="node"><title>12</title> +<ellipse fill="none" stroke="black" cx="499.295" cy="-735" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="499.295" y="-731.3" font-family="Times,serif" font-size="14.00">lexer.re:137</text> +</g> +<!-- 11->12 --> +<g id="edge27" class="edge"><title>11->12</title> +<path fill="none" stroke="black" d="M538.267,-805.012C531.361,-792.783 521.701,-775.677 513.727,-761.556"/> +<polygon fill="black" stroke="black" points="516.741,-759.775 508.776,-752.789 510.645,-763.217 516.741,-759.775"/> +</g> +<!-- 14 --> +<g id="node28" class="node"><title>14</title> +<ellipse fill="none" stroke="black" cx="624.295" cy="-735" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="624.295" y="-731.3" font-family="Times,serif" font-size="14.00">lexer.re:123</text> +</g> +<!-- 13->14 --> +<g id="edge28" class="edge"><title>13->14</title> +<path fill="none" stroke="black" d="M645.159,-804.207C641.55,-792.409 636.646,-776.378 632.5,-762.822"/> +<polygon fill="black" stroke="black" points="635.782,-761.588 629.51,-753.049 629.089,-763.636 635.782,-761.588"/> +</g> +<!-- 16 --> +<g id="node29" class="node"><title>16</title> +<ellipse fill="none" stroke="black" cx="749.295" cy="-735" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="749.295" y="-731.3" font-family="Times,serif" font-size="14.00">lexer.re:109</text> +</g> +<!-- 15->16 --> +<g id="edge29" class="edge"><title>15->16</title> +<path fill="none" stroke="black" d="M774.171,-804.207C769.868,-792.409 764.021,-776.378 759.077,-762.822"/> +<polygon fill="black" stroke="black" points="762.228,-761.245 755.513,-753.049 755.651,-763.643 762.228,-761.245"/> +</g> +<!-- 18 --> +<g id="node30" class="node"><title>18</title> +<ellipse fill="none" stroke="black" cx="911.295" cy="-735" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="911.295" y="-731.3" font-family="Times,serif" font-size="14.00">lexer.re:116</text> +</g> +<!-- 17->18 --> +<g id="edge30" class="edge"><title>17->18</title> +<path fill="none" stroke="black" d="M881.027,-803.862C880.354,-793.983 880.604,-781.483 884.295,-771 885.541,-767.462 887.295,-763.999 889.318,-760.712"/> +<polygon fill="black" stroke="black" points="892.218,-762.674 895.137,-752.489 886.504,-758.63 892.218,-762.674"/> +<text text-anchor="middle" x="931.295" y="-774.8" font-family="Times,serif" font-size="14.00">[0x00-/][1-0xFF]</text> +</g> +<!-- 37 --> +<g id="node31" class="node"><title>37</title> +<ellipse fill="none" stroke="black" cx="673.295" cy="-681" rx="27" ry="18"/> +<text text-anchor="middle" x="673.295" y="-677.3" font-family="Times,serif" font-size="14.00">37</text> +</g> +<!-- 17->37 --> +<g id="edge31" class="edge"><title>17->37</title> +<path fill="none" stroke="black" d="M873.162,-804.942C855.496,-777.172 820.1,-722.593 811.295,-717 770.591,-691.141 749.852,-714.815 704.295,-699 703.433,-698.701 702.566,-698.379 701.698,-698.038"/> +<polygon fill="black" stroke="black" points="703.064,-694.814 692.516,-693.824 700.145,-701.176 703.064,-694.814"/> +<text text-anchor="middle" x="868.295" y="-774.8" font-family="Times,serif" font-size="14.00">[0]</text> +</g> +<!-- 20 --> +<g id="node32" class="node"><title>20</title> +<ellipse fill="none" stroke="black" cx="1217.3" cy="-735" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="1217.3" y="-731.3" font-family="Times,serif" font-size="14.00">lexer.re:130</text> +</g> +<!-- 19->20 --> +<g id="edge32" class="edge"><title>19->20</title> +<path fill="none" stroke="black" d="M1217.3,-803.799C1217.3,-792.163 1217.3,-776.548 1217.3,-763.237"/> +<polygon fill="black" stroke="black" points="1220.8,-763.175 1217.3,-753.175 1213.8,-763.175 1220.8,-763.175"/> +</g> +<!-- 22 --> +<g id="node33" class="node"><title>22</title> +<ellipse fill="none" stroke="black" cx="749.295" cy="-540" rx="48.9926" ry="18"/> +<text text-anchor="middle" x="749.295" y="-536.3" font-family="Times,serif" font-size="14.00">lexer.re:58</text> +</g> +<!-- 21->22 --> +<g id="edge33" class="edge"><title>21->22</title> +<path fill="none" stroke="black" d="M1038,-804.619C1022.52,-777.965 991.358,-727.15 973.295,-717 924.545,-689.604 760.397,-739.932 722.295,-699 688.846,-663.066 714.319,-601.626 733.391,-566.898"/> +<polygon fill="black" stroke="black" points="736.634,-568.275 738.546,-557.854 730.553,-564.809 736.634,-568.275"/> +<text text-anchor="middle" x="790.295" y="-677.3" font-family="Times,serif" font-size="14.00">[0x00-W][Y-w][y-0xFF]</text> +</g> +<!-- 38 --> +<g id="node34" class="node"><title>38</title> +<ellipse fill="none" stroke="black" cx="1047.3" cy="-735" rx="27" ry="18"/> +<text text-anchor="middle" x="1047.3" y="-731.3" font-family="Times,serif" font-size="14.00">38</text> +</g> +<!-- 21->38 --> +<g id="edge34" class="edge"><title>21->38</title> +<path fill="none" stroke="black" d="M1047.3,-803.799C1047.3,-792.163 1047.3,-776.548 1047.3,-763.237"/> +<polygon fill="black" stroke="black" points="1050.8,-763.175 1047.3,-753.175 1043.8,-763.175 1050.8,-763.175"/> +<text text-anchor="middle" x="1064.8" y="-774.8" font-family="Times,serif" font-size="14.00">[X][x]</text> +</g> +<!-- 24 --> +<g id="node35" class="node"><title>24</title> +<ellipse fill="none" stroke="black" cx="1119.3" cy="-735" rx="27" ry="18"/> +<text text-anchor="middle" x="1119.3" y="-731.3" font-family="Times,serif" font-size="14.00">24</text> +</g> +<!-- 23->24 --> +<g id="edge35" class="edge"><title>23->24</title> +<path fill="none" stroke="black" d="M1136.84,-804.579C1134.13,-798.818 1131.31,-792.229 1129.3,-786 1126.96,-778.787 1125.07,-770.805 1123.58,-763.375"/> +<polygon fill="black" stroke="black" points="1127,-762.583 1121.75,-753.376 1120.11,-763.843 1127,-762.583"/> +</g> +<!-- 26 --> +<g id="node36" class="node"><title>26</title> +<ellipse fill="none" stroke="black" cx="1342.3" cy="-735" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="1342.3" y="-731.3" font-family="Times,serif" font-size="14.00">lexer.re:198</text> +</g> +<!-- 25->26 --> +<g id="edge38" class="edge"><title>25->26</title> +<path fill="none" stroke="black" d="M1328.33,-803.748C1328.12,-794.053 1328.39,-781.772 1330.3,-771 1330.77,-768.306 1331.42,-765.539 1332.18,-762.799"/> +<polygon fill="black" stroke="black" points="1335.54,-763.756 1335.22,-753.166 1328.87,-761.643 1335.54,-763.756"/> +<text text-anchor="middle" x="1380.3" y="-774.8" font-family="Times,serif" font-size="14.00">[0x00-<][>-0xFF]</text> +</g> +<!-- 40 --> +<g id="node37" class="node"><title>40</title> +<ellipse fill="none" stroke="black" cx="1440.3" cy="-735" rx="27" ry="18"/> +<text text-anchor="middle" x="1440.3" y="-731.3" font-family="Times,serif" font-size="14.00">40</text> +</g> +<!-- 25->40 --> +<g id="edge39" class="edge"><title>25->40</title> +<path fill="none" stroke="black" d="M1356.12,-818.953C1379.2,-815.719 1411.63,-807.397 1430.3,-786 1435.78,-779.715 1438.58,-771.283 1439.93,-763.136"/> +<polygon fill="black" stroke="black" points="1443.42,-763.459 1440.96,-753.153 1436.45,-762.741 1443.42,-763.459"/> +<text text-anchor="middle" x="1447.3" y="-774.8" font-family="Times,serif" font-size="14.00">[=]</text> +</g> +<!-- 28 --> +<g id="node38" class="node"><title>28</title> +<ellipse fill="none" stroke="black" cx="3985.3" cy="-105" rx="27" ry="18"/> +<text text-anchor="middle" x="3985.3" y="-101.3" font-family="Times,serif" font-size="14.00">28</text> +</g> +<!-- 27->28 --> +<g id="edge40" class="edge"><title>27->28</title> +<path fill="none" stroke="black" d="M4008.62,-174.987C4005.36,-169.15 4001.89,-162.407 3999.3,-156 3996.31,-148.649 3993.73,-140.443 3991.62,-132.839"/> +<polygon fill="black" stroke="black" points="3994.96,-131.771 3989.04,-122.98 3988.18,-133.54 3994.96,-131.771"/> +</g> +<!-- 30->28 --> +<g id="edge43" class="edge"><title>30->28</title> +<path fill="none" stroke="black" d="M4692.3,-521.744C4692.3,-504.57 4692.3,-477.464 4692.3,-454 4692.3,-454 4692.3,-454 4692.3,-191 4692.3,-122.931 4169.02,-109.072 4022.83,-106.528"/> +<polygon fill="black" stroke="black" points="4022.63,-103.024 4012.58,-106.357 4022.52,-110.023 4022.63,-103.024"/> +<text text-anchor="middle" x="4739.3" y="-318.8" font-family="Times,serif" font-size="14.00">[0x00-`][b-0xFF]</text> +</g> +<!-- 42 --> +<g id="node40" class="node"><title>42</title> +<ellipse fill="none" stroke="black" cx="4860.3" cy="-453" rx="27" ry="18"/> +<text text-anchor="middle" x="4860.3" y="-449.3" font-family="Times,serif" font-size="14.00">42</text> +</g> +<!-- 30->42 --> +<g id="edge44" class="edge"><title>30->42</title> +<path fill="none" stroke="black" d="M4713.23,-528.407C4742.74,-513.477 4796.71,-486.17 4830.42,-469.113"/> +<polygon fill="black" stroke="black" points="4832.02,-472.231 4839.36,-464.593 4828.86,-465.985 4832.02,-472.231"/> +<text text-anchor="middle" x="4794.3" y="-492.8" font-family="Times,serif" font-size="14.00">[a]</text> +</g> +<!-- 31->28 --> +<g id="edge45" class="edge"><title>31->28</title> +<path fill="none" stroke="black" d="M1708.17,-434.885C1703.39,-393.686 1693.46,-290.241 1710.3,-261 1718.24,-247.193 1729.28,-253.462 1741.3,-243 1770.66,-217.428 1766.32,-200.022 1795.3,-174 1815.94,-155.458 1821.68,-148.845 1848.3,-141 1953,-110.136 3671.42,-106.44 3947.89,-106.044"/> +<polygon fill="black" stroke="black" points="3948.19,-109.544 3958.19,-106.03 3948.18,-102.544 3948.19,-109.544"/> +<text text-anchor="middle" x="1757.3" y="-275.3" font-family="Times,serif" font-size="14.00">[0x00-t][v-0xFF]</text> +</g> +<!-- 43 --> +<g id="node41" class="node"><title>43</title> +<ellipse fill="none" stroke="black" cx="1832.3" cy="-366" rx="27" ry="18"/> +<text text-anchor="middle" x="1832.3" y="-362.3" font-family="Times,serif" font-size="14.00">43</text> +</g> +<!-- 31->43 --> +<g id="edge46" class="edge"><title>31->43</title> +<path fill="none" stroke="black" d="M1728.3,-439.458C1748.75,-425.208 1782.33,-401.815 1805.78,-385.476"/> +<polygon fill="black" stroke="black" points="1808.02,-388.182 1814.22,-379.593 1804.01,-382.438 1808.02,-388.182"/> +<text text-anchor="middle" x="1787.3" y="-405.8" font-family="Times,serif" font-size="14.00">[u]</text> +</g> +<!-- 32->28 --> +<g id="edge47" class="edge"><title>32->28</title> +<path fill="none" stroke="black" d="M1528.2,-807.408C1544.45,-791.929 1567.3,-765.002 1567.3,-736 1567.3,-736 1567.3,-736 1567.3,-408.5 1567.3,-304.269 1495.63,-252.412 1564.3,-174 1637.55,-90.3493 1701.41,-149.243 1812.3,-141 2251.63,-108.343 3697.59,-106.142 3948.14,-106.007"/> +<polygon fill="black" stroke="black" points="3948.19,-109.507 3958.19,-106.002 3948.18,-102.507 3948.19,-109.507"/> +<text text-anchor="middle" x="1615.8" y="-449.3" font-family="Times,serif" font-size="14.00">[0x00-n][p-0xFF]</text> +</g> +<!-- 44 --> +<g id="node42" class="node"><title>44</title> +<ellipse fill="none" stroke="black" cx="1512.3" cy="-735" rx="27" ry="18"/> +<text text-anchor="middle" x="1512.3" y="-731.3" font-family="Times,serif" font-size="14.00">44</text> +</g> +<!-- 32->44 --> +<g id="edge48" class="edge"><title>32->44</title> +<path fill="none" stroke="black" d="M1512.3,-803.799C1512.3,-792.163 1512.3,-776.548 1512.3,-763.237"/> +<polygon fill="black" stroke="black" points="1515.8,-763.175 1512.3,-753.175 1508.8,-763.175 1515.8,-763.175"/> +<text text-anchor="middle" x="1520.3" y="-774.8" font-family="Times,serif" font-size="14.00">[o]</text> +</g> +<!-- 33->28 --> +<g id="edge49" class="edge"><title>33->28</title> +<path fill="none" stroke="black" d="M5258.06,-618.871C5226.22,-607.838 5174.3,-583.353 5174.3,-541 5174.3,-541 5174.3,-541 5174.3,-191 5174.3,-167.746 5150.58,-164.918 4917.3,-141 4571.01,-105.496 4149.06,-104.94 4022.73,-105.673"/> +<polygon fill="black" stroke="black" points="4022.43,-102.175 4012.45,-105.74 4022.47,-109.175 4022.43,-102.175"/> +<text text-anchor="middle" x="5234.8" y="-362.3" font-family="Times,serif" font-size="14.00">[0x00-`][b-n][p-0xFF]</text> +</g> +<!-- 46 --> +<g id="node43" class="node"><title>46</title> +<ellipse fill="none" stroke="black" cx="5573.3" cy="-540" rx="27" ry="18"/> +<text text-anchor="middle" x="5573.3" y="-536.3" font-family="Times,serif" font-size="14.00">46</text> +</g> +<!-- 33->46 --> +<g id="edge50" class="edge"><title>33->46</title> +<path fill="none" stroke="black" d="M5306.61,-618.899C5358.39,-603.774 5479.68,-568.345 5539.17,-550.968"/> +<polygon fill="black" stroke="black" points="5540.23,-554.304 5548.85,-548.14 5538.27,-547.585 5540.23,-554.304"/> +<text text-anchor="middle" x="5452.3" y="-579.8" font-family="Times,serif" font-size="14.00">[a]</text> +</g> +<!-- 47 --> +<g id="node44" class="node"><title>47</title> +<ellipse fill="none" stroke="black" cx="5982.3" cy="-453" rx="27" ry="18"/> +<text text-anchor="middle" x="5982.3" y="-449.3" font-family="Times,serif" font-size="14.00">47</text> +</g> +<!-- 33->47 --> +<g id="edge51" class="edge"><title>33->47</title> +<path fill="none" stroke="black" d="M5307.97,-621.345C5343.26,-614.882 5408.72,-602.665 5464.3,-591 5528.98,-577.424 5545.22,-574.213 5609.3,-558 5734.88,-526.222 5882.73,-483.36 5948.18,-464.105"/> +<polygon fill="black" stroke="black" points="5949.36,-467.407 5957.96,-461.222 5947.38,-460.692 5949.36,-467.407"/> +<text text-anchor="middle" x="5748.3" y="-536.3" font-family="Times,serif" font-size="14.00">[o]</text> +</g> +<!-- 34->28 --> +<g id="edge52" class="edge"><title>34->28</title> +<path fill="none" stroke="black" d="M2811.23,-625.003C2657.44,-619.16 1900.3,-588.01 1900.3,-541 1900.3,-541 1900.3,-541 1900.3,-191 1900.3,-148.465 1817.43,-167.637 2162.3,-141 2527.54,-112.789 3722.48,-106.98 3948.3,-106.126"/> +<polygon fill="black" stroke="black" points="3948.32,-109.626 3958.31,-106.089 3948.3,-102.626 3948.32,-109.626"/> +<text text-anchor="middle" x="1973.3" y="-362.3" font-family="Times,serif" font-size="14.00">[0x00-n][p-q][s-t][v-0xFF]</text> +</g> +<!-- 48 --> +<g id="node45" class="node"><title>48</title> +<ellipse fill="none" stroke="black" cx="2838.3" cy="-366" rx="27" ry="18"/> +<text text-anchor="middle" x="2838.3" y="-362.3" font-family="Times,serif" font-size="14.00">48</text> +</g> +<!-- 34->48 --> +<g id="edge53" class="edge"><title>34->48</title> +<path fill="none" stroke="black" d="M2838.3,-608.604C2838.3,-564.462 2838.3,-447.829 2838.3,-394.415"/> +<polygon fill="black" stroke="black" points="2841.8,-394.32 2838.3,-384.32 2834.8,-394.32 2841.8,-394.32"/> +<text text-anchor="middle" x="2846.3" y="-492.8" font-family="Times,serif" font-size="14.00">[o]</text> +</g> +<!-- 49 --> +<g id="node46" class="node"><title>49</title> +<ellipse fill="none" stroke="black" cx="2223.3" cy="-540" rx="27" ry="18"/> +<text text-anchor="middle" x="2223.3" y="-536.3" font-family="Times,serif" font-size="14.00">49</text> +</g> +<!-- 34->49 --> +<g id="edge54" class="edge"><title>34->49</title> +<path fill="none" stroke="black" d="M2811.87,-622.348C2714.09,-608.834 2372.67,-561.645 2259.81,-546.047"/> +<polygon fill="black" stroke="black" points="2260.01,-542.541 2249.62,-544.639 2259.05,-549.475 2260.01,-542.541"/> +<text text-anchor="middle" x="2575.3" y="-579.8" font-family="Times,serif" font-size="14.00">[r]</text> +</g> +<!-- 50 --> +<g id="node47" class="node"><title>50</title> +<ellipse fill="none" stroke="black" cx="3260.3" cy="-453" rx="27" ry="18"/> +<text text-anchor="middle" x="3260.3" y="-449.3" font-family="Times,serif" font-size="14.00">50</text> +</g> +<!-- 34->50 --> +<g id="edge55" class="edge"><title>34->50</title> +<path fill="none" stroke="black" d="M2860.69,-616.874C2930.85,-588.277 3146.62,-500.334 3228.41,-466.996"/> +<polygon fill="black" stroke="black" points="3229.76,-470.224 3237.7,-463.208 3227.12,-463.742 3229.76,-470.224"/> +<text text-anchor="middle" x="3099.3" y="-536.3" font-family="Times,serif" font-size="14.00">[u]</text> +</g> +<!-- 35->28 --> +<g id="edge56" class="edge"><title>35->28</title> +<path fill="none" stroke="black" d="M4395.6,-524.924C4447.24,-476.681 4610.13,-317.86 4580.3,-261 4576.34,-253.468 4462.05,-177.491 4454.3,-174 4398.36,-148.829 4380.72,-151.545 4320.3,-141 4213.02,-122.278 4084.54,-112.273 4022.48,-108.21"/> +<polygon fill="black" stroke="black" points="4022.59,-104.711 4012.39,-107.564 4022.15,-111.696 4022.59,-104.711"/> +<text text-anchor="middle" x="4620.3" y="-318.8" font-family="Times,serif" font-size="14.00">[0x00-d][f-0xFF]</text> +</g> +<!-- 51 --> +<g id="node48" class="node"><title>51</title> +<ellipse fill="none" stroke="black" cx="4380.3" cy="-453" rx="27" ry="18"/> +<text text-anchor="middle" x="4380.3" y="-449.3" font-family="Times,serif" font-size="14.00">51</text> +</g> +<!-- 35->51 --> +<g id="edge57" class="edge"><title>35->51</title> +<path fill="none" stroke="black" d="M4380.3,-521.799C4380.3,-510.163 4380.3,-494.548 4380.3,-481.237"/> +<polygon fill="black" stroke="black" points="4383.8,-481.175 4380.3,-471.175 4376.8,-481.175 4383.8,-481.175"/> +<text text-anchor="middle" x="4388.3" y="-492.8" font-family="Times,serif" font-size="14.00">[e]</text> +</g> +<!-- 36->28 --> +<g id="edge58" class="edge"><title>36->28</title> +<path fill="none" stroke="black" d="M6517.94,-623.115C6561.29,-616.784 6642.3,-597.406 6642.3,-541 6642.3,-541 6642.3,-541 6642.3,-191 6642.3,-83.3481 6512.28,-152.945 6405.3,-141 6158.95,-113.495 4310.69,-106.959 4022.91,-106.104"/> +<polygon fill="black" stroke="black" points="4022.6,-102.603 4012.59,-106.074 4022.58,-109.603 4022.6,-102.603"/> +<text text-anchor="middle" x="6689.8" y="-362.3" font-family="Times,serif" font-size="14.00">[0x00-s][u-0xFF]</text> +</g> +<!-- 52 --> +<g id="node49" class="node"><title>52</title> +<ellipse fill="none" stroke="black" cx="6491.3" cy="-540" rx="27" ry="18"/> +<text text-anchor="middle" x="6491.3" y="-536.3" font-family="Times,serif" font-size="14.00">52</text> +</g> +<!-- 36->52 --> +<g id="edge59" class="edge"><title>36->52</title> +<path fill="none" stroke="black" d="M6491.3,-608.799C6491.3,-597.163 6491.3,-581.548 6491.3,-568.237"/> +<polygon fill="black" stroke="black" points="6494.8,-568.175 6491.3,-558.175 6487.8,-568.175 6494.8,-568.175"/> +<text text-anchor="middle" x="6497.8" y="-579.8" font-family="Times,serif" font-size="14.00">[t]</text> +</g> +<!-- 7->6 --> +<g id="edge25" class="edge"><title>7->6</title> +<path fill="none" stroke="black" d="M282.801,-752.758C287.454,-764.741 293.806,-781.104 299.125,-794.803"/> +<polygon fill="black" stroke="black" points="295.894,-796.151 302.776,-804.207 302.419,-793.618 295.894,-796.151"/> +<text text-anchor="middle" x="319.795" y="-774.8" font-family="Times,serif" font-size="14.00">[0x09][ ]</text> +</g> +<!-- 8 --> +<g id="node25" class="node"><title>8</title> +<ellipse fill="none" stroke="black" cx="276.295" cy="-627" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="276.295" y="-623.3" font-family="Times,serif" font-size="14.00">lexer.re:220</text> +</g> +<!-- 7->8 --> +<g id="edge24" class="edge"><title>7->8</title> +<path fill="none" stroke="black" d="M276.295,-716.969C276.295,-700.378 276.295,-674.883 276.295,-655.431"/> +<polygon fill="black" stroke="black" points="279.795,-655.341 276.295,-645.341 272.795,-655.341 279.795,-655.341"/> +<text text-anchor="middle" x="369.295" y="-677.3" font-family="Times,serif" font-size="14.00">[0x00-0x08][0x0A-0x1F][!-0xFF]</text> +</g> +<!-- 37->22 --> +<g id="edge60" class="edge"><title>37->22</title> +<path fill="none" stroke="black" d="M676.372,-662.939C680.883,-641.274 690.833,-603.418 709.295,-576 712.388,-571.408 716.228,-567.045 720.295,-563.057"/> +<polygon fill="black" stroke="black" points="722.681,-565.619 727.75,-556.315 717.985,-560.427 722.681,-565.619"/> +</g> +<!-- 39 --> +<g id="node50" class="node"><title>39</title> +<ellipse fill="none" stroke="black" cx="830.295" cy="-627" rx="27" ry="18"/> +<text text-anchor="middle" x="830.295" y="-623.3" font-family="Times,serif" font-size="14.00">39</text> +</g> +<!-- 38->39 --> +<g id="edge61" class="edge"><title>38->39</title> +<path fill="none" stroke="black" d="M1025.5,-723.869C1019.39,-721.331 1012.67,-718.816 1006.3,-717 958.653,-703.423 939.958,-722.403 896.295,-699 890.526,-695.908 867.397,-670.355 850.136,-650.781"/> +<polygon fill="black" stroke="black" points="852.625,-648.311 843.397,-643.106 847.364,-652.93 852.625,-648.311"/> +<text text-anchor="middle" x="971.795" y="-677.3" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][G-`][g-0xFF]</text> +</g> +<!-- 53 --> +<g id="node51" class="node"><title>53</title> +<ellipse fill="none" stroke="black" cx="1056.3" cy="-627" rx="27" ry="18"/> +<text text-anchor="middle" x="1056.3" y="-623.3" font-family="Times,serif" font-size="14.00">53</text> +</g> +<!-- 38->53 --> +<g id="edge62" class="edge"><title>38->53</title> +<path fill="none" stroke="black" d="M1048.74,-716.969C1050.16,-700.279 1052.34,-674.579 1054,-655.084"/> +<polygon fill="black" stroke="black" points="1057.49,-655.249 1054.85,-644.988 1050.52,-654.656 1057.49,-655.249"/> +<text text-anchor="middle" x="1094.3" y="-677.3" font-family="Times,serif" font-size="14.00">[0-9][A-F][a-f]</text> +</g> +<!-- 24->23 --> +<g id="edge37" class="edge"><title>24->23</title> +<path fill="none" stroke="black" d="M1124.42,-752.758C1128.05,-764.625 1132.99,-780.787 1137.16,-794.403"/> +<polygon fill="black" stroke="black" points="1133.89,-795.668 1140.16,-804.207 1140.58,-793.62 1133.89,-795.668"/> +<text text-anchor="middle" x="1148.3" y="-774.8" font-family="Times,serif" font-size="14.00">[0-9]</text> +</g> +<!-- 24->22 --> +<g id="edge36" class="edge"><title>24->22</title> +<path fill="none" stroke="black" d="M1131.08,-718.494C1141.59,-702.656 1153.32,-678.283 1139.3,-663 1107.62,-628.495 973.975,-659.052 929.295,-645 927.311,-644.376 834.766,-590.675 783.172,-560.696"/> +<polygon fill="black" stroke="black" points="784.755,-557.568 774.351,-555.569 781.238,-563.62 784.755,-557.568"/> +<text text-anchor="middle" x="974.795" y="-623.3" font-family="Times,serif" font-size="14.00">[0x00-/][:-0xFF]</text> +</g> +<!-- 41 --> +<g id="node52" class="node"><title>41</title> +<ellipse fill="none" stroke="black" cx="1154.3" cy="-627" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="1154.3" y="-623.3" font-family="Times,serif" font-size="14.00">lexer.re:192</text> +</g> +<!-- 40->41 --> +<g id="edge64" class="edge"><title>40->41</title> +<path fill="none" stroke="black" d="M1419.82,-722.872C1414.86,-720.591 1409.49,-718.448 1404.3,-717 1328.98,-696.006 1300.36,-731.612 1229.3,-699 1206.81,-688.683 1186.78,-668.868 1173.09,-652.787"/> +<polygon fill="black" stroke="black" points="1175.58,-650.299 1166.53,-644.788 1170.16,-654.739 1175.58,-650.299"/> +</g> +<!-- 28->27 --> +<g id="edge42" class="edge"><title>28->27</title> +<path fill="none" stroke="black" d="M3991.8,-122.758C3996.45,-134.741 4002.81,-151.104 4008.12,-164.803"/> +<polygon fill="black" stroke="black" points="4004.89,-166.151 4011.78,-174.207 4011.42,-163.618 4004.89,-166.151"/> +<text text-anchor="middle" x="4054.3" y="-144.8" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 29 --> +<g id="node39" class="node"><title>29</title> +<ellipse fill="none" stroke="black" cx="3985.3" cy="-18" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="3985.3" y="-14.3" font-family="Times,serif" font-size="14.00">lexer.re:212</text> +</g> +<!-- 28->29 --> +<g id="edge41" class="edge"><title>28->29</title> +<path fill="none" stroke="black" d="M3985.3,-86.799C3985.3,-75.1626 3985.3,-59.5479 3985.3,-46.2368"/> +<polygon fill="black" stroke="black" points="3988.8,-46.1754 3985.3,-36.1754 3981.8,-46.1755 3988.8,-46.1754"/> +<text text-anchor="middle" x="4066.3" y="-57.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 42->28 --> +<g id="edge65" class="edge"><title>42->28</title> +<path fill="none" stroke="black" d="M4871.58,-436.538C4899.19,-399.896 4974.14,-307.382 5059.3,-261 5091.63,-243.387 5158.15,-256.872 5135.3,-228 5030.71,-95.8896 4933.19,-164.206 4766.3,-141 4620.03,-120.661 4158.11,-109.61 4022.86,-106.753"/> +<polygon fill="black" stroke="black" points="4022.67,-103.249 4012.6,-106.539 4022.52,-110.247 4022.67,-103.249"/> +<text text-anchor="middle" x="5109.8" y="-275.3" font-family="Times,serif" font-size="14.00">[0x00-k][m-0xFF]</text> +</g> +<!-- 56 --> +<g id="node53" class="node"><title>56</title> +<ellipse fill="none" stroke="black" cx="4860.3" cy="-366" rx="27" ry="18"/> +<text text-anchor="middle" x="4860.3" y="-362.3" font-family="Times,serif" font-size="14.00">56</text> +</g> +<!-- 42->56 --> +<g id="edge66" class="edge"><title>42->56</title> +<path fill="none" stroke="black" d="M4860.3,-434.799C4860.3,-423.163 4860.3,-407.548 4860.3,-394.237"/> +<polygon fill="black" stroke="black" points="4863.8,-394.175 4860.3,-384.175 4856.8,-394.175 4863.8,-394.175"/> +<text text-anchor="middle" x="4866.8" y="-405.8" font-family="Times,serif" font-size="14.00">[l]</text> +</g> +<!-- 43->28 --> +<g id="edge67" class="edge"><title>43->28</title> +<path fill="none" stroke="black" d="M1831.35,-347.692C1829.51,-326.102 1824.12,-288.665 1808.3,-261 1802.52,-250.903 1793.89,-253.686 1789.3,-243 1786.66,-236.876 1786.58,-234.088 1789.3,-228 1812.9,-175.119 1832.39,-162.151 1886.3,-141 1986.06,-101.859 3674.74,-105.098 3948.07,-105.881"/> +<polygon fill="black" stroke="black" points="3948.24,-109.381 3958.26,-105.911 3948.27,-102.381 3948.24,-109.381"/> +<text text-anchor="middle" x="1837.8" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-o][q-0xFF]</text> +</g> +<!-- 57 --> +<g id="node54" class="node"><title>57</title> +<ellipse fill="none" stroke="black" cx="2319.3" cy="-279" rx="27" ry="18"/> +<text text-anchor="middle" x="2319.3" y="-275.3" font-family="Times,serif" font-size="14.00">57</text> +</g> +<!-- 43->57 --> +<g id="edge68" class="edge"><title>43->57</title> +<path fill="none" stroke="black" d="M1854.98,-355.769C1862.33,-353.006 1870.58,-350.144 1878.3,-348 1953.71,-327.028 1973.8,-326.056 2051.3,-315 2134.83,-303.082 2156.91,-309.898 2240.3,-297 2254.77,-294.761 2270.57,-291.522 2284.22,-288.47"/> +<polygon fill="black" stroke="black" points="2285.21,-291.834 2294.17,-286.192 2283.65,-285.01 2285.21,-291.834"/> +<text text-anchor="middle" x="2059.3" y="-318.8" font-family="Times,serif" font-size="14.00">[p]</text> +</g> +<!-- 44->27 --> +<g id="edge70" class="edge"><title>44->27</title> +<path fill="none" stroke="black" d="M1539.27,-733.506C1798.71,-728.673 3842.3,-688.677 3842.3,-628 3842.3,-628 3842.3,-628 3842.3,-495.5 3842.3,-362.166 3944.52,-362.185 4004.3,-243 4007.85,-235.909 4010.62,-227.785 4012.72,-220.176"/> +<polygon fill="black" stroke="black" points="4016.16,-220.813 4015.17,-210.264 4009.37,-219.127 4016.16,-220.813"/> +<text text-anchor="middle" x="3927.3" y="-449.3" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-e][g-s][u-z]</text> +</g> +<!-- 45 --> +<g id="node55" class="node"><title>45</title> +<ellipse fill="none" stroke="black" cx="1399.3" cy="-627" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="1399.3" y="-623.3" font-family="Times,serif" font-size="14.00">lexer.re:158</text> +</g> +<!-- 44->45 --> +<g id="edge69" class="edge"><title>44->45</title> +<path fill="none" stroke="black" d="M1491.69,-723.269C1486.74,-720.972 1481.4,-718.721 1476.3,-717 1439.7,-704.672 1415.61,-729.001 1391.3,-699 1381.33,-686.707 1383.28,-669.036 1387.75,-654.399"/> +<polygon fill="black" stroke="black" points="1391.09,-655.449 1391.13,-644.854 1384.49,-653.113 1391.09,-655.449"/> +<text text-anchor="middle" x="1472.3" y="-677.3" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 59 --> +<g id="node56" class="node"><title>59</title> +<ellipse fill="none" stroke="black" cx="1301.3" cy="-627" rx="27" ry="18"/> +<text text-anchor="middle" x="1301.3" y="-623.3" font-family="Times,serif" font-size="14.00">59</text> +</g> +<!-- 44->59 --> +<g id="edge71" class="edge"><title>44->59</title> +<path fill="none" stroke="black" d="M1491.75,-723.096C1486.8,-720.806 1481.44,-718.602 1476.3,-717 1428.99,-702.28 1409.87,-722.569 1366.3,-699 1345.96,-687.998 1328.61,-668.145 1316.97,-652.225"/> +<polygon fill="black" stroke="black" points="1319.71,-650.042 1311.11,-643.866 1313.98,-654.062 1319.71,-650.042"/> +<text text-anchor="middle" x="1373.3" y="-677.3" font-family="Times,serif" font-size="14.00">[f]</text> +</g> +<!-- 60 --> +<g id="node57" class="node"><title>60</title> +<ellipse fill="none" stroke="black" cx="1159.3" cy="-540" rx="27" ry="18"/> +<text text-anchor="middle" x="1159.3" y="-536.3" font-family="Times,serif" font-size="14.00">60</text> +</g> +<!-- 44->60 --> +<g id="edge72" class="edge"><title>44->60</title> +<path fill="none" stroke="black" d="M1491.8,-722.924C1486.85,-720.641 1481.48,-718.484 1476.3,-717 1410.05,-698.038 1386.12,-724.989 1322.3,-699 1285.9,-684.181 1281.07,-671.758 1252.3,-645 1224.46,-619.111 1195.8,-585.876 1177.79,-564.033"/> +<polygon fill="black" stroke="black" points="1180.47,-561.784 1171.43,-556.258 1175.05,-566.215 1180.47,-561.784"/> +<text text-anchor="middle" x="1258.8" y="-623.3" font-family="Times,serif" font-size="14.00">[t]</text> +</g> +<!-- 46->28 --> +<g id="edge73" class="edge"><title>46->28</title> +<path fill="none" stroke="black" d="M5593.43,-527.849C5597.33,-525.821 5601.41,-523.785 5605.3,-522 5680.75,-487.354 5779.3,-537.029 5779.3,-454 5779.3,-454 5779.3,-454 5779.3,-191 5779.3,-99.7909 4280.21,-104.307 4022.72,-105.755"/> +<polygon fill="black" stroke="black" points="4022.38,-102.257 4012.4,-105.815 4022.42,-109.257 4022.38,-102.257"/> +<text text-anchor="middle" x="5826.8" y="-318.8" font-family="Times,serif" font-size="14.00">[0x00-a][c-0xFF]</text> +</g> +<!-- 61 --> +<g id="node58" class="node"><title>61</title> +<ellipse fill="none" stroke="black" cx="5573.3" cy="-453" rx="27" ry="18"/> +<text text-anchor="middle" x="5573.3" y="-449.3" font-family="Times,serif" font-size="14.00">61</text> +</g> +<!-- 46->61 --> +<g id="edge74" class="edge"><title>46->61</title> +<path fill="none" stroke="black" d="M5573.3,-521.799C5573.3,-510.163 5573.3,-494.548 5573.3,-481.237"/> +<polygon fill="black" stroke="black" points="5576.8,-481.175 5573.3,-471.175 5569.8,-481.175 5576.8,-481.175"/> +<text text-anchor="middle" x="5581.3" y="-492.8" font-family="Times,serif" font-size="14.00">[b]</text> +</g> +<!-- 47->28 --> +<g id="edge75" class="edge"><title>47->28</title> +<path fill="none" stroke="black" d="M6007.89,-446.696C6044.46,-437.449 6107.3,-414.632 6107.3,-367 6107.3,-367 6107.3,-367 6107.3,-191 6107.3,-78.1242 5970.51,-153.215 5858.3,-141 5483.73,-100.228 4252.92,-104.589 4022.6,-105.784"/> +<polygon fill="black" stroke="black" points="4022.38,-102.285 4012.4,-105.838 4022.42,-109.285 4022.38,-102.285"/> +<text text-anchor="middle" x="6154.3" y="-275.3" font-family="Times,serif" font-size="14.00">[0x00-`][b-0xFF]</text> +</g> +<!-- 62 --> +<g id="node59" class="node"><title>62</title> +<ellipse fill="none" stroke="black" cx="5982.3" cy="-366" rx="27" ry="18"/> +<text text-anchor="middle" x="5982.3" y="-362.3" font-family="Times,serif" font-size="14.00">62</text> +</g> +<!-- 47->62 --> +<g id="edge76" class="edge"><title>47->62</title> +<path fill="none" stroke="black" d="M5982.3,-434.799C5982.3,-423.163 5982.3,-407.548 5982.3,-394.237"/> +<polygon fill="black" stroke="black" points="5985.8,-394.175 5982.3,-384.175 5978.8,-394.175 5985.8,-394.175"/> +<text text-anchor="middle" x="5990.3" y="-405.8" font-family="Times,serif" font-size="14.00">[a]</text> +</g> +<!-- 48->28 --> +<g id="edge77" class="edge"><title>48->28</title> +<path fill="none" stroke="black" d="M2811.3,-364.442C2711.19,-361.472 2371.85,-342.895 2468.3,-228 2566.44,-111.087 3723.54,-105.835 3947.79,-105.92"/> +<polygon fill="black" stroke="black" points="3948.05,-109.42 3958.05,-105.928 3948.05,-102.42 3948.05,-109.42"/> +<text text-anchor="middle" x="2516.8" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-o][q-0xFF]</text> +</g> +<!-- 63 --> +<g id="node60" class="node"><title>63</title> +<ellipse fill="none" stroke="black" cx="3396.3" cy="-279" rx="27" ry="18"/> +<text text-anchor="middle" x="3396.3" y="-275.3" font-family="Times,serif" font-size="14.00">63</text> +</g> +<!-- 48->63 --> +<g id="edge78" class="edge"><title>48->63</title> +<path fill="none" stroke="black" d="M2865.14,-363.945C2942.5,-360.381 3172.1,-346.109 3355.3,-297 3358.67,-296.095 3362.14,-294.976 3365.56,-293.749"/> +<polygon fill="black" stroke="black" points="3366.91,-296.978 3374.96,-290.086 3364.37,-290.455 3366.91,-296.978"/> +<text text-anchor="middle" x="3281.3" y="-318.8" font-family="Times,serif" font-size="14.00">[p]</text> +</g> +<!-- 49->28 --> +<g id="edge79" class="edge"><title>49->28</title> +<path fill="none" stroke="black" d="M2197.46,-534.64C2158.52,-526.425 2089.3,-504.691 2089.3,-454 2089.3,-454 2089.3,-454 2086.3,-321.5 2086.3,-318.611 2085.72,-317.831 2086.3,-315 2099.9,-248.269 2101.37,-225.188 2146.3,-174 2165.35,-152.287 2174.5,-148.874 2202.3,-141 2289.16,-116.391 3698.3,-107.569 3947.72,-106.197"/> +<polygon fill="black" stroke="black" points="3948.08,-109.695 3958.06,-106.14 3948.04,-102.695 3948.08,-109.695"/> +<text text-anchor="middle" x="2136.3" y="-318.8" font-family="Times,serif" font-size="14.00">[0x00-h][j-0xFF]</text> +</g> +<!-- 65 --> +<g id="node61" class="node"><title>65</title> +<ellipse fill="none" stroke="black" cx="2223.3" cy="-453" rx="27" ry="18"/> +<text text-anchor="middle" x="2223.3" y="-449.3" font-family="Times,serif" font-size="14.00">65</text> +</g> +<!-- 49->65 --> +<g id="edge80" class="edge"><title>49->65</title> +<path fill="none" stroke="black" d="M2223.3,-521.799C2223.3,-510.163 2223.3,-494.548 2223.3,-481.237"/> +<polygon fill="black" stroke="black" points="2226.8,-481.175 2223.3,-471.175 2219.8,-481.175 2226.8,-481.175"/> +<text text-anchor="middle" x="2229.8" y="-492.8" font-family="Times,serif" font-size="14.00">[i]</text> +</g> +<!-- 50->28 --> +<g id="edge81" class="edge"><title>50->28</title> +<path fill="none" stroke="black" d="M3260.3,-434.744C3260.3,-417.57 3260.3,-390.464 3260.3,-367 3260.3,-367 3260.3,-367 3260.3,-191 3260.3,-121.068 3799.27,-108.539 3947.79,-106.414"/> +<polygon fill="black" stroke="black" points="3948.25,-109.908 3958.2,-106.273 3948.15,-102.908 3948.25,-109.908"/> +<text text-anchor="middle" x="3305.8" y="-275.3" font-family="Times,serif" font-size="14.00">[0x00-r][t-0xFF]</text> +</g> +<!-- 66 --> +<g id="node62" class="node"><title>66</title> +<ellipse fill="none" stroke="black" cx="3478.3" cy="-366" rx="27" ry="18"/> +<text text-anchor="middle" x="3478.3" y="-362.3" font-family="Times,serif" font-size="14.00">66</text> +</g> +<!-- 50->66 --> +<g id="edge82" class="edge"><title>50->66</title> +<path fill="none" stroke="black" d="M3283.21,-443.064C3322.14,-427.887 3401.27,-397.031 3445.87,-379.645"/> +<polygon fill="black" stroke="black" points="3447.31,-382.837 3455.36,-375.944 3444.77,-376.316 3447.31,-382.837"/> +<text text-anchor="middle" x="3390.8" y="-405.8" font-family="Times,serif" font-size="14.00">[s]</text> +</g> +<!-- 51->28 --> +<g id="edge83" class="edge"><title>51->28</title> +<path fill="none" stroke="black" d="M4389.69,-436.096C4393.11,-430.153 4396.97,-423.314 4400.3,-417 4407.9,-402.582 4409.99,-399.029 4416.3,-384 4438.77,-330.468 4422.56,-305.125 4460.3,-261 4471.15,-248.303 4484.77,-257.366 4493.3,-243 4496.7,-237.267 4497.09,-233.484 4493.3,-228 4438.95,-149.387 4129.85,-117.529 4022.23,-108.721"/> +<polygon fill="black" stroke="black" points="4022.42,-105.224 4012.17,-107.917 4021.86,-112.202 4022.42,-105.224"/> +<text text-anchor="middle" x="4520.3" y="-275.3" font-family="Times,serif" font-size="14.00">[0x00-`][b-s][u-0xFF]</text> +</g> +<!-- 67 --> +<g id="node63" class="node"><title>67</title> +<ellipse fill="none" stroke="black" cx="4380.3" cy="-366" rx="27" ry="18"/> +<text text-anchor="middle" x="4380.3" y="-362.3" font-family="Times,serif" font-size="14.00">67</text> +</g> +<!-- 51->67 --> +<g id="edge84" class="edge"><title>51->67</title> +<path fill="none" stroke="black" d="M4380.3,-434.799C4380.3,-423.163 4380.3,-407.548 4380.3,-394.237"/> +<polygon fill="black" stroke="black" points="4383.8,-394.175 4380.3,-384.175 4376.8,-394.175 4383.8,-394.175"/> +<text text-anchor="middle" x="4388.3" y="-405.8" font-family="Times,serif" font-size="14.00">[a]</text> +</g> +<!-- 68 --> +<g id="node64" class="node"><title>68</title> +<ellipse fill="none" stroke="black" cx="4184.3" cy="-366" rx="27" ry="18"/> +<text text-anchor="middle" x="4184.3" y="-362.3" font-family="Times,serif" font-size="14.00">68</text> +</g> +<!-- 51->68 --> +<g id="edge85" class="edge"><title>51->68</title> +<path fill="none" stroke="black" d="M4358.19,-442.415C4323.32,-427.293 4255.43,-397.848 4215.57,-380.563"/> +<polygon fill="black" stroke="black" points="4216.88,-377.318 4206.32,-376.55 4214.1,-383.74 4216.88,-377.318"/> +<text text-anchor="middle" x="4300.8" y="-405.8" font-family="Times,serif" font-size="14.00">[t]</text> +</g> +<!-- 52->28 --> +<g id="edge86" class="edge"><title>52->28</title> +<path fill="none" stroke="black" d="M6503.21,-523.674C6514.68,-507.354 6530.3,-480.303 6530.3,-454 6530.3,-454 6530.3,-454 6530.3,-191 6530.3,-68.5227 6381.17,-153.096 6259.3,-141 6028.11,-118.056 4299.98,-107.717 4022.76,-106.199"/> +<polygon fill="black" stroke="black" points="4022.46,-102.697 4012.44,-106.142 4022.42,-109.697 4022.46,-102.697"/> +<text text-anchor="middle" x="6578.8" y="-318.8" font-family="Times,serif" font-size="14.00">[0x00-n][p-0xFF]</text> +</g> +<!-- 70 --> +<g id="node65" class="node"><title>70</title> +<ellipse fill="none" stroke="black" cx="6407.3" cy="-453" rx="27" ry="18"/> +<text text-anchor="middle" x="6407.3" y="-449.3" font-family="Times,serif" font-size="14.00">70</text> +</g> +<!-- 52->70 --> +<g id="edge87" class="edge"><title>52->70</title> +<path fill="none" stroke="black" d="M6477.05,-524.581C6463.89,-511.271 6444.17,-491.309 6429.04,-476.007"/> +<polygon fill="black" stroke="black" points="6431.13,-473.142 6421.61,-468.49 6426.15,-478.063 6431.13,-473.142"/> +<text text-anchor="middle" x="6462.3" y="-492.8" font-family="Times,serif" font-size="14.00">[o]</text> +</g> +<!-- 39->22 --> +<g id="edge63" class="edge"><title>39->22</title> +<path fill="none" stroke="black" d="M816.186,-611.194C803.989,-598.395 786.136,-579.66 771.941,-564.764"/> +<polygon fill="black" stroke="black" points="774.333,-562.201 764.901,-557.376 769.266,-567.03 774.333,-562.201"/> +</g> +<!-- 54 --> +<g id="node66" class="node"><title>54</title> +<ellipse fill="none" stroke="black" cx="1023.3" cy="-540" rx="27" ry="18"/> +<text text-anchor="middle" x="1023.3" y="-536.3" font-family="Times,serif" font-size="14.00">54</text> +</g> +<!-- 53->54 --> +<g id="edge88" class="edge"><title>53->54</title> +<path fill="none" stroke="black" d="M1046.62,-609.987C1043.36,-604.15 1039.89,-597.407 1037.3,-591 1034.31,-583.649 1031.73,-575.443 1029.62,-567.839"/> +<polygon fill="black" stroke="black" points="1032.96,-566.771 1027.04,-557.98 1026.18,-568.54 1032.96,-566.771"/> +</g> +<!-- 56->28 --> +<g id="edge91" class="edge"><title>56->28</title> +<path fill="none" stroke="black" d="M4869.48,-348.825C4883.1,-322.606 4905.29,-269.573 4888.3,-228 4875.57,-196.872 4864.44,-190.785 4835.3,-174 4784.01,-144.462 4764.81,-149.813 4706.3,-141 4572.35,-120.828 4150.51,-109.767 4022.49,-106.813"/> +<polygon fill="black" stroke="black" points="4022.48,-103.312 4012.41,-106.583 4022.32,-110.31 4022.48,-103.312"/> +<text text-anchor="middle" x="4942.8" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-k][m-0xFF]</text> +</g> +<!-- 71 --> +<g id="node68" class="node"><title>71</title> +<ellipse fill="none" stroke="black" cx="4747.3" cy="-279" rx="27" ry="18"/> +<text text-anchor="middle" x="4747.3" y="-275.3" font-family="Times,serif" font-size="14.00">71</text> +</g> +<!-- 56->71 --> +<g id="edge92" class="edge"><title>56->71</title> +<path fill="none" stroke="black" d="M4843.13,-352.09C4824.38,-337.986 4794.16,-315.251 4772.67,-299.086"/> +<polygon fill="black" stroke="black" points="4774.71,-296.245 4764.62,-293.031 4770.51,-301.84 4774.71,-296.245"/> +<text text-anchor="middle" x="4816.8" y="-318.8" font-family="Times,serif" font-size="14.00">[l]</text> +</g> +<!-- 57->27 --> +<g id="edge94" class="edge"><title>57->27</title> +<path fill="none" stroke="black" d="M2346.28,-277.072C2468.92,-272.795 2969.2,-254.698 3000.3,-243 3010.37,-239.212 3009.17,-231.649 3019.3,-228 3058.87,-213.732 3734.27,-211.974 3776.3,-210 3849.05,-206.582 3933.93,-200.025 3981.36,-196.129"/> +<polygon fill="black" stroke="black" points="3981.78,-199.606 3991.46,-195.293 3981.21,-192.63 3981.78,-199.606"/> +<text text-anchor="middle" x="3069.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 58 --> +<g id="node69" class="node"><title>58</title> +<ellipse fill="none" stroke="black" cx="2286.3" cy="-192" rx="48.9926" ry="18"/> +<text text-anchor="middle" x="2286.3" y="-188.3" font-family="Times,serif" font-size="14.00">lexer.re:88</text> +</g> +<!-- 57->58 --> +<g id="edge93" class="edge"><title>57->58</title> +<path fill="none" stroke="black" d="M2302.55,-264.379C2296.58,-258.497 2290.54,-251.104 2287.3,-243 2284.49,-235.986 2283.48,-227.965 2283.36,-220.431"/> +<polygon fill="black" stroke="black" points="2286.87,-220.372 2283.7,-210.261 2279.87,-220.138 2286.87,-220.372"/> +<text text-anchor="middle" x="2368.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 59->28 --> +<g id="edge95" class="edge"><title>59->28</title> +<path fill="none" stroke="black" d="M1292.51,-609.916C1272.35,-571.977 1223.21,-473.361 1206.3,-384 1197.45,-337.282 1218.58,-211.894 1247.3,-174 1265.44,-150.055 1277.27,-148.768 1306.3,-141 1439.72,-105.289 3632.44,-105.716 3947.67,-105.963"/> +<polygon fill="black" stroke="black" points="3948.08,-109.463 3958.08,-105.971 3948.09,-102.463 3948.08,-109.463"/> +<text text-anchor="middle" x="1253.3" y="-362.3" font-family="Times,serif" font-size="14.00">[0x00-`][b-0xFF]</text> +</g> +<!-- 73 --> +<g id="node70" class="node"><title>73</title> +<ellipse fill="none" stroke="black" cx="1328.3" cy="-540" rx="27" ry="18"/> +<text text-anchor="middle" x="1328.3" y="-536.3" font-family="Times,serif" font-size="14.00">73</text> +</g> +<!-- 59->73 --> +<g id="edge96" class="edge"><title>59->73</title> +<path fill="none" stroke="black" d="M1306.63,-609.207C1310.4,-597.332 1315.54,-581.168 1319.86,-567.557"/> +<polygon fill="black" stroke="black" points="1323.28,-568.349 1322.97,-557.758 1316.61,-566.229 1323.28,-568.349"/> +<text text-anchor="middle" x="1325.3" y="-579.8" font-family="Times,serif" font-size="14.00">[a]</text> +</g> +<!-- 60->28 --> +<g id="edge97" class="edge"><title>60->28</title> +<path fill="none" stroke="black" d="M1132.65,-536.115C1089.3,-529.784 1008.3,-510.406 1008.3,-454 1008.3,-454 1008.3,-454 1008.3,-191 1008.3,-113.097 1099.28,-152.708 1176.3,-141 1319.77,-119.189 3625.24,-107.678 3947.9,-106.17"/> +<polygon fill="black" stroke="black" points="3948.14,-109.669 3958.12,-106.123 3948.11,-102.67 3948.14,-109.669"/> +<text text-anchor="middle" x="1055.8" y="-318.8" font-family="Times,serif" font-size="14.00">[0x00-q][s-0xFF]</text> +</g> +<!-- 74 --> +<g id="node71" class="node"><title>74</title> +<ellipse fill="none" stroke="black" cx="1159.3" cy="-453" rx="27" ry="18"/> +<text text-anchor="middle" x="1159.3" y="-449.3" font-family="Times,serif" font-size="14.00">74</text> +</g> +<!-- 60->74 --> +<g id="edge98" class="edge"><title>60->74</title> +<path fill="none" stroke="black" d="M1159.3,-521.799C1159.3,-510.163 1159.3,-494.548 1159.3,-481.237"/> +<polygon fill="black" stroke="black" points="1162.8,-481.175 1159.3,-471.175 1155.8,-481.175 1162.8,-481.175"/> +<text text-anchor="middle" x="1166.3" y="-492.8" font-family="Times,serif" font-size="14.00">[r]</text> +</g> +<!-- 61->28 --> +<g id="edge99" class="edge"><title>61->28</title> +<path fill="none" stroke="black" d="M5590.07,-438.589C5607.2,-423.267 5631.3,-396.477 5631.3,-367 5631.3,-367 5631.3,-367 5631.3,-191 5631.3,-107.648 4267.36,-105.612 4022.65,-105.917"/> +<polygon fill="black" stroke="black" points="4022.49,-102.417 4012.49,-105.932 4022.5,-109.417 4022.49,-102.417"/> +<text text-anchor="middle" x="5678.3" y="-275.3" font-family="Times,serif" font-size="14.00">[0x00-d][f-0xFF]</text> +</g> +<!-- 75 --> +<g id="node72" class="node"><title>75</title> +<ellipse fill="none" stroke="black" cx="5515.3" cy="-366" rx="27" ry="18"/> +<text text-anchor="middle" x="5515.3" y="-362.3" font-family="Times,serif" font-size="14.00">75</text> +</g> +<!-- 61->75 --> +<g id="edge100" class="edge"><title>61->75</title> +<path fill="none" stroke="black" d="M5562.66,-436.41C5554.04,-423.788 5541.76,-405.788 5531.86,-391.281"/> +<polygon fill="black" stroke="black" points="5534.59,-389.067 5526.06,-382.779 5528.81,-393.012 5534.59,-389.067"/> +<text text-anchor="middle" x="5555.3" y="-405.8" font-family="Times,serif" font-size="14.00">[e]</text> +</g> +<!-- 62->28 --> +<g id="edge101" class="edge"><title>62->28</title> +<path fill="none" stroke="black" d="M5985.18,-347.669C5988.86,-320.768 5992.81,-267.909 5975.3,-228 5939.27,-145.902 5882.14,-153.058 5793.3,-141 5612.15,-116.414 4264.03,-107.594 4022.34,-106.203"/> +<polygon fill="black" stroke="black" points="4022.32,-102.703 4012.3,-106.146 4022.28,-109.703 4022.32,-102.703"/> +<text text-anchor="middle" x="6027.8" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-c][e-0xFF]</text> +</g> +<!-- 76 --> +<g id="node73" class="node"><title>76</title> +<ellipse fill="none" stroke="black" cx="5834.3" cy="-279" rx="27" ry="18"/> +<text text-anchor="middle" x="5834.3" y="-275.3" font-family="Times,serif" font-size="14.00">76</text> +</g> +<!-- 62->76 --> +<g id="edge102" class="edge"><title>62->76</title> +<path fill="none" stroke="black" d="M5962.34,-353.537C5936.85,-338.898 5892.55,-313.458 5863.33,-296.674"/> +<polygon fill="black" stroke="black" points="5864.83,-293.499 5854.41,-291.553 5861.34,-299.569 5864.83,-293.499"/> +<text text-anchor="middle" x="5924.3" y="-318.8" font-family="Times,serif" font-size="14.00">[d]</text> +</g> +<!-- 63->27 --> +<g id="edge104" class="edge"><title>63->27</title> +<path fill="none" stroke="black" d="M3422.39,-274.144C3457.18,-268.708 3520.51,-257.779 3573.3,-243 3591.98,-237.769 3595.35,-232.207 3614.3,-228 3649.62,-220.154 3888.74,-202.339 3981.56,-195.625"/> +<polygon fill="black" stroke="black" points="3981.9,-199.11 3991.62,-194.9 3981.4,-192.128 3981.9,-199.11"/> +<text text-anchor="middle" x="3664.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 64 --> +<g id="node74" class="node"><title>64</title> +<ellipse fill="none" stroke="black" cx="3337.3" cy="-192" rx="48.9926" ry="18"/> +<text text-anchor="middle" x="3337.3" y="-188.3" font-family="Times,serif" font-size="14.00">lexer.re:81</text> +</g> +<!-- 63->64 --> +<g id="edge103" class="edge"><title>63->64</title> +<path fill="none" stroke="black" d="M3374.33,-268.39C3368.22,-265.854 3361.54,-263.21 3355.3,-261 3328.65,-251.573 3311.22,-265.64 3294.3,-243 3286.87,-233.062 3293.43,-222.577 3303.48,-213.79"/> +<polygon fill="black" stroke="black" points="3305.91,-216.334 3311.66,-207.438 3301.62,-210.804 3305.91,-216.334"/> +<text text-anchor="middle" x="3375.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 65->28 --> +<g id="edge105" class="edge"><title>65->28</title> +<path fill="none" stroke="black" d="M2223.18,-434.895C2222.06,-406.374 2215.75,-348.898 2184.3,-315 2168.51,-297.993 2148.57,-316.025 2135.3,-297 2107.86,-257.697 2166.63,-182.151 2177.3,-174 2240.87,-125.401 2274.7,-149.219 2354.3,-141 2678.11,-107.565 3735.51,-105.955 3947.93,-105.975"/> +<polygon fill="black" stroke="black" points="3948.23,-109.474 3958.24,-105.977 3948.24,-102.474 3948.23,-109.474"/> +<text text-anchor="middle" x="2185.8" y="-275.3" font-family="Times,serif" font-size="14.00">[0x00-m][o-0xFF]</text> +</g> +<!-- 78 --> +<g id="node75" class="node"><title>78</title> +<ellipse fill="none" stroke="black" cx="2264.3" cy="-366" rx="27" ry="18"/> +<text text-anchor="middle" x="2264.3" y="-362.3" font-family="Times,serif" font-size="14.00">78</text> +</g> +<!-- 65->78 --> +<g id="edge106" class="edge"><title>65->78</title> +<path fill="none" stroke="black" d="M2231.2,-435.611C2237.1,-423.382 2245.27,-406.443 2252.02,-392.456"/> +<polygon fill="black" stroke="black" points="2255.22,-393.866 2256.41,-383.339 2248.92,-390.825 2255.22,-393.866"/> +<text text-anchor="middle" x="2254.3" y="-405.8" font-family="Times,serif" font-size="14.00">[n]</text> +</g> +<!-- 66->28 --> +<g id="edge107" class="edge"><title>66->28</title> +<path fill="none" stroke="black" d="M3471.94,-348.264C3462.51,-320.288 3448.61,-263.593 3475.3,-228 3532.84,-151.254 3841.23,-118.189 3948.49,-108.896"/> +<polygon fill="black" stroke="black" points="3948.85,-112.378 3958.52,-108.046 3948.26,-105.403 3948.85,-112.378"/> +<text text-anchor="middle" x="3522.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-g][i-0xFF]</text> +</g> +<!-- 79 --> +<g id="node76" class="node"><title>79</title> +<ellipse fill="none" stroke="black" cx="3718.3" cy="-279" rx="27" ry="18"/> +<text text-anchor="middle" x="3718.3" y="-275.3" font-family="Times,serif" font-size="14.00">79</text> +</g> +<!-- 66->79 --> +<g id="edge108" class="edge"><title>66->79</title> +<path fill="none" stroke="black" d="M3501.74,-356.695C3544.67,-341.492 3635.98,-309.153 3685.21,-291.719"/> +<polygon fill="black" stroke="black" points="3686.49,-294.976 3694.75,-288.339 3684.16,-288.378 3686.49,-294.976"/> +<text text-anchor="middle" x="3621.3" y="-318.8" font-family="Times,serif" font-size="14.00">[h]</text> +</g> +<!-- 67->28 --> +<g id="edge109" class="edge"><title>67->28</title> +<path fill="none" stroke="black" d="M4386.75,-348.354C4396.22,-321 4410.37,-265.813 4387.3,-228 4348.28,-164.07 4113.15,-124.198 4021.67,-110.927"/> +<polygon fill="black" stroke="black" points="4021.9,-107.423 4011.5,-109.476 4020.91,-114.353 4021.9,-107.423"/> +<text text-anchor="middle" x="4441.8" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-c][e-0xFF]</text> +</g> +<!-- 81 --> +<g id="node77" class="node"><title>81</title> +<ellipse fill="none" stroke="black" cx="4337.3" cy="-279" rx="27" ry="18"/> +<text text-anchor="middle" x="4337.3" y="-275.3" font-family="Times,serif" font-size="14.00">81</text> +</g> +<!-- 67->81 --> +<g id="edge110" class="edge"><title>67->81</title> +<path fill="none" stroke="black" d="M4372,-348.611C4365.82,-336.382 4357.25,-319.443 4350.17,-305.456"/> +<polygon fill="black" stroke="black" points="4353.2,-303.682 4345.56,-296.339 4346.95,-306.842 4353.2,-303.682"/> +<text text-anchor="middle" x="4370.3" y="-318.8" font-family="Times,serif" font-size="14.00">[d]</text> +</g> +<!-- 68->27 --> +<g id="edge112" class="edge"><title>68->27</title> +<path fill="none" stroke="black" d="M4161.38,-355.987C4137.18,-345.352 4099.52,-325.445 4077.3,-297 4057.39,-271.527 4071.48,-255.377 4054.3,-228 4051.03,-222.798 4046.83,-217.807 4042.47,-213.306"/> +<polygon fill="black" stroke="black" points="4044.74,-210.632 4035.09,-206.243 4039.89,-215.688 4044.74,-210.632"/> +<text text-anchor="middle" x="4127.3" y="-275.3" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 69 --> +<g id="node78" class="node"><title>69</title> +<ellipse fill="none" stroke="black" cx="4239.3" cy="-279" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="4239.3" y="-275.3" font-family="Times,serif" font-size="14.00">lexer.re:172</text> +</g> +<!-- 68->69 --> +<g id="edge111" class="edge"><title>68->69</title> +<path fill="none" stroke="black" d="M4183.01,-347.692C4183.04,-337.519 4184.5,-324.778 4190.3,-315 4193.55,-309.511 4198.04,-304.65 4202.98,-300.43"/> +<polygon fill="black" stroke="black" points="4205.18,-303.159 4211.03,-294.326 4200.94,-297.583 4205.18,-303.159"/> +<text text-anchor="middle" x="4271.3" y="-318.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 70->28 --> +<g id="edge113" class="edge"><title>70->28</title> +<path fill="none" stroke="black" d="M6409.59,-434.921C6415.47,-388.65 6429.09,-262.068 6407.3,-228 6349.96,-138.387 6289.34,-157.83 6184.3,-141 5962.7,-105.497 4293.38,-105.685 4022.41,-105.952"/> +<polygon fill="black" stroke="black" points="4022.3,-102.452 4012.31,-105.963 4022.31,-109.452 4022.3,-102.452"/> +<text text-anchor="middle" x="6465.8" y="-275.3" font-family="Times,serif" font-size="14.00">[0x00-q][s-0xFF]</text> +</g> +<!-- 83 --> +<g id="node79" class="node"><title>83</title> +<ellipse fill="none" stroke="black" cx="6325.3" cy="-366" rx="27" ry="18"/> +<text text-anchor="middle" x="6325.3" y="-362.3" font-family="Times,serif" font-size="14.00">83</text> +</g> +<!-- 70->83 --> +<g id="edge114" class="edge"><title>70->83</title> +<path fill="none" stroke="black" d="M6393.01,-437.194C6380.2,-423.909 6361.21,-404.228 6346.6,-389.084"/> +<polygon fill="black" stroke="black" points="6348.88,-386.403 6339.41,-381.636 6343.84,-391.263 6348.88,-386.403"/> +<text text-anchor="middle" x="6377.3" y="-405.8" font-family="Times,serif" font-size="14.00">[r]</text> +</g> +<!-- 54->53 --> +<g id="edge90" class="edge"><title>54->53</title> +<path fill="none" stroke="black" d="M1029.8,-557.758C1034.45,-569.741 1040.81,-586.104 1046.12,-599.803"/> +<polygon fill="black" stroke="black" points="1042.89,-601.151 1049.78,-609.207 1049.42,-598.618 1042.89,-601.151"/> +<text text-anchor="middle" x="1083.3" y="-579.8" font-family="Times,serif" font-size="14.00">[0-9][A-F][a-f]</text> +</g> +<!-- 55 --> +<g id="node67" class="node"><title>55</title> +<ellipse fill="none" stroke="black" cx="842.295" cy="-453" rx="48.9926" ry="18"/> +<text text-anchor="middle" x="842.295" y="-449.3" font-family="Times,serif" font-size="14.00">lexer.re:66</text> +</g> +<!-- 54->55 --> +<g id="edge89" class="edge"><title>54->55</title> +<path fill="none" stroke="black" d="M996.381,-537.772C951.073,-535.085 862.61,-526.961 843.295,-504 838.029,-497.74 836.504,-489.315 836.679,-481.167"/> +<polygon fill="black" stroke="black" points="840.166,-481.471 837.657,-471.177 833.2,-480.789 840.166,-481.471"/> +<text text-anchor="middle" x="918.795" y="-492.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][G-`][g-0xFF]</text> +</g> +<!-- 71->27 --> +<g id="edge116" class="edge"><title>71->27</title> +<path fill="none" stroke="black" d="M4722.39,-271.468C4679.17,-260.429 4587.32,-238.284 4508.3,-228 4357.36,-208.358 4317.98,-222.691 4166.3,-210 4128.02,-206.798 4084.36,-201.591 4054.43,-197.782"/> +<polygon fill="black" stroke="black" points="4054.81,-194.303 4044.45,-196.499 4053.92,-201.245 4054.81,-194.303"/> +<text text-anchor="middle" x="4645.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 72 --> +<g id="node80" class="node"><title>72</title> +<ellipse fill="none" stroke="black" cx="4773.3" cy="-192" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="4773.3" y="-188.3" font-family="Times,serif" font-size="14.00">lexer.re:165</text> +</g> +<!-- 71->72 --> +<g id="edge115" class="edge"><title>71->72</title> +<path fill="none" stroke="black" d="M4733.99,-262.884C4726.84,-252.839 4720.55,-239.443 4726.3,-228 4728.99,-222.642 4732.93,-217.895 4737.4,-213.763"/> +<polygon fill="black" stroke="black" points="4739.72,-216.39 4745.31,-207.39 4735.33,-210.939 4739.72,-216.39"/> +<text text-anchor="middle" x="4807.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 73->28 --> +<g id="edge117" class="edge"><title>73->28</title> +<path fill="none" stroke="black" d="M1331.5,-522.005C1337.32,-485.725 1345.48,-399.79 1304.3,-348 1289.85,-329.842 1268.57,-349.025 1255.3,-330 1201.71,-253.232 1257.61,-164.27 1348.3,-141 1479.92,-107.223 3635.78,-105.993 3947.78,-105.993"/> +<polygon fill="black" stroke="black" points="3948.09,-109.493 3958.09,-105.993 3948.09,-102.493 3948.09,-109.493"/> +<text text-anchor="middle" x="1305.8" y="-318.8" font-family="Times,serif" font-size="14.00">[0x00-k][m-0xFF]</text> +</g> +<!-- 84 --> +<g id="node81" class="node"><title>84</title> +<ellipse fill="none" stroke="black" cx="1438.3" cy="-453" rx="27" ry="18"/> +<text text-anchor="middle" x="1438.3" y="-449.3" font-family="Times,serif" font-size="14.00">84</text> +</g> +<!-- 73->84 --> +<g id="edge118" class="edge"><title>73->84</title> +<path fill="none" stroke="black" d="M1345.48,-525.719C1363.65,-511.684 1392.47,-489.409 1413.18,-473.407"/> +<polygon fill="black" stroke="black" points="1415.46,-476.072 1421.23,-467.188 1411.18,-470.533 1415.46,-476.072"/> +<text text-anchor="middle" x="1396.8" y="-492.8" font-family="Times,serif" font-size="14.00">[l]</text> +</g> +<!-- 74->28 --> +<g id="edge119" class="edge"><title>74->28</title> +<path fill="none" stroke="black" d="M1149.16,-435.869C1129.61,-402.619 1090.46,-324.271 1112.3,-261 1134.39,-196.957 1145.57,-171.043 1206.3,-141 1270.67,-109.15 3620.63,-106.269 3947.67,-106.022"/> +<polygon fill="black" stroke="black" points="3948.02,-109.522 3958.02,-106.015 3948.02,-102.522 3948.02,-109.522"/> +<text text-anchor="middle" x="1159.3" y="-275.3" font-family="Times,serif" font-size="14.00">[0x00-t][v-0xFF]</text> +</g> +<!-- 85 --> +<g id="node82" class="node"><title>85</title> +<ellipse fill="none" stroke="black" cx="1383.3" cy="-366" rx="27" ry="18"/> +<text text-anchor="middle" x="1383.3" y="-362.3" font-family="Times,serif" font-size="14.00">85</text> +</g> +<!-- 74->85 --> +<g id="edge120" class="edge"><title>74->85</title> +<path fill="none" stroke="black" d="M1182.42,-443.224C1222.52,-428.01 1305.02,-396.704 1350.83,-379.319"/> +<polygon fill="black" stroke="black" points="1352.19,-382.549 1360.29,-375.729 1349.7,-376.004 1352.19,-382.549"/> +<text text-anchor="middle" x="1293.3" y="-405.8" font-family="Times,serif" font-size="14.00">[u]</text> +</g> +<!-- 75->28 --> +<g id="edge121" class="edge"><title>75->28</title> +<path fill="none" stroke="black" d="M5517.81,-347.913C5520.98,-319.419 5522.87,-261.981 5493.3,-228 5400.75,-121.667 5327.88,-160.637 5188.3,-141 4954.99,-108.178 4199.16,-106.023 4022.48,-105.974"/> +<polygon fill="black" stroke="black" points="4022.38,-102.475 4012.38,-105.974 4022.38,-109.475 4022.38,-102.475"/> +<text text-anchor="middle" x="5552.8" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-k][m-0xFF]</text> +</g> +<!-- 86 --> +<g id="node83" class="node"><title>86</title> +<ellipse fill="none" stroke="black" cx="5229.3" cy="-279" rx="27" ry="18"/> +<text text-anchor="middle" x="5229.3" y="-275.3" font-family="Times,serif" font-size="14.00">86</text> +</g> +<!-- 75->86 --> +<g id="edge122" class="edge"><title>75->86</title> +<path fill="none" stroke="black" d="M5490.91,-357.753C5439.94,-342.604 5322,-307.551 5263.49,-290.162"/> +<polygon fill="black" stroke="black" points="5264.2,-286.723 5253.62,-287.229 5262.21,-293.433 5264.2,-286.723"/> +<text text-anchor="middle" x="5395.8" y="-318.8" font-family="Times,serif" font-size="14.00">[l]</text> +</g> +<!-- 76->27 --> +<g id="edge124" class="edge"><title>76->27</title> +<path fill="none" stroke="black" d="M5808.51,-273.035C5787.32,-269.145 5756.47,-263.919 5729.3,-261 5654.95,-253.013 5464.37,-266.217 5393.3,-243 5381.69,-239.211 5381.97,-231.565 5370.3,-228 5306.32,-208.459 4233.05,-214.322 4166.3,-210 4127.97,-207.519 4084.31,-202.196 4054.4,-198.163"/> +<polygon fill="black" stroke="black" points="4054.81,-194.687 4044.42,-196.797 4053.86,-201.622 4054.81,-194.687"/> +<text text-anchor="middle" x="5443.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 77 --> +<g id="node84" class="node"><title>77</title> +<ellipse fill="none" stroke="black" cx="5860.3" cy="-192" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="5860.3" y="-188.3" font-family="Times,serif" font-size="14.00">lexer.re:179</text> +</g> +<!-- 76->77 --> +<g id="edge123" class="edge"><title>76->77</title> +<path fill="none" stroke="black" d="M5820.99,-262.884C5813.84,-252.839 5807.55,-239.443 5813.3,-228 5815.99,-222.642 5819.93,-217.895 5824.4,-213.763"/> +<polygon fill="black" stroke="black" points="5826.72,-216.39 5832.31,-207.39 5822.33,-210.939 5826.72,-216.39"/> +<text text-anchor="middle" x="5894.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 78->28 --> +<g id="edge125" class="edge"><title>78->28</title> +<path fill="none" stroke="black" d="M2265.18,-347.93C2265.39,-325.2 2262.3,-285.069 2240.3,-261 2222.94,-242.018 2200.39,-263.824 2185.3,-243 2163.8,-213.348 2190.86,-193.55 2228.3,-174 2307.2,-132.794 3701.3,-110.22 3948.11,-106.538"/> +<polygon fill="black" stroke="black" points="3948.4,-110.034 3958.34,-106.386 3948.29,-103.035 3948.4,-110.034"/> +<text text-anchor="middle" x="2232.8" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-s][u-0xFF]</text> +</g> +<!-- 88 --> +<g id="node85" class="node"><title>88</title> +<ellipse fill="none" stroke="black" cx="2837.3" cy="-279" rx="27" ry="18"/> +<text text-anchor="middle" x="2837.3" y="-275.3" font-family="Times,serif" font-size="14.00">88</text> +</g> +<!-- 78->88 --> +<g id="edge126" class="edge"><title>78->88</title> +<path fill="none" stroke="black" d="M2290.4,-361.127C2382.78,-347.423 2694.33,-301.207 2801.07,-285.374"/> +<polygon fill="black" stroke="black" points="2801.65,-288.825 2811.03,-283.896 2800.63,-281.901 2801.65,-288.825"/> +<text text-anchor="middle" x="2591.8" y="-318.8" font-family="Times,serif" font-size="14.00">[t]</text> +</g> +<!-- 79->27 --> +<g id="edge128" class="edge"><title>79->27</title> +<path fill="none" stroke="black" d="M3744.87,-275.316C3777.89,-271.309 3835.47,-262.088 3881.3,-243 3892.56,-238.307 3893.24,-233.175 3904.3,-228 3929.77,-216.07 3960.33,-206.944 3983.39,-201.006"/> +<polygon fill="black" stroke="black" points="3984.24,-204.401 3993.09,-198.58 3982.54,-197.61 3984.24,-204.401"/> +<text text-anchor="middle" x="3954.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 80 --> +<g id="node86" class="node"><title>80</title> +<ellipse fill="none" stroke="black" cx="3718.3" cy="-192" rx="48.9926" ry="18"/> +<text text-anchor="middle" x="3718.3" y="-188.3" font-family="Times,serif" font-size="14.00">lexer.re:74</text> +</g> +<!-- 79->80 --> +<g id="edge127" class="edge"><title>79->80</title> +<path fill="none" stroke="black" d="M3718.3,-260.799C3718.3,-249.163 3718.3,-233.548 3718.3,-220.237"/> +<polygon fill="black" stroke="black" points="3721.8,-220.175 3718.3,-210.175 3714.8,-220.175 3721.8,-220.175"/> +<text text-anchor="middle" x="3799.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 81->27 --> +<g id="edge130" class="edge"><title>81->27</title> +<path fill="none" stroke="black" d="M4316.82,-266.852C4311.86,-264.571 4306.49,-262.433 4301.3,-261 4221.66,-239.038 4195.59,-266.178 4116.3,-243 4102.46,-238.955 4070.86,-222.294 4047.26,-209.302"/> +<polygon fill="black" stroke="black" points="4048.79,-206.148 4038.35,-204.361 4045.4,-212.27 4048.79,-206.148"/> +<text text-anchor="middle" x="4166.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 82 --> +<g id="node87" class="node"><title>82</title> +<ellipse fill="none" stroke="black" cx="4224.3" cy="-192" rx="48.9926" ry="18"/> +<text text-anchor="middle" x="4224.3" y="-188.3" font-family="Times,serif" font-size="14.00">lexer.re:95</text> +</g> +<!-- 81->82 --> +<g id="edge129" class="edge"><title>81->82</title> +<path fill="none" stroke="black" d="M4316.66,-267.357C4311.71,-265.056 4306.38,-262.782 4301.3,-261 4268.53,-249.526 4247.1,-270.011 4225.3,-243 4220.16,-236.635 4218.67,-228.182 4218.83,-220.041"/> +<polygon fill="black" stroke="black" points="4222.32,-220.362 4219.78,-210.075 4215.35,-219.699 4222.32,-220.362"/> +<text text-anchor="middle" x="4306.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 83->28 --> +<g id="edge131" class="edge"><title>83->28</title> +<path fill="none" stroke="black" d="M6325.79,-347.974C6325.9,-321.03 6323.28,-267.566 6303.3,-228 6262.88,-147.97 6210.15,-152.926 6121.3,-141 5905.68,-112.063 4291.12,-106.768 4022.98,-106.086"/> +<polygon fill="black" stroke="black" points="4022.62,-102.585 4012.61,-106.06 4022.6,-109.585 4022.62,-102.585"/> +<text text-anchor="middle" x="6356.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-d][f-0xFF]</text> +</g> +<!-- 90 --> +<g id="node88" class="node"><title>90</title> +<ellipse fill="none" stroke="black" cx="6246.3" cy="-279" rx="27" ry="18"/> +<text text-anchor="middle" x="6246.3" y="-275.3" font-family="Times,serif" font-size="14.00">90</text> +</g> +<!-- 83->90 --> +<g id="edge132" class="edge"><title>83->90</title> +<path fill="none" stroke="black" d="M6311.53,-350.194C6299.19,-336.909 6280.9,-317.228 6266.82,-302.084"/> +<polygon fill="black" stroke="black" points="6269.27,-299.578 6259.9,-294.636 6264.14,-304.344 6269.27,-299.578"/> +<text text-anchor="middle" x="6298.3" y="-318.8" font-family="Times,serif" font-size="14.00">[e]</text> +</g> +<!-- 84->28 --> +<g id="edge133" class="edge"><title>84->28</title> +<path fill="none" stroke="black" d="M1440.44,-434.835C1443,-407.701 1444.69,-353.98 1424.3,-315 1418.6,-304.108 1408.43,-308.168 1403.3,-297 1396.61,-282.464 1399.95,-276.646 1403.3,-261 1417.29,-195.546 1430.15,-160.125 1494.3,-141 1616.99,-104.417 3644.46,-105.566 3947.52,-105.944"/> +<polygon fill="black" stroke="black" points="3947.96,-109.444 3957.96,-105.957 3947.96,-102.444 3947.96,-109.444"/> +<text text-anchor="middle" x="1448.8" y="-275.3" font-family="Times,serif" font-size="14.00">[0x00-r][t-0xFF]</text> +</g> +<!-- 92 --> +<g id="node89" class="node"><title>92</title> +<ellipse fill="none" stroke="black" cx="1512.3" cy="-366" rx="27" ry="18"/> +<text text-anchor="middle" x="1512.3" y="-362.3" font-family="Times,serif" font-size="14.00">92</text> +</g> +<!-- 84->92 --> +<g id="edge134" class="edge"><title>84->92</title> +<path fill="none" stroke="black" d="M1451.52,-436.804C1462.89,-423.75 1479.44,-404.735 1492.4,-389.847"/> +<polygon fill="black" stroke="black" points="1495.25,-391.905 1499.18,-382.065 1489.97,-387.309 1495.25,-391.905"/> +<text text-anchor="middle" x="1487.8" y="-405.8" font-family="Times,serif" font-size="14.00">[s]</text> +</g> +<!-- 85->28 --> +<g id="edge135" class="edge"><title>85->28</title> +<path fill="none" stroke="black" d="M1377.03,-348.123C1372.96,-338.103 1367.13,-325.371 1360.3,-315 1336.57,-279.004 1310.77,-283.238 1295.3,-243 1272.32,-183.275 1323.37,-167.338 1389.3,-141 1451.44,-116.17 3633.7,-107.284 3947.79,-106.132"/> +<polygon fill="black" stroke="black" points="3948.18,-109.631 3958.17,-106.094 3948.15,-102.631 3948.18,-109.631"/> +<text text-anchor="middle" x="1342.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-d][f-0xFF]</text> +</g> +<!-- 93 --> +<g id="node90" class="node"><title>93</title> +<ellipse fill="none" stroke="black" cx="1615.3" cy="-279" rx="27" ry="18"/> +<text text-anchor="middle" x="1615.3" y="-275.3" font-family="Times,serif" font-size="14.00">93</text> +</g> +<!-- 85->93 --> +<g id="edge136" class="edge"><title>85->93</title> +<path fill="none" stroke="black" d="M1406.39,-356.539C1447.8,-341.367 1534.79,-309.494 1582.42,-292.046"/> +<polygon fill="black" stroke="black" points="1583.77,-295.279 1591.95,-288.553 1581.36,-288.707 1583.77,-295.279"/> +<text text-anchor="middle" x="1521.3" y="-318.8" font-family="Times,serif" font-size="14.00">[e]</text> +</g> +<!-- 86->27 --> +<g id="edge138" class="edge"><title>86->27</title> +<path fill="none" stroke="black" d="M5205.18,-270.729C5165.43,-259.133 5083.46,-236.861 5012.3,-228 4825.69,-204.767 4353.91,-222.743 4166.3,-210 4127.98,-207.397 4084.32,-202.094 4054.4,-198.099"/> +<polygon fill="black" stroke="black" points="4054.81,-194.622 4044.43,-196.747 4053.87,-201.559 4054.81,-194.622"/> +<text text-anchor="middle" x="5146.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 87 --> +<g id="node91" class="node"><title>87</title> +<ellipse fill="none" stroke="black" cx="5255.3" cy="-192" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="5255.3" y="-188.3" font-family="Times,serif" font-size="14.00">lexer.re:205</text> +</g> +<!-- 86->87 --> +<g id="edge137" class="edge"><title>86->87</title> +<path fill="none" stroke="black" d="M5215.99,-262.884C5208.84,-252.839 5202.55,-239.443 5208.3,-228 5210.99,-222.642 5214.93,-217.895 5219.4,-213.763"/> +<polygon fill="black" stroke="black" points="5221.72,-216.39 5227.31,-207.39 5217.33,-210.939 5221.72,-216.39"/> +<text text-anchor="middle" x="5289.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 88->27 --> +<g id="edge140" class="edge"><title>88->27</title> +<path fill="none" stroke="black" d="M2863.86,-275.72C2914.55,-271.154 3028.49,-259.86 3123.3,-243 3152.06,-237.885 3158.33,-231.798 3187.3,-228 3446.97,-193.949 3514.73,-223.179 3776.3,-210 3849.03,-206.335 3933.92,-199.865 3981.36,-196.051"/> +<polygon fill="black" stroke="black" points="3981.77,-199.529 3991.46,-195.234 3981.21,-192.552 3981.77,-199.529"/> +<text text-anchor="middle" x="3237.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 89 --> +<g id="node92" class="node"><title>89</title> +<ellipse fill="none" stroke="black" cx="2837.3" cy="-192" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="2837.3" y="-188.3" font-family="Times,serif" font-size="14.00">lexer.re:102</text> +</g> +<!-- 88->89 --> +<g id="edge139" class="edge"><title>88->89</title> +<path fill="none" stroke="black" d="M2837.3,-260.799C2837.3,-249.163 2837.3,-233.548 2837.3,-220.237"/> +<polygon fill="black" stroke="black" points="2840.8,-220.175 2837.3,-210.175 2833.8,-220.175 2840.8,-220.175"/> +<text text-anchor="middle" x="2918.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 90->27 --> +<g id="edge142" class="edge"><title>90->27</title> +<path fill="none" stroke="black" d="M6225.06,-267.511C6218.84,-264.904 6211.92,-262.444 6205.3,-261 6096.88,-237.375 5816.65,-254.56 5706.3,-243 5667.71,-238.958 5658.93,-231.585 5620.3,-228 5298.54,-198.143 4488.78,-230.464 4166.3,-210 4127.97,-207.568 4084.31,-202.237 4054.4,-198.189"/> +<polygon fill="black" stroke="black" points="4054.81,-194.713 4044.42,-196.818 4053.85,-201.648 4054.81,-194.713"/> +<text text-anchor="middle" x="5756.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 91 --> +<g id="node93" class="node"><title>91</title> +<ellipse fill="none" stroke="black" cx="6188.3" cy="-192" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="6188.3" y="-188.3" font-family="Times,serif" font-size="14.00">lexer.re:186</text> +</g> +<!-- 90->91 --> +<g id="edge141" class="edge"><title>90->91</title> +<path fill="none" stroke="black" d="M6224.35,-268.337C6218.24,-265.801 6211.56,-263.17 6205.3,-261 6177.38,-251.324 6159.14,-266.553 6141.3,-243 6133.48,-232.684 6140.76,-222.119 6151.73,-213.375"/> +<polygon fill="black" stroke="black" points="6154.08,-216 6160.21,-207.359 6150.03,-210.291 6154.08,-216"/> +<text text-anchor="middle" x="6222.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 92->28 --> +<g id="edge143" class="edge"><title>92->28</title> +<path fill="none" stroke="black" d="M1515.16,-348.01C1517.96,-325.369 1519.17,-285.341 1498.3,-261 1479.9,-239.542 1454.22,-265.64 1437.3,-243 1433.3,-237.66 1434.63,-234.109 1437.3,-228 1460.09,-175.839 1478.44,-162.141 1531.3,-141 1589.91,-117.554 3644.35,-107.518 3947.96,-106.161"/> +<polygon fill="black" stroke="black" points="3948.03,-109.661 3958.02,-106.117 3948,-102.661 3948.03,-109.661"/> +<text text-anchor="middle" x="1484.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-d][f-0xFF]</text> +</g> +<!-- 95 --> +<g id="node94" class="node"><title>95</title> +<ellipse fill="none" stroke="black" cx="1955.3" cy="-279" rx="27" ry="18"/> +<text text-anchor="middle" x="1955.3" y="-275.3" font-family="Times,serif" font-size="14.00">95</text> +</g> +<!-- 92->95 --> +<g id="edge144" class="edge"><title>92->95</title> +<path fill="none" stroke="black" d="M1538.03,-360.063C1613.35,-345.609 1833.52,-303.366 1919.91,-286.789"/> +<polygon fill="black" stroke="black" points="1920.61,-290.22 1929.77,-284.898 1919.29,-283.345 1920.61,-290.22"/> +<text text-anchor="middle" x="1769.3" y="-318.8" font-family="Times,serif" font-size="14.00">[e]</text> +</g> +<!-- 93->27 --> +<g id="edge146" class="edge"><title>93->27</title> +<path fill="none" stroke="black" d="M1639.73,-270.965C1653.8,-267.254 1671.9,-263.054 1688.3,-261 1785.45,-248.831 2477.13,-276.054 2569.3,-243 2579.42,-239.368 2578.16,-231.605 2588.3,-228 2650.49,-205.88 3710.35,-212.814 3776.3,-210 3849.06,-206.895 3933.94,-200.228 3981.37,-196.228"/> +<polygon fill="black" stroke="black" points="3981.8,-199.704 3991.46,-195.369 3981.2,-192.73 3981.8,-199.704"/> +<text text-anchor="middle" x="2638.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 94 --> +<g id="node95" class="node"><title>94</title> +<ellipse fill="none" stroke="black" cx="1626.3" cy="-192" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="1626.3" y="-188.3" font-family="Times,serif" font-size="14.00">lexer.re:144</text> +</g> +<!-- 93->94 --> +<g id="edge145" class="edge"><title>93->94</title> +<path fill="none" stroke="black" d="M1596.93,-265.769C1584.81,-256.061 1572.34,-241.861 1579.3,-228 1581.99,-222.642 1585.93,-217.895 1590.4,-213.763"/> +<polygon fill="black" stroke="black" points="1592.72,-216.39 1598.31,-207.39 1588.33,-210.939 1592.72,-216.39"/> +<text text-anchor="middle" x="1660.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +<!-- 95->27 --> +<g id="edge148" class="edge"><title>95->27</title> +<path fill="none" stroke="black" d="M1981.52,-274.56C2012.82,-270.598 2066.78,-264.221 2113.3,-261 2241.72,-252.108 2565.91,-267.426 2692.3,-243 2711.35,-239.318 2714.22,-231.55 2733.3,-228 2847.25,-206.794 3660.5,-215.063 3776.3,-210 3849.06,-206.819 3933.94,-200.179 3981.37,-196.204"/> +<polygon fill="black" stroke="black" points="3981.79,-199.68 3991.46,-195.351 3981.2,-192.705 3981.79,-199.68"/> +<text text-anchor="middle" x="2783.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0-9][A-Z][_][a-z]</text> +</g> +<!-- 96 --> +<g id="node96" class="node"><title>96</title> +<ellipse fill="none" stroke="black" cx="1981.3" cy="-192" rx="53.0913" ry="18"/> +<text text-anchor="middle" x="1981.3" y="-188.3" font-family="Times,serif" font-size="14.00">lexer.re:151</text> +</g> +<!-- 95->96 --> +<g id="edge147" class="edge"><title>95->96</title> +<path fill="none" stroke="black" d="M1941.99,-262.884C1934.84,-252.839 1928.55,-239.443 1934.3,-228 1936.99,-222.642 1940.93,-217.895 1945.4,-213.763"/> +<polygon fill="black" stroke="black" points="1947.72,-216.39 1953.31,-207.39 1943.33,-210.939 1947.72,-216.39"/> +<text text-anchor="middle" x="2015.3" y="-231.8" font-family="Times,serif" font-size="14.00">[0x00-/][:-@][[-^][`][{-0xFF]</text> +</g> +</g> +</svg> diff --git a/src/asm/lexdump.cpp b/src/asm/lexdump.cpp new file mode 100644 index 0000000..440ff1e --- /dev/null +++ b/src/asm/lexdump.cpp @@ -0,0 +1,83 @@ +#include <iomanip> +#include <iostream> + +#include <cassert> + +#include "lexer.hpp" +#include "token.hpp" + +using namespace SpasmImpl::ASM::Lexer; + +#define TOKENS \ + TOK(push) \ + TOK(pop) \ + TOK(dup) \ + TOK(print) \ + TOK(read) \ + TOK(plus) \ + TOK(minus) \ + TOK(multiply) \ + TOK(divide) \ + TOK(modulus) \ + TOK(gotrue) \ + TOK(gofalse) \ + TOK(go) \ + TOK(call) \ + TOK(ret) \ + TOK(load) \ + TOK(store) \ + TOK(label) \ + TOK(ident) \ + TOK(integer) \ + TOK(xinteger) \ + TOK(endinput) + +class TokenDumper : public TokenStream +{ + public: + TokenDumper() : end_reached(false) {} + void push_token(const Token& token) + { + Token::Token_type ttype = token.type(); + std::cout.width(8); + std::cout << token.lineno(); + std::cout << ": " << token_name[ttype]; + if (ttype == Token::integer || ttype == Token::xinteger) + std::cout << '|' << token.value_int() << '|'; + else if (ttype == Token::ident) + std::cout << '|' << token.value_str() << '|'; + std::cout << std::endl; + if (token.type() == Token::endinput) + end_reached = true; + } + + bool input_end() const { return end_reached; } + + private: + bool end_reached; + + static const char* token_name[24]; +}; + +const char* TokenDumper::token_name[24] = {"halt", +#define TOK(x) #x, + TOKENS +#undef TOK + "notused!!!"}; + +int main() +{ + Lexer lex(std::cin); + TokenDumper td; + Token token; + + lex.buffer_init(); + + while (!td.input_end()) + { + lex.read(1); + lex.tokenize(td); + } + + return 0; +} diff --git a/src/asm/lexdump3.cpp b/src/asm/lexdump3.cpp new file mode 100644 index 0000000..4e4ce9e --- /dev/null +++ b/src/asm/lexdump3.cpp @@ -0,0 +1,62 @@ +#include <iomanip> +#include <iostream> + +#include <cassert> + +#include "token.hpp" +#include "tokenizer.hpp" + +using namespace SpasmImpl::ASM::Lexer; + +#define TOKENS \ + TOK(push) \ + TOK(pop) \ + TOK(dup) \ + TOK(print) \ + TOK(read) \ + TOK(plus) \ + TOK(minus) \ + TOK(multiply) \ + TOK(divide) \ + TOK(modulus) \ + TOK(gotrue) \ + TOK(gofalse) \ + TOK(go) \ + TOK(call) \ + TOK(ret) \ + TOK(load) \ + TOK(store) \ + TOK(label) \ + TOK(ident) \ + TOK(integer) \ + TOK(xinteger) \ + TOK(endinput) + +const char* token_name[24] = {"halt", +#define TOK(x) #x, + TOKENS +#undef TOK + "notused!!!"}; + +int main() +{ + Tokenizer td(std::cin); + Token token; + + token = td.next_token(); + while (token.type() != Token::endinput) + { + token = td.next_token(); + Token::Token_type ttype = token.type(); + std::cout.width(8); + std::cout << token.lineno(); + std::cout << ": " << token_name[ttype]; + if (ttype == Token::integer || ttype == Token::xinteger) + std::cout << '|' << token.value_int() << '|'; + else if (ttype == Token::ident) + std::cout << '|' << token.value_str() << '|'; + std::cout << std::endl; + } + + return 0; +} diff --git a/src/asm/lexer.cpp b/src/asm/lexer.cpp new file mode 100644 index 0000000..ef650e4 --- /dev/null +++ b/src/asm/lexer.cpp @@ -0,0 +1,1123 @@ +/* Generated by re2c 0.13.5 on Wed Jun 25 12:01:36 2008 */ +#line 1 "lexer.re" +#include <iostream> + +#include "lexer.hpp" + +#include "token.hpp" + +namespace SpasmImpl +{ +namespace ASM +{ +//! Namespace for all lexical analisys classes +namespace Lexer +{ +Lexer::Lexer(std::istream& _file, size_t _buffer_size) + : file(&_file), buffer_size(_buffer_size), state(unsigned(-1)), lineno(0) +{ + buffer = new char[buffer_size]; + cursor = limit = marker = token_start = NULL; +} + +Lexer::~Lexer() +{ + delete[] buffer; +} + +bool Lexer::tokenize(TokenStream& ts) +{ +#line 43 "lexer.re" + + switch (state) + { + default: + goto yy0; + case 0: + goto yyFillLabel0; + case 1: + goto yyFillLabel1; + case 2: + goto yyFillLabel2; + case 3: + goto yyFillLabel3; + case 4: + goto yyFillLabel4; + } + + while (1) + { +#line 48 "lexer.cpp" + + yy0: + state = (0); + if ((limit - cursor) < 8) + return true; + yyFillLabel0: + yych = *cursor; + if (yych <= '<') + { + if (yych <= ')') + { + if (yych <= '\n') + { + if (yych <= 0x00) + goto yy30; + if (yych <= 0x08) + goto yy32; + if (yych <= '\t') + goto yy26; + goto yy28; + } + else + { + if (yych <= ' ') + { + if (yych <= 0x1F) + goto yy32; + goto yy26; + } + else + { + if (yych == '%') + goto yy17; + goto yy32; + } + } + } + else + { + if (yych <= '.') + { + if (yych <= '+') + { + if (yych <= '*') + goto yy13; + goto yy11; + } + else + { + if (yych != '-') + goto yy32; + } + } + else + { + if (yych <= '0') + { + if (yych <= '/') + goto yy15; + goto yy4; + } + else + { + if (yych <= '9') + goto yy6; + if (yych <= ';') + goto yy32; + goto yy23; + } + } + } + } + else + { + if (yych <= 'f') + { + if (yych <= '_') + { + if (yych <= '@') + goto yy32; + if (yych <= 'Z') + goto yy25; + if (yych <= '^') + goto yy32; + goto yy25; + } + else + { + if (yych <= 'b') + { + if (yych <= '`') + goto yy32; + goto yy25; + } + else + { + if (yych <= 'c') + goto yy20; + if (yych <= 'd') + goto yy9; + goto yy25; + } + } + } + else + { + if (yych <= 'p') + { + if (yych <= 'k') + { + if (yych <= 'g') + goto yy19; + goto yy25; + } + else + { + if (yych <= 'l') + goto yy21; + if (yych <= 'o') + goto yy25; + goto yy7; + } + } + else + { + if (yych <= 'r') + { + if (yych <= 'q') + goto yy25; + goto yy10; + } + else + { + if (yych <= 's') + goto yy22; + if (yych <= 'z') + goto yy25; + goto yy32; + } + } + } + } + ++cursor; + if ((yych = *cursor) == '0') + goto yy99; +#line 116 "lexer.re" + { + ts.push_token(Token(Token::minus, lineno)); + token_start = cursor; + + continue; + } +#line 138 "lexer.cpp" + yy4: + yych = *(marker = ++cursor); + if (yych == 'X') + goto yy94; + if (yych == 'x') + goto yy94; + yy5: +#line 58 "lexer.re" + { + ts.push_token(Token(Token::integer, lineno, token_start, cursor)); + token_start = cursor; + + continue; + } +#line 152 "lexer.cpp" + yy6: + yych = *++cursor; + goto yy93; + yy7: + ++cursor; + if ((yych = *cursor) <= 'q') + { + if (yych == 'o') + goto yy80; + goto yy37; + } + else + { + if (yych <= 'r') + goto yy81; + if (yych == 'u') + goto yy82; + goto yy37; + } + yy8: +#line 212 "lexer.re" + { + ts.push_token(Token(Token::ident, lineno, token_start, cursor)); + token_start = cursor; + + continue; + } +#line 175 "lexer.cpp" + yy9: + yych = *++cursor; + if (yych == 'u') + goto yy77; + goto yy37; + yy10: + yych = *++cursor; + if (yych == 'e') + goto yy71; + goto yy37; + yy11: + ++cursor; +#line 109 "lexer.re" + { + ts.push_token(Token(Token::plus, lineno)); + token_start = cursor; + + continue; + } +#line 193 "lexer.cpp" + yy13: + ++cursor; +#line 123 "lexer.re" + { + ts.push_token(Token(Token::multiply, lineno)); + token_start = cursor; + + continue; + } +#line 203 "lexer.cpp" + yy15: + ++cursor; +#line 130 "lexer.re" + { + ts.push_token(Token(Token::divide, lineno)); + token_start = cursor; + + continue; + } +#line 213 "lexer.cpp" + yy17: + ++cursor; +#line 137 "lexer.re" + { + ts.push_token(Token(Token::modulus, lineno)); + token_start = cursor; + + continue; + } +#line 223 "lexer.cpp" + yy19: + yych = *++cursor; + if (yych == 'o') + goto yy58; + goto yy37; + yy20: + yych = *++cursor; + if (yych == 'a') + goto yy54; + goto yy37; + yy21: + yych = *++cursor; + if (yych == 'a') + goto yy45; + if (yych == 'o') + goto yy46; + goto yy37; + yy22: + yych = *++cursor; + if (yych == 't') + goto yy40; + goto yy37; + yy23: + ++cursor; + if ((yych = *cursor) == '=') + goto yy38; +#line 198 "lexer.re" + { + ts.push_token(Token(Token::less, lineno)); + token_start = cursor; + + continue; + } +#line 251 "lexer.cpp" + yy25: + yych = *++cursor; + goto yy37; + yy26: + ++cursor; + yych = *cursor; + goto yy35; + yy27: +#line 220 "lexer.re" + { + token_start = cursor; + + continue; + } +#line 266 "lexer.cpp" + yy28: + ++cursor; +#line 226 "lexer.re" + { + ++lineno; + token_start = cursor; + + continue; + } +#line 276 "lexer.cpp" + yy30: + ++cursor; +#line 233 "lexer.re" + { + ts.push_token(Token(Token::endinput, lineno)); + + break; + } +#line 285 "lexer.cpp" + yy32: + ++cursor; +#line 239 "lexer.re" + { + return false; + } +#line 292 "lexer.cpp" + yy34: + ++cursor; + state = (1); + if (limit <= cursor) + return true; + yyFillLabel1: + yych = *cursor; + yy35: + if (yych == '\t') + goto yy34; + if (yych == ' ') + goto yy34; + goto yy27; + yy36: + ++cursor; + state = (2); + if (limit <= cursor) + return true; + yyFillLabel2: + yych = *cursor; + yy37: + if (yych <= 'Z') + { + if (yych <= '/') + goto yy8; + if (yych <= '9') + goto yy36; + if (yych <= '@') + goto yy8; + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych <= '^') + goto yy8; + goto yy36; + } + else + { + if (yych <= '`') + goto yy8; + if (yych <= 'z') + goto yy36; + goto yy8; + } + } + yy38: + ++cursor; +#line 192 "lexer.re" + { + ts.push_token(Token(Token::lesseq, lineno)); + token_start = cursor; + + continue; + } +#line 334 "lexer.cpp" + yy40: + yych = *++cursor; + if (yych != 'o') + goto yy37; + yych = *++cursor; + if (yych != 'r') + goto yy37; + yych = *++cursor; + if (yych != 'e') + goto yy37; + ++cursor; + if ((yych = *cursor) <= 'Z') + { + if (yych <= '/') + goto yy44; + if (yych <= '9') + goto yy36; + if (yych >= 'A') + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych >= '_') + goto yy36; + } + else + { + if (yych <= '`') + goto yy44; + if (yych <= 'z') + goto yy36; + } + } + yy44: +#line 186 "lexer.re" + { + ts.push_token(Token(Token::store, lineno)); + token_start = cursor; + + continue; + } +#line 363 "lexer.cpp" + yy45: + yych = *++cursor; + if (yych == 'b') + goto yy50; + goto yy37; + yy46: + yych = *++cursor; + if (yych != 'a') + goto yy37; + yych = *++cursor; + if (yych != 'd') + goto yy37; + ++cursor; + if ((yych = *cursor) <= 'Z') + { + if (yych <= '/') + goto yy49; + if (yych <= '9') + goto yy36; + if (yych >= 'A') + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych >= '_') + goto yy36; + } + else + { + if (yych <= '`') + goto yy49; + if (yych <= 'z') + goto yy36; + } + } + yy49: +#line 179 "lexer.re" + { + ts.push_token(Token(Token::load, lineno)); + token_start = cursor; + + continue; + } +#line 394 "lexer.cpp" + yy50: + yych = *++cursor; + if (yych != 'e') + goto yy37; + yych = *++cursor; + if (yych != 'l') + goto yy37; + ++cursor; + if ((yych = *cursor) <= 'Z') + { + if (yych <= '/') + goto yy53; + if (yych <= '9') + goto yy36; + if (yych >= 'A') + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych >= '_') + goto yy36; + } + else + { + if (yych <= '`') + goto yy53; + if (yych <= 'z') + goto yy36; + } + } + yy53: +#line 205 "lexer.re" + { + ts.push_token(Token(Token::label, lineno)); + token_start = cursor; + + continue; + } +#line 421 "lexer.cpp" + yy54: + yych = *++cursor; + if (yych != 'l') + goto yy37; + yych = *++cursor; + if (yych != 'l') + goto yy37; + ++cursor; + if ((yych = *cursor) <= 'Z') + { + if (yych <= '/') + goto yy57; + if (yych <= '9') + goto yy36; + if (yych >= 'A') + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych >= '_') + goto yy36; + } + else + { + if (yych <= '`') + goto yy57; + if (yych <= 'z') + goto yy36; + } + } + yy57: +#line 165 "lexer.re" + { + ts.push_token(Token(Token::call, lineno)); + token_start = cursor; + + continue; + } +#line 448 "lexer.cpp" + yy58: + ++cursor; + if ((yych = *cursor) <= '_') + { + if (yych <= '@') + { + if (yych <= '/') + goto yy59; + if (yych <= '9') + goto yy36; + } + else + { + if (yych <= 'Z') + goto yy36; + if (yych >= '_') + goto yy36; + } + } + else + { + if (yych <= 'f') + { + if (yych <= '`') + goto yy59; + if (yych <= 'e') + goto yy36; + goto yy61; + } + else + { + if (yych == 't') + goto yy60; + if (yych <= 'z') + goto yy36; + } + } + yy59: +#line 158 "lexer.re" + { + ts.push_token(Token(Token::go, lineno)); + token_start = cursor; + + continue; + } +#line 477 "lexer.cpp" + yy60: + yych = *++cursor; + if (yych == 'r') + goto yy67; + goto yy37; + yy61: + yych = *++cursor; + if (yych != 'a') + goto yy37; + yych = *++cursor; + if (yych != 'l') + goto yy37; + yych = *++cursor; + if (yych != 's') + goto yy37; + yych = *++cursor; + if (yych != 'e') + goto yy37; + ++cursor; + if ((yych = *cursor) <= 'Z') + { + if (yych <= '/') + goto yy66; + if (yych <= '9') + goto yy36; + if (yych >= 'A') + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych >= '_') + goto yy36; + } + else + { + if (yych <= '`') + goto yy66; + if (yych <= 'z') + goto yy36; + } + } + yy66: +#line 151 "lexer.re" + { + ts.push_token(Token(Token::gofalse, lineno)); + token_start = cursor; + + continue; + } +#line 512 "lexer.cpp" + yy67: + yych = *++cursor; + if (yych != 'u') + goto yy37; + yych = *++cursor; + if (yych != 'e') + goto yy37; + ++cursor; + if ((yych = *cursor) <= 'Z') + { + if (yych <= '/') + goto yy70; + if (yych <= '9') + goto yy36; + if (yych >= 'A') + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych >= '_') + goto yy36; + } + else + { + if (yych <= '`') + goto yy70; + if (yych <= 'z') + goto yy36; + } + } + yy70: +#line 144 "lexer.re" + { + ts.push_token(Token(Token::gotrue, lineno)); + token_start = cursor; + + continue; + } +#line 539 "lexer.cpp" + yy71: + yych = *++cursor; + if (yych == 'a') + goto yy72; + if (yych == 't') + goto yy73; + goto yy37; + yy72: + yych = *++cursor; + if (yych == 'd') + goto yy75; + goto yy37; + yy73: + ++cursor; + if ((yych = *cursor) <= 'Z') + { + if (yych <= '/') + goto yy74; + if (yych <= '9') + goto yy36; + if (yych >= 'A') + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych >= '_') + goto yy36; + } + else + { + if (yych <= '`') + goto yy74; + if (yych <= 'z') + goto yy36; + } + } + yy74: +#line 172 "lexer.re" + { + ts.push_token(Token(Token::ret, lineno)); + token_start = cursor; + + continue; + } +#line 571 "lexer.cpp" + yy75: + ++cursor; + if ((yych = *cursor) <= 'Z') + { + if (yych <= '/') + goto yy76; + if (yych <= '9') + goto yy36; + if (yych >= 'A') + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych >= '_') + goto yy36; + } + else + { + if (yych <= '`') + goto yy76; + if (yych <= 'z') + goto yy36; + } + } + yy76: +#line 95 "lexer.re" + { + ts.push_token(Token(Token::read, lineno)); + token_start = cursor; + + continue; + } +#line 594 "lexer.cpp" + yy77: + yych = *++cursor; + if (yych != 'p') + goto yy37; + ++cursor; + if ((yych = *cursor) <= 'Z') + { + if (yych <= '/') + goto yy79; + if (yych <= '9') + goto yy36; + if (yych >= 'A') + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych >= '_') + goto yy36; + } + else + { + if (yych <= '`') + goto yy79; + if (yych <= 'z') + goto yy36; + } + } + yy79: +#line 88 "lexer.re" + { + ts.push_token(Token(Token::dup, lineno)); + token_start = cursor; + + continue; + } +#line 619 "lexer.cpp" + yy80: + yych = *++cursor; + if (yych == 'p') + goto yy90; + goto yy37; + yy81: + yych = *++cursor; + if (yych == 'i') + goto yy86; + goto yy37; + yy82: + yych = *++cursor; + if (yych != 's') + goto yy37; + yych = *++cursor; + if (yych != 'h') + goto yy37; + ++cursor; + if ((yych = *cursor) <= 'Z') + { + if (yych <= '/') + goto yy85; + if (yych <= '9') + goto yy36; + if (yych >= 'A') + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych >= '_') + goto yy36; + } + else + { + if (yych <= '`') + goto yy85; + if (yych <= 'z') + goto yy36; + } + } + yy85: +#line 74 "lexer.re" + { + ts.push_token(Token(Token::push, lineno)); + token_start = cursor; + + continue; + } +#line 654 "lexer.cpp" + yy86: + yych = *++cursor; + if (yych != 'n') + goto yy37; + yych = *++cursor; + if (yych != 't') + goto yy37; + ++cursor; + if ((yych = *cursor) <= 'Z') + { + if (yych <= '/') + goto yy89; + if (yych <= '9') + goto yy36; + if (yych >= 'A') + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych >= '_') + goto yy36; + } + else + { + if (yych <= '`') + goto yy89; + if (yych <= 'z') + goto yy36; + } + } + yy89: +#line 102 "lexer.re" + { + ts.push_token(Token(Token::print, lineno)); + token_start = cursor; + + continue; + } +#line 681 "lexer.cpp" + yy90: + ++cursor; + if ((yych = *cursor) <= 'Z') + { + if (yych <= '/') + goto yy91; + if (yych <= '9') + goto yy36; + if (yych >= 'A') + goto yy36; + } + else + { + if (yych <= '_') + { + if (yych >= '_') + goto yy36; + } + else + { + if (yych <= '`') + goto yy91; + if (yych <= 'z') + goto yy36; + } + } + yy91: +#line 81 "lexer.re" + { + ts.push_token(Token(Token::pop, lineno)); + token_start = cursor; + + continue; + } +#line 704 "lexer.cpp" + yy92: + ++cursor; + state = (3); + if (limit <= cursor) + return true; + yyFillLabel3: + yych = *cursor; + yy93: + if (yych <= '/') + goto yy5; + if (yych <= '9') + goto yy92; + goto yy5; + yy94: + yych = *++cursor; + if (yych <= '@') + { + if (yych <= '/') + goto yy95; + if (yych <= '9') + goto yy96; + } + else + { + if (yych <= 'F') + goto yy96; + if (yych <= '`') + goto yy95; + if (yych <= 'f') + goto yy96; + } + yy95: + cursor = marker; + goto yy5; + yy96: + ++cursor; + state = (4); + if (limit <= cursor) + return true; + yyFillLabel4: + yych = *cursor; + if (yych <= '@') + { + if (yych <= '/') + goto yy98; + if (yych <= '9') + goto yy96; + } + else + { + if (yych <= 'F') + goto yy96; + if (yych <= '`') + goto yy98; + if (yych <= 'f') + goto yy96; + } + yy98: +#line 66 "lexer.re" + { + ts.push_token(Token(Token::xinteger, lineno, token_start, cursor)); + token_start = cursor; + + continue; + } +#line 751 "lexer.cpp" + yy99: + ++cursor; + yych = *cursor; + goto yy5; +#line 243 "lexer.re" + } + return true; +} + +/*! +** Fills up the buffer when neccessary. +** Note the buffer is always filled to the maximum, not just the +** number of bytes neccessary for the lexer to continue. +** +** \param nbytes - the number of bytes +*/ + +void Lexer::buffer_grow(size_t new_size) +{ + char* new_buffer = new char[new_size]; + + std::copy(buffer, limit, new_buffer); + + token_start = new_buffer + (token_start - buffer); + cursor = new_buffer + (cursor - buffer); + limit = new_buffer + new_size; + + buffer_size = new_size; + + delete[] buffer; + buffer = new_buffer; +} + +void Lexer::read(size_t nbytes) +{ + if (token_start + nbytes > limit) + { // we need larger buffer + buffer_grow(token_start - buffer + nbytes); + } + + std::copy(token_start, limit, buffer); + cursor -= token_start - buffer; + char* old_limit = limit - (token_start - buffer); + token_start = buffer; + + file->read(old_limit, limit - old_limit); + if (file->eof()) + { + size_t bytes = file->gcount(); + std::fill(old_limit + bytes, limit, '\0'); + } +} + +void Lexer::buffer_init() +{ + file->read(buffer, buffer_size); + if (file->eof()) + { + size_t bytes = file->gcount(); + std::fill(buffer + bytes, buffer + buffer_size, '\0'); + } + + cursor = marker = token_start = buffer; + limit = buffer + buffer_size; +} + +} // namespace Lexer + +} // namespace ASM +} // namespace SpasmImpl diff --git a/src/asm/lexer.hpp b/src/asm/lexer.hpp new file mode 100644 index 0000000..ece4a07 --- /dev/null +++ b/src/asm/lexer.hpp @@ -0,0 +1,70 @@ +#ifndef LEXER_HPP +#define LEXER_HPP + +#include <iostream> + +#include "token.hpp" + +namespace SpasmImpl +{ +// ! Namespace for all classes and functions dealing with assembler +namespace ASM +{ +//! Namespace for all lexical analisys classes +namespace Lexer +{ +/*! +** Class for lexers for the assembler-like language for spasm +*/ +class Lexer +{ + public: + Lexer(std::istream&, size_t = 4096); + ~Lexer(); + bool tokenize(TokenStream&); + + //! fills the buffer called when the lexer needs more data + void read(size_t = 1); + void buffer_init(); + + private: + Lexer(const Lexer&); + Lexer& operator=(const Lexer&); + + void buffer_grow(size_t); + + //! input stream for the lexer + std::istream* file; + + //! buffer for the lexer + char* buffer; + + //! size of the buffer + size_t buffer_size; + + //! cursor for re2c generated lexer + char* cursor; + + //! limit for re2c generated lexer + char* limit; + + //! marker for re2c generated lexer + char* marker; + + //! pointer to the start of the just recognized token + char* token_start; + + //! saves the state of the lexer + unsigned int state; + + //! current char + char yych; + + //! number of current line + size_t lineno; +}; +} // namespace Lexer +} // namespace ASM +} // namespace SpasmImpl + +#endif diff --git a/src/asm/lexer.re b/src/asm/lexer.re new file mode 100644 index 0000000..5e21796 --- /dev/null +++ b/src/asm/lexer.re @@ -0,0 +1,307 @@ +#include <iostream> + +#include "lexer.hpp" + +#include "token.hpp" + +namespace SpasmImpl +{ + namespace ASM + { + //! Namespace for all lexical analisys classes + namespace Lexer + { + + Lexer::Lexer (std::istream & _file, size_t _buffer_size) + : file (&_file), buffer_size (_buffer_size), state (unsigned(-1)), + lineno (0) + { + buffer = new char[buffer_size]; + cursor = limit = marker = token_start = NULL; + } + + Lexer::~Lexer () + { + delete [] buffer; + } + + bool Lexer::tokenize (TokenStream &ts) + { +/*!re2c +re2c:indent:top = 5; + +re2c:define:YYFILL="return true;"; +re2c:define:YYFILL:naked=1; +re2c:define:YYCTYPE="char"; +re2c:define:YYCURSOR=cursor; +re2c:define:YYLIMIT=limit; +re2c:define:YYMARKER=marker; +re2c:define:YYGETSTATE=state; +re2c:define:YYGETSTATE:naked=1; +re2c:define:YYSETSTATE="state = "; +re2c:define:YYSETSTATE:naked=1; +*/ + +/*!getstate:re2c */ + + while (1) { + +/*!re2c + +DIGIT = [0-9] ; +XDIGIT = [0-9a-fA-F] ; + +INTEGER = "-"? "0" | ([1-9] DIGIT*) ; +XINTEGER = "0" [xX] XDIGIT+ ; +IDENTIFIER = [a-zA-Z_] [0-9a-zA-Z_]* ; + +INTEGER { + ts.push_token (Token (Token::integer, lineno, + token_start, cursor)); + token_start = cursor; + + continue; + } + +XINTEGER { + ts.push_token (Token (Token::xinteger, lineno, + token_start, cursor)); + token_start = cursor; + + continue; + } + +"push" { + ts.push_token (Token (Token::push, lineno)); + token_start = cursor; + + continue; + } + +"pop" { + ts.push_token (Token (Token::pop, lineno)); + token_start = cursor; + + continue; + } + +"dup" { + ts.push_token (Token (Token::dup, lineno)); + token_start = cursor; + + continue; + } + +"read" { + ts.push_token (Token (Token::read, lineno)); + token_start = cursor; + + continue; + } + +"print" { + ts.push_token (Token (Token::print, lineno)); + token_start = cursor; + + continue; + } + +"+" { + ts.push_token (Token (Token::plus, lineno)); + token_start = cursor; + + continue; + } + +"-" { + ts.push_token (Token (Token::minus, lineno)); + token_start = cursor; + + continue; + } + +"*" { + ts.push_token (Token (Token::multiply, lineno)); + token_start = cursor; + + continue; + } + +"/" { + ts.push_token (Token (Token::divide, lineno)); + token_start = cursor; + + continue; + } + +"%" { + ts.push_token (Token (Token::modulus, lineno)); + token_start = cursor; + + continue; + } + +"gotrue" { + ts.push_token (Token (Token::gotrue, lineno)); + token_start = cursor; + + continue; + } + +"gofalse" { + ts.push_token (Token (Token::gofalse, lineno)); + token_start = cursor; + + continue; + } + +"go" { + ts.push_token (Token (Token::go, lineno)); + token_start = cursor; + + continue; + } + +"call" { + ts.push_token (Token (Token::call, lineno)); + token_start = cursor; + + continue; + } + +"ret" { + ts.push_token (Token (Token::ret, lineno)); + token_start = cursor; + + continue; + } + +"load" { + ts.push_token (Token (Token::load, lineno)); + token_start = cursor; + + continue; + } + +"store" { + ts.push_token (Token (Token::store, lineno)); + token_start = cursor; + + continue; + } +"<=" { + ts.push_token (Token (Token::lesseq, lineno)); + token_start = cursor; + + continue; + } +"<" { + ts.push_token (Token (Token::less, lineno)); + token_start = cursor; + + continue; + } + +"label" { + ts.push_token (Token (Token::label, lineno)); + token_start = cursor; + + continue; + } + +IDENTIFIER { + ts.push_token (Token (Token::ident, lineno, token_start, + cursor)); + token_start = cursor; + + continue; + } + +[ ]+ { + token_start = cursor; + + continue; + } + +"\n" { + ++lineno; + token_start = cursor; + + continue; + } + +"\000" { + ts.push_token (Token (Token::endinput, lineno)); + + break; + } + +[^] { + return false; + } + +*/ + } + return true; + } + + /*! + ** Fills up the buffer when neccessary. + ** Note the buffer is always filled to the maximum, not just the + ** number of bytes neccessary for the lexer to continue. + ** + ** \param nbytes - the number of bytes + */ + + void Lexer::buffer_grow (size_t new_size) + { + char *new_buffer = new char[new_size]; + + std::copy (buffer, limit, new_buffer); + + token_start = new_buffer + (token_start - buffer); + cursor = new_buffer + (cursor - buffer); + limit = new_buffer + new_size; + + buffer_size = new_size; + + delete [] buffer; + buffer = new_buffer; + } + + void Lexer::read (size_t nbytes) + { + if (token_start + nbytes > limit) { // we need larger buffer + buffer_grow (token_start - buffer + nbytes); + } + + std::copy (token_start, limit, buffer); + cursor -= token_start - buffer; + char *old_limit = limit - (token_start - buffer); + token_start = buffer; + + file->read (old_limit, limit - old_limit); + if (file->eof ()) { + size_t bytes = file->gcount (); + std::fill (old_limit + bytes, limit, '\0'); + } + } + + void Lexer::buffer_init () + { + file->read (buffer, buffer_size); + if (file->eof ()) { + size_t bytes = file->gcount (); + std::fill (buffer + bytes, buffer + buffer_size, '\0'); + } + + cursor = marker = token_start = buffer; + limit = buffer + buffer_size; + } + + + } // namespace Lexer + + } // namespace ASM +} // namespace SpasmImpl + diff --git a/src/asm/main.cpp b/src/asm/main.cpp new file mode 100644 index 0000000..da8fcf6 --- /dev/null +++ b/src/asm/main.cpp @@ -0,0 +1,21 @@ +#include <fstream> +#include <iostream> +#include "assembler.hpp" + +int main(int argc, const char* argv[]) +{ + if (argc != 2) + return 1; + SpasmImpl::ASM::Bytecode_Memory bytecode; + SpasmImpl::ASM::compile(std::cin, bytecode); + + std::ofstream output(argv[1], std::ios_base::out | std::ios_base::binary); + + // output.write ("SPASM", 5); + auto& bc = bytecode.bytecode(); + auto size = bc.size(); + output.write(reinterpret_cast<const char*>(&size), sizeof(size)); + output.write(reinterpret_cast<const char*>(bc.data()), size); + + return 0; +} diff --git a/src/asm/symbol.cpp b/src/asm/symbol.cpp new file mode 100644 index 0000000..7964142 --- /dev/null +++ b/src/asm/symbol.cpp @@ -0,0 +1,120 @@ +#include <list> +#include <string> + +#include "symbol.hpp" + +namespace SpasmImpl +{ +namespace ASM +{ +const size_t Symbol::notdefined = ~0ull; + +Symbol::Symbol() : _definition(notdefined) {} + +Symbol::Symbol(const std::string& identifier, size_t definition) + : _identifier(identifier), _definition(definition) +{ +} + +const std::string& Symbol::identifier() const +{ + return _identifier; +} + +size_t Symbol::definition() const +{ + return _definition; +} + +void Symbol::define(size_t definition) +{ + _definition = definition; +} + +size_t Symbol::add_position(size_t position) +{ + _positions.push_back(position); + + return _definition; +} + +Symbol::Positions_t::const_iterator Symbol::positions_begin() const +{ + return _positions.begin(); +} + +Symbol::Positions_t::const_iterator Symbol::positions_end() const +{ + return _positions.end(); +} + +Symbol_Table::Symbol_Table() {} + +/*! +** Search the table for symbol by identifier +** +** \param identifier - identifier of the symbol +** +** \return pointer to the symbol if it exists or NULL otherwise. +*/ +Symbol* Symbol_Table::find(const std::string& identifier) const +{ + const_iterator i = _table.find(identifier); + return (i != _table.end()) ? i->second : NULL; +} + +/*! +** Insert symbol with identifier indentifier on position position +** of just add new position for symbol. +** \param identifier - identifer of the symbol +** \param position - position of the symbol +** +** \return pointer to the symbol +*/ +Symbol* Symbol_Table::insert(const std::string& identifier, size_t position) +{ + Symbol* psymbol = find(identifier); + if (psymbol == NULL) + { + psymbol = new Symbol(identifier); + _table.insert(std::make_pair(identifier, psymbol)); + } + psymbol->add_position(position); + + return psymbol; +} + +/*! +** define symbol with identifier indentifier +** If the symbol already exists its definition is changed +** \param identifier - identifer of the symbol +** \param definition - definition of the symbol +** +** \return pointer to the symbol +*/ +Symbol* Symbol_Table::define(const std::string& identifier, size_t definition) +{ + Symbol* psymbol = find(identifier); + if (psymbol == NULL) + { + psymbol = new Symbol(identifier, definition); + _table.insert(std::make_pair(identifier, psymbol)); + } + else + psymbol->define(definition); + + return psymbol; +} + +Symbol_Table::const_iterator Symbol_Table::begin() const +{ + return _table.begin(); +} + +Symbol_Table::const_iterator Symbol_Table::end() const +{ + return _table.end(); +} + +} // namespace ASM +} // namespace SpasmImpl diff --git a/src/asm/symbol.hpp b/src/asm/symbol.hpp new file mode 100644 index 0000000..6ce4dbf --- /dev/null +++ b/src/asm/symbol.hpp @@ -0,0 +1,69 @@ +#ifndef SYMBOL_HPP +#define SYMBOL_HPP + +#include <list> +#include <map> +#include <string> + +namespace SpasmImpl +{ +namespace ASM +{ +//! Represents symbol table entry for the assembler +class Symbol +{ + public: + typedef std::list<size_t> Positions_t; + static const size_t notdefined; + Symbol(); + Symbol(const std::string&, size_t = 0); + + const std::string& identifier() const; + size_t definition() const; + + void define(size_t); + + size_t add_position(size_t); + + Positions_t::const_iterator positions_begin() const; + Positions_t::const_iterator positions_end() const; + + private: + //! identifier of the symbol + std::string _identifier; + + //! position of definition of the identifier + size_t _definition; + + //! list of uses of the identifier (positions) + Positions_t _positions; +}; + +//! This is the symbol table of the assembler +class Symbol_Table +{ + private: + typedef std::map<std::string, Symbol*> Table_t; + typedef Table_t::iterator iterator; + + public: + Symbol_Table(); + typedef Table_t::const_iterator const_iterator; + + Symbol* find(const std::string&) const; + Symbol* insert(const std::string&, size_t); + Symbol* define(const std::string&, size_t); + + const_iterator begin() const; + const_iterator end() const; + + private: + Symbol_Table(const Symbol_Table&); + Symbol_Table& operator=(const Symbol_Table&); + + Table_t _table; +}; +} // namespace ASM +} // namespace SpasmImpl + +#endif // SYMBOL_HPP diff --git a/src/asm/token.cpp b/src/asm/token.cpp new file mode 100644 index 0000000..6c88bef --- /dev/null +++ b/src/asm/token.cpp @@ -0,0 +1,65 @@ +#include <memory> +#include <new> +#include <queue> +#include <string> + +#include "token.hpp" + +namespace SpasmImpl +{ +namespace ASM +{ +namespace Lexer +{ +Token::Token(Token_type type) + : _type(type), _lineno(0), _value_int(0), _value_str("") +{ +} + +Token::Token(Token::Token_type type, + size_t lineno, + const char* start, + const char* end) + : _type(type), _lineno(lineno) +{ + if (_type == integer || _type == xinteger) + { + _value_int = strtol(start, NULL, 0); + } + else if (_type == ident) + { + if (end) + { + _value_str = std::string(start, end); + } + else + { + _value_str = std::string(start); + } + } +} + +Token::Token_type Token::type() const +{ + return _type; +} + +int Token::value_int() const +{ + return _value_int; +} + +const std::string& Token::value_str() const +{ + return _value_str; +} + +size_t Token::lineno() const +{ + return _lineno; +} + +} // namespace Lexer + +} // namespace ASM +} // namespace SpasmImpl diff --git a/src/asm/token.hpp b/src/asm/token.hpp new file mode 100644 index 0000000..4ef7ce0 --- /dev/null +++ b/src/asm/token.hpp @@ -0,0 +1,85 @@ +#ifndef TOKEN_HPP +#define TOKEN_HPP + +#include <string> + +#define TOKENS \ + TOK(push) \ + TOK(pop) \ + TOK(dup) \ + TOK(print) \ + TOK(read) \ + TOK(plus) \ + TOK(minus) \ + TOK(multiply) \ + TOK(divide) \ + TOK(modulus) \ + TOK(gotrue) \ + TOK(gofalse) \ + TOK(go) \ + TOK(call) \ + TOK(ret) \ + TOK(load) \ + TOK(store) \ + TOK(less) \ + TOK(lesseq) \ + TOK(label) \ + TOK(ident) \ + TOK(integer) \ + TOK(xinteger) \ + TOK(endinput) + +namespace SpasmImpl +{ +namespace ASM +{ +namespace Lexer +{ +class Token +{ + public: + enum Token_type + { + halt = 0, +#define TOK(x) x, + TOKENS +#undef TOK + notused + }; + + Token(Token_type = notused); + + Token(Token_type, size_t, const char* = NULL, const char* = NULL); + + Token_type type() const; + + size_t lineno() const; + + int value_int() const; + + const std::string& value_str() const; + + private: + Token_type _type; + + size_t _lineno; + + int _value_int; + + std::string _value_str; +}; + +class TokenStream +{ + public: + virtual void push_token(const Token&) = 0; + virtual ~TokenStream(){}; +}; + +} // namespace Lexer +} // namespace ASM +} // namespace SpasmImpl + +#undef TOKENS + +#endif diff --git a/src/asm/tokenizer.cpp b/src/asm/tokenizer.cpp new file mode 100644 index 0000000..8694ccf --- /dev/null +++ b/src/asm/tokenizer.cpp @@ -0,0 +1,51 @@ +#include <iostream> +#include <memory> +#include <new> + +#include "lexer.hpp" +#include "token.hpp" +#include "tokenizer.hpp" + +namespace SpasmImpl +{ +namespace ASM +{ +namespace Lexer +{ +Tokenizer::Tokenizer(std::istream& istr) + : _lexer(new Lexer(istr, 1024)), end_input(false) +{ + _lexer->buffer_init(); +} + +void Tokenizer::push_token(const Token& token) +{ + _tokens.push(token); + if (token.type() == Token::endinput) + end_input = true; +} + +Token Tokenizer::next_token() +{ + Token t(Token::endinput); + if (!_tokens.empty()) + { + t = _tokens.front(); + _tokens.pop(); + } + else if (!end_input) + { + while (_tokens.empty()) + { + _lexer->read(); + _lexer->tokenize(*this); + } + t = _tokens.front(); + _tokens.pop(); + } + return t; +} + +} // namespace Lexer +} // namespace ASM +} // namespace SpasmImpl diff --git a/src/asm/tokenizer.hpp b/src/asm/tokenizer.hpp new file mode 100644 index 0000000..1155db7 --- /dev/null +++ b/src/asm/tokenizer.hpp @@ -0,0 +1,35 @@ +#ifndef TOKENIZER_HPP +#define TOKENIZER_HPP + +#include <iostream> +#include <memory> +#include <queue> + +#include "lexer.hpp" +#include "token.hpp" + +namespace SpasmImpl +{ +namespace ASM +{ +namespace Lexer +{ +class Tokenizer : public TokenStream +{ + public: + Tokenizer(std::istream&); + + virtual void push_token(const Token&); + Token next_token(); + + private: + std::unique_ptr<Lexer> _lexer; + std::queue<Token> _tokens; + bool end_input; +}; // class Tokenizer +} // namespace Lexer + +} // namespace ASM +} // namespace SpasmImpl + +#endif diff --git a/src/dstack.cpp b/src/dstack.cpp new file mode 100644 index 0000000..93592ed --- /dev/null +++ b/src/dstack.cpp @@ -0,0 +1,172 @@ +#include "dstack.hpp" + +#include <algorithm> + +namespace SpasmImpl +{ +Dstack::Dstack() : bottom(NULL), tos(NULL), s_size(0) {} + +Dstack::Dstack(const Dstack& ds) : s_size(ds.s_size) +{ + copy_dstack(ds); +} + +Dstack& Dstack::operator=(const Dstack& ds) +{ + if (this != &ds) + { + if (bottom) + delete[] bottom; + s_size = ds.s_size; + copy_dstack(ds); + } + return *this; +} + +Dstack::~Dstack() +{ + if (bottom) + delete[] bottom; +} + +/** + * Makes the stack occupy new_size bytes + * \param new_size new size for the stack + */ +void Dstack::reserve(size_t new_size) +{ + size_t offset = tos - bottom; + byte* new_bottom = new byte[new_size]; + if (bottom) + { + std::copy(bottom, bottom + std::min(s_size, new_size), new_bottom); + delete[] bottom; + } + bottom = new_bottom; + tos = new_bottom + offset; + s_size = new_size; +} + +/*! +** Pushes x in the stack. +** If the stack is full its size is doubled. +** \param x data_t object to be pushed on the stack +*/ +void Dstack::push(data_t x) +{ + if (bottom + s_size < tos + sizeof(data_t)) + reserve((s_size ? s_size : sizeof(data_t)) * 2); + *((data_t*)tos) = x; + tos += sizeof(data_t); +} + +/*! +** Pushes the object of size x_size bytes pointed by x in the stack. +** If the stack is full its size is doubled (or more is x_size is greater +** than the size of the stack). +** \param x pointer to the element to be pushed on the stack +** \param x_size size of the element +*/ +void Dstack::push(byte* x, size_t x_size) +{ + if (bottom + s_size < tos + x_size) + reserve(s_size + ((s_size > x_size) ? s_size : x_size)); + std::copy(x, x + x_size, tos); + tos += x_size; +} + +/*! +** Pops an object of size x_size from the stack. +** The object is written to the place pointed by x. +** +** \param x pointer to the place for popping +** \param x_size size of the object to be popped +*/ +void Dstack::pop(void* x, size_t x_size) +{ + if (tos - x_size >= bottom) + { + std::copy(tos - x_size, tos, (byte*)x); + tos -= x_size; + } +} + +/*! +** \return a single data_t object, popping it from the stack. +*/ +data_t Dstack::pop() +{ + data_t x{}; + if (tos - sizeof(data_t) >= bottom) + { + tos -= sizeof(data_t); + x = *((data_t*)tos); + } + return x; +} + +/*! +** \return copy of the data_t object that is on top of the stack +*/ +data_t Dstack::top() const +{ + data_t x{}; + if (tos - sizeof(data_t) >= bottom) + { + x = *((data_t*)(tos - sizeof(data_t))); + } + return x; +} + +/*! +** \return the size of the stack in bytes +*/ +size_t Dstack::size() const +{ + return tos - bottom; +} + +/*! +** \return the space reserved for the stack in bytes +*/ +size_t Dstack::reserved() const +{ + return s_size; +} + +/*! +** Frees unused memory. Note that it is not always possible because memory +** management is done with new / delete +*/ + +void Dstack::strip_memory() +{ + reserve(size()); +} + +/*! +** \return true if the stack is empty +*/ +bool Dstack::empty() const +{ + return tos - bottom == 0; +} + +/*! +** Creates a copy of ds +** +** \param ds data stack to be copied +*/ +void Dstack::copy_dstack(const Dstack& ds) +{ + if (ds.bottom) + { + bottom = new byte[ds.s_size]; + tos = bottom + (ds.tos - ds.bottom); + std::copy(ds.bottom, ds.tos, bottom); + } + else + bottom = tos = NULL; +} + +} // namespace SpasmImpl diff --git a/src/dstack.hpp b/src/dstack.hpp new file mode 100644 index 0000000..850b66b --- /dev/null +++ b/src/dstack.hpp @@ -0,0 +1,46 @@ +#ifndef DSTACK_HPP +#define DSTACK_HPP + +#include "types.hpp" + +namespace SpasmImpl +{ +//! class representing the data stack + +/*! The class is quite simple stack. It is byte-orientatied - every push +** and pop is done in bytes with no taking care of any byte order! +*/ +class Dstack +{ + public: + Dstack(); + Dstack(const Dstack&); + Dstack& operator=(const Dstack&); + ~Dstack(); + void push(data_t); + void push(byte*, size_t); + void pop(void*, size_t); + data_t pop(); + data_t top() const; + + void reserve(size_t); + void strip_memory(); + size_t size() const; + size_t reserved() const; + bool empty() const; + + private: + void copy_dstack(const Dstack&); + + //! pointer to the bottom of the stack + byte* bottom; + + //! pointer to the top of the stack + byte* tos; + + //! size of the stack in bytes + size_t s_size; +}; +} // namespace SpasmImpl + +#endif // #ifndef DSTACK_HPP diff --git a/src/frames.cpp b/src/frames.cpp new file mode 100644 index 0000000..8b7c891 --- /dev/null +++ b/src/frames.cpp @@ -0,0 +1,130 @@ +#include <algorithm> + +#include "types.hpp" + +#include "frames.hpp" + +namespace SpasmImpl +{ +FrameStack::FrameStack() : base_ptr(NULL), frame_ptr(NULL), g_size(0), c_size(0) +{ +} + +FrameStack::FrameStack(const FrameStack& fs) + : g_size(fs.g_size), c_size(fs.c_size), fstack(fs.fstack) +{ + copy_fstack(fs); +} + +FrameStack::~FrameStack() +{ + delete_fstack(); +} + +FrameStack& FrameStack::operator=(const FrameStack& fs) +{ + if (this != &fs) + { + delete_fstack(); + copy_fstack(fs); + g_size = fs.g_size; + c_size = fs.c_size; + fstack = fs.fstack; + } + return *this; +} + +/*! +** Deletes the frame stack +*/ +void FrameStack::delete_fstack() +{ + if (base_ptr) + delete[] base_ptr; +} + +/*! +** Copies the frame stack fs +** +** \param fs - the frame stack to be copied +*/ +void FrameStack::copy_fstack(const FrameStack& fs) +{ + base_ptr = new data_t[fs.g_size]; + std::copy(fs.base_ptr, fs.frame_ptr + fs.c_size, base_ptr); + frame_ptr = base_ptr + (fs.frame_ptr - fs.base_ptr); +} + +/*! +** Returns a data_t object from the current frame +** +** \param index - index of the data_t object +** \return const reference to the object +*/ +const data_t& FrameStack::operator[](size_t index) const +{ + return frame_ptr[index]; +} + +/*! +** Returns a data_t object from the current frame +** +** \param index - index of the data_t object +** \return reference to the object +*/ +data_t& FrameStack::operator[](size_t index) +{ + return frame_ptr[index]; +} + +/*! +** Removes the current frame from the stack. +** It is called when a function does return. +*/ +void FrameStack::pop_frame() +{ + if (fstack.empty()) + { + frame_ptr = base_ptr; + c_size = 0; + } + else + { + data_t* new_frame_ptr = base_ptr + fstack.top(); + fstack.pop(); + c_size = frame_ptr - new_frame_ptr; + frame_ptr = new_frame_ptr; + } +} + +/*! +** Creates (pushes on the stack) new frame of fsize data_t objects +** +** \param fsize - size in data_t objects of the new frame +*/ +void FrameStack::new_frame(size_t fsize) +{ + if (frame_ptr + c_size + fsize > base_ptr + g_size) + { + size_t new_size = g_size + std::max(g_size, c_size + fsize); + data_t* new_base = new data_t[new_size]; + if (base_ptr) + { + std::copy(base_ptr, frame_ptr + c_size, new_base); + delete[] base_ptr; + } + frame_ptr = new_base + (frame_ptr - base_ptr); + base_ptr = new_base; + } + fstack.push(frame_ptr - base_ptr); + c_size = fsize; +} + +/*! +** \return true if the stack is empty +*/ +bool FrameStack::empty() const +{ + return frame_ptr == base_ptr && c_size == 0; +} +} // namespace SpasmImpl diff --git a/src/frames.hpp b/src/frames.hpp new file mode 100644 index 0000000..14d1d14 --- /dev/null +++ b/src/frames.hpp @@ -0,0 +1,51 @@ +#ifndef FRAMES_HPP +#define FRAMES_HPP + +#include <stack> + +#include "types.hpp" + +namespace SpasmImpl +{ +//! Class representing the stack frame for a function +/*! +** The class is implemented as a simple stack of frames while each frame +** is built up by a number of data_t objects +*/ +class FrameStack +{ + public: + FrameStack(); + FrameStack(const FrameStack&); + ~FrameStack(); + FrameStack& operator=(const FrameStack&); + + const data_t& operator[](size_t) const; + data_t& operator[](size_t); + void pop_frame(); + void new_frame(size_t); + bool empty() const; + + private: + //! pointer to the base of the stack + data_t* base_ptr; + + //! pointer to the beginning of the current frame + data_t* frame_ptr; + + //! size of the whole stack in data_t objects + size_t g_size; + + //! size of the current frame in data_t objects + size_t c_size; + + //! stack of the offsets between frames in the stack. + std::stack<size_t> fstack; + + void copy_fstack(const FrameStack&); + void delete_fstack(); +}; + +} // namespace SpasmImpl + +#endif // #ifndef FRAMES_HPP diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..17bb322 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,33 @@ +#include <fstream> +#include <iostream> + +#include <memory> +#include "spasm.hpp" + +int main(int argc, const char* argv[]) +{ + if (argc != 2) + return 1; + + std::ifstream input(argv[1], std::ios_base::in | std::ios_base::binary); + + size_t len; + + input.read((char*)&len, sizeof(len)); + + std::unique_ptr<Spasm::byte[]> bytecode(new Spasm::byte[len]); + + input.read((char*)bytecode.get(), len); + + for (size_t i = 0; i < len; ++i) + std::cout << std::hex << (int)bytecode[i] << ' '; + std::cout << std::endl; + + Spasm::Spasm vm(len, bytecode.get()); + + vm.run(); + + std::cout << std::endl; + + return 0; +} diff --git a/src/program.spa b/src/program.spa new file mode 100644 index 0000000..d92456a --- /dev/null +++ b/src/program.spa @@ -0,0 +1,12 @@ +read +label next +dup +push 1 +< +gotrue bye +push 1 +- +dup +print +go next +label bye diff --git a/src/spasm.cpp b/src/spasm.cpp new file mode 100644 index 0000000..e67c975 --- /dev/null +++ b/src/spasm.cpp @@ -0,0 +1,348 @@ +#include <algorithm> +#include <iostream> + +#include "spasm.hpp" + +namespace SpasmImpl +{ +PC_t Spasm::op_size = 21; +// Be sure the same number is on the previous and next lines +Operation Spasm::operations[] = {NULL, + &Spasm::push, + &Spasm::pop, + &Spasm::dup, + &Spasm::print, + &Spasm::read, + &Spasm::plus, + &Spasm::minus, + &Spasm::multiply, + &Spasm::divide, + &Spasm::modulus, + &Spasm::gotrue, + &Spasm::gofalse, + &Spasm::go, + &Spasm::call, + &Spasm::ret, + &Spasm::load, + &Spasm::store, + &Spasm::less, + &Spasm::lesseq}; + +Spasm::Spasm() + : pc(0), bc_size(0), bytecode(NULL), istr(&std::cin), ostr(&std::cout) +{ +} + +/*! +** Constructs new Spasm object +** +** \param _bc_size - size/length of the bytecode +** \param _bytecode - the bytecode of the program +** \param _istr - input stream for the machine +** \param _ostr - output stream for the machine +*/ +Spasm::Spasm(PC_t _bc_size, + const byte* _bytecode, + std::istream& _istr, + std::ostream& _ostr) + : pc(0), bc_size(_bc_size), istr(&_istr), ostr(&_ostr) +{ + bytecode = new byte[bc_size]; + std::copy(_bytecode, _bytecode + bc_size, bytecode); +} + +Spasm::Spasm(const Spasm& m) + : pc(m.pc), + bc_size(m.bc_size), + data_stack(m.data_stack), + return_stack(m.return_stack), + frame(m.frame), + istr(m.istr), + ostr(m.ostr) +{ + copybc(m); +} + +Spasm::~Spasm() +{ + deleteobj(); +} + +Spasm& Spasm::operator=(const Spasm& m) +{ + if (this != &m) + { + deleteobj(); + data_stack = m.data_stack; + return_stack = m.return_stack; + frame = m.frame; + istr = m.istr; + ostr = m.ostr; + copybc(m); + } + return *this; +} + +/*! +** Copies the bytecode of another machine m +** +** \param m - the machine from the bytecode is copied +*/ + +void Spasm::copybc(const Spasm& m) +{ + bytecode = new byte[bc_size]; + std::copy(m.bytecode, m.bytecode + bc_size, bytecode); +} + +/*! +** Deletes the machine +*/ +void Spasm::deleteobj() +{ + if (bytecode) + delete[] bytecode; +} + +/*! +** Returns the dstack, so that it can be examined after execution +** +** \return const reference to the data stack +*/ +const Dstack& Spasm::get_dstack() const +{ + return data_stack; +} + +/*! +** Starts the machine. The machine stops if it reaches an invalid opcode +** or opcode 0 or the pc reaches beyond the end of the bytecode. +*/ +void Spasm::run() +{ + while (pc < bc_size) + { + if (bytecode[pc] > 0 && bytecode[pc] < op_size) + (this->*operations[bytecode[pc]])(); + else + { + std::cerr << "opcode got to " << int(bytecode[pc]) << std::endl; + break; + } + ++pc; + } +} + +/*! +** Pushes the next data_t object on the data stack +*/ +void Spasm::push() +{ + ++pc; + data_stack.push(*reinterpret_cast<data_t*>(bytecode + pc)); + pc += sizeof(data_t) - 1; +} + +/*! +** Pops a data_t object from the data stack. +*/ +void Spasm::pop() +{ + data_stack.pop(); +} + +/*! +** Dups the data_t object on top of the data stack. +*/ +void Spasm::dup() +{ + data_stack.push(data_stack.top()); +} + +/*! +** Reads a data_t object from the input stream and pushes it on the data +** stack. +*/ +void Spasm::read() +{ + data_t x; + *istr >> x; + data_stack.push(x); +} + +/*! +** Pops a data_t object from the data stack and prints it on the output +** stream. +*/ +void Spasm::print() +{ + *ostr << data_stack.pop(); +} + +/*! +** Pops two data objects from the data stack and pushes their sum on the +** data stack. +*/ +void Spasm::plus() +{ + data_t x, y = data_stack.pop(); + x = data_stack.pop(); + data_stack.push(x + y); +} + +/*! +** Pops two data objects from the data stack and pushes their difference +** on the data stack. +*/ +void Spasm::minus() +{ + data_t x, y = data_stack.pop(); + x = data_stack.pop(); + data_stack.push(x - y); +} + +/*! +** Pops two data objects from the data stack and pushes their product +** on the data stack. +*/ +void Spasm::multiply() +{ + data_t x, y = data_stack.pop(); + x = data_stack.pop(); + data_stack.push(x * y); +} + +/*! +** Pops two data objects from the data stack and pushes their division +** on the data stack. +*/ +void Spasm::divide() +{ + data_t x, y = data_stack.pop(); + x = data_stack.pop(); + data_stack.push(x / y); +} + +/*! +** Pops two data objects from the data stack and pushes their modulus +** on the data stack. +*/ +void Spasm::modulus() +{ + data_t x, y = data_stack.pop(); + x = data_stack.pop(); + data_stack.push(x % y); +} + +/*! +** Conditional execution. +** If the data_t object on top of the data stack evaluates to true +** execution continues from the place pointed by number in the next bytes +*/ +void Spasm::gotrue() +{ + ++pc; + if (data_stack.pop()) + pc = *(reinterpret_cast<PC_t*>(bytecode + pc)) - 1; + else + pc += sizeof(size_t) - 1; +} + +/*! +** Conditional execution. +** If the data_t object on top of the data stack evaluates to false +** execution continues from the place pointed by number in the next bytes +*/ +void Spasm::gofalse() +{ + ++pc; + if (!data_stack.pop()) + pc = *(reinterpret_cast<PC_t*>(bytecode + pc)) - 1; + else + pc += sizeof(size_t) - 1; +} + +/*! +** Unconditional execution. +** Execution continues from the opcode pointed by the next bytes +*/ +void Spasm::go() +{ + ++pc; + pc = *(reinterpret_cast<PC_t*>(bytecode + pc)) - 1; +} + +/*! +** Function call. A new frame with the specified size is created, the +** return address is saved in the return stack and the new pc is loaded. +*/ +void Spasm::call() +{ + size_t fs; // new frame size + return_stack.push(pc); // using the ++pc in run() + data_stack.pop(&fs, sizeof(fs)); + data_stack.pop(&pc, sizeof(pc)); + frame.new_frame(fs); + --pc; // the ++pc in run() +} + +/*! +** Function return. The frame of the current function is destroyed and the +** saved return address is loaded in the pc +*/ +void Spasm::ret() +{ + pc = return_stack.top(); + return_stack.pop(); + frame.pop_frame(); +} + +/*! +** Local variable with index top of the data stack is pushed on top of the +** data stack. +*/ +void Spasm::load() +{ + size_t offset; + + data_stack.pop(&offset, sizeof(offset)); + data_stack.push(frame[offset]); +} + +/*! +** Local variable is assigned value +*/ +void Spasm::store() +{ + data_t value = data_stack.pop(); + size_t offset; + + data_stack.pop(&offset, sizeof(offset)); + frame[offset] = value; +} + +/*! +** Compares the values on top of the stack. Pushes 1 if the value before +** the top of the stack is less than that on top of the stack. +*/ +void Spasm::less() +{ + data_t y = data_stack.pop(); + data_t x = data_stack.pop(); + + data_stack.push(x < y); +} + +/*! +** Compares the values on top of the stack. Pushes 1 if the value before +** the top of the stack is less than or equal to that on top of the stack. +*/ +void Spasm::lesseq() +{ + data_t y = data_stack.pop(); + data_t x = data_stack.pop(); + + data_stack.push(x <= y); +} + +} // namespace SpasmImpl diff --git a/src/spasm.hpp b/src/spasm.hpp new file mode 100644 index 0000000..7468bd8 --- /dev/null +++ b/src/spasm.hpp @@ -0,0 +1,13 @@ +#ifndef SPASM_HPP +#define SPASM_HPP + +#include "spasm_impl.hpp" + +namespace Spasm +{ +using SpasmImpl::byte; +using SpasmImpl::PC_t; +using SpasmImpl::Spasm; +} // namespace Spasm + +#endif // #ifndef SPASM_HPP diff --git a/src/spasm_impl.hpp b/src/spasm_impl.hpp new file mode 100644 index 0000000..78c5d08 --- /dev/null +++ b/src/spasm_impl.hpp @@ -0,0 +1,97 @@ +#ifndef SPASM_IMPL_HPP +#define SPASM_IMPL_HPP + +#include <iostream> + +#include "dstack.hpp" +#include "frames.hpp" +#include "types.hpp" + +namespace SpasmImpl +{ +//! The Abstract Stack Machine +/*! +** The machine contains a data stack for operations and control flow and +** frame stack for function calls (including parameter passing) and local +** variables and return stack for the addresses of the returns. +*/ +class Spasm +{ + public: + Spasm(); + Spasm(PC_t, + const byte*, + std::istream& = std::cin, + std::ostream& = std::cout); + Spasm(const Spasm&); + ~Spasm(); + Spasm& operator=(const Spasm&); + + void run(); + + const Dstack& get_dstack() const; + + private: + //! Operations (opcodes) of the machine + static Operation operations[]; + + //! number of operations + static PC_t op_size; + + //! Program counter - points the current opcode + PC_t pc; + + //! size of the program bytecode + PC_t bc_size; + + //! bytecode of the program + byte* bytecode; + + //! Data stack for arithmetic operations and control flow + Dstack data_stack; + + //! Return stack for the addresses of the returns + Rstack_t return_stack; + + //! Stack for the frame of the functions + FrameStack frame; + + //! Input stream for read () operation + std::istream* istr; + + //! Output stream for print () opertion + std::ostream* ostr; + + void push(); + void pop(); + void dup(); + + void print(); + void read(); + + void plus(); + void minus(); + void multiply(); + void divide(); + void modulus(); + + void gotrue(); + void gofalse(); + void go(); + + void call(); + void ret(); + + void load(); + void store(); + + void less(); + void lesseq(); + + // private method for copying and deleting an object + void copybc(const Spasm&); + void deleteobj(); +}; + +} // namespace SpasmImpl +#endif // #ifndef SPASM_IMPL_HPP diff --git a/src/types.hpp b/src/types.hpp new file mode 100644 index 0000000..0d86cab --- /dev/null +++ b/src/types.hpp @@ -0,0 +1,17 @@ +#ifndef TYPES_HPP +#define TYPES_HPP + +#include <cstdlib> +#include <stack> + +namespace SpasmImpl +{ +typedef unsigned char byte; +typedef size_t PC_t; +typedef int data_t; +typedef std::stack<PC_t> Rstack_t; + +class Spasm; +typedef void (Spasm::*Operation)(); +} // namespace SpasmImpl +#endif // ----- #ifndef TYPES_HPP |
