diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..b2e385f31a0f147dd6381b0a39ab993649d52a91 --- /dev/null +++ b/.clang-format @@ -0,0 +1,149 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: true +AlignConsecutiveAssignments: true +AlignConsecutiveBitFields: true +AlignConsecutiveDeclarations: true +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Linux +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + - Regex: '.*' + Priority: 1 + SortPriority: 0 +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE +... + diff --git a/.gitignore b/.gitignore index d529c2578c03c3c0b6fe842958a8d951d5501ba0..af9520e2cdaef62a4f3223d8ad9620d15ae14599 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,127 @@ libraries/draft/* /.cproject compiler/*.o build/* -/Makefile \ No newline at end of file +/Makefile +# /docs/_sidebar.md +secret/ + +# Created by https://www.toptal.com/developers/gitignore/api/flex,c++ +# Edit at https://www.toptal.com/developers/gitignore?templates=flex,c++ + +### C++ ### +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Linker files +*.ilk + +# Debugger Files +*.pdb + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +### Flex ### + +# Build and Release Folders +bin/ +bin-debug/ +bin-release/ +.actionScriptProperties + +# only for a non-library project +.flexProperties + +# only for library project +.flexLibProperties + + +# Other files and folders +.settings/ +.project/ + +.FlexUnitSettings +.externalToolBuilders +.model + +# End of https://www.toptal.com/developers/gitignore/api/flex,c++ + +# http://www.gnu.org/software/automake + +Makefile.in +/ar-lib +/mdate-sh +/py-compile +/test-driver +/ylwrap +.deps/ +.dirstamp + +# http://www.gnu.org/software/autoconf + +autom4te.cache +/autoscan.log +/autoscan-*.log +/aclocal.m4 +/compile +/config.guess +/config.h.in +/config.log +/config.status +/config.sub +/configure +/configure~ +/configure.scan +/depcomp +/install-sh +/missing +/stamp-h1 + +# https://www.gnu.org/software/libtool/ + +/ltmain.sh + +# http://www.gnu.org/software/texinfo + +/texinfo.tex + +# http://www.gnu.org/software/m4/ + +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 + +# Generated Makefile +# (meta build system like autotools, +# can automatically generate from config.status script +# (which is called by configure script)) +Makefile \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 4b97a41aca795513ed6dcdce8937db494fa26df4..d24cb55248f83309f974417f5e5c451ab7c846a8 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -5,8 +5,11 @@ "defines": [], "compilerPath": "/usr/bin/gcc", "cStandard": "c11", - "cppStandard": "c++20", - "intelliSenseMode": "gcc-x64" + "cppStandard": "c++17", + "intelliSenseMode": "gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ] } ], "version": 4 diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000000000000000000000000000000000000..6ca08f277abb68ae91316ea28d21d280032d1552 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "daohong-emilio.yash" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000000000000000000000000000000000..cc67606f330b4e5b4d643ce3adadee13122a081c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "python.linting.pylintEnabled": true, + "python.linting.enabled": true +} \ No newline at end of file diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000000000000000000000000000000000000..2427a5c1f014d418f49ae16fb0c1c6bf651be61c --- /dev/null +++ b/AUTHORS @@ -0,0 +1,7 @@ +Authors +Yitong Dang (NaiveTomcat) +Bocheng Zou (uebian) +Yubo Zhao (zyb, qyuqxun) +Zichun Gong (gongzichun2) +Haoran Wang (haoran) +Anlan Zhao (zal) \ No newline at end of file diff --git a/COPYING b/COPYING new file mode 100644 index 0000000000000000000000000000000000000000..efc5d950ffda0b83e893ed3e5877f679122dac21 --- /dev/null +++ b/COPYING @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000000000000000000000000000000000000..d49893cd615b349bf16896f8eee0c1820a6817ee --- /dev/null +++ b/ChangeLog @@ -0,0 +1 @@ +Since AloLang Compiler is still under heavy development, no changelog is available \ No newline at end of file diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000000000000000000000000000000000000..8865734f81b136629e961c230380423899c75794 --- /dev/null +++ b/INSTALL @@ -0,0 +1,368 @@ +Installation Instructions +************************* + + Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software +Foundation, Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell command './configure && make && make install' +should configure, build, and install this package. The following +more-detailed instructions are generic; see the 'README' file for +instructions specific to this package. Some packages provide this +'INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The 'configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a 'Makefile' in each directory of the package. +It may also create one or more '.h' files containing system-dependent +definitions. Finally, it creates a shell script 'config.status' that +you can run in the future to recreate the current configuration, and a +file 'config.log' containing compiler output (useful mainly for +debugging 'configure'). + + It can also use an optional file (typically called 'config.cache' and +enabled with '--cache-file=config.cache' or simply '-C') that saves the +results of its tests to speed up reconfiguring. Caching is disabled by +default to prevent problems with accidental use of stale cache files. + + If you need to do unusual things to compile the package, please try +to figure out how 'configure' could check whether to do them, and mail +diffs or instructions to the address given in the 'README' so they can +be considered for the next release. If you are using the cache, and at +some point 'config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file 'configure.ac' (or 'configure.in') is used to create +'configure' by a program called 'autoconf'. You need 'configure.ac' if +you want to change it or regenerate 'configure' using a newer version of +'autoconf'. + + The simplest way to compile this package is: + + 1. 'cd' to the directory containing the package's source code and type + './configure' to configure the package for your system. + + Running 'configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type 'make' to compile the package. + + 3. Optionally, type 'make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type 'make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the 'make install' phase executed with root + privileges. + + 5. Optionally, type 'make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior 'make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing 'make clean'. To also remove the + files that 'configure' created (so you can compile the package for + a different kind of computer), type 'make distclean'. There is + also a 'make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type 'make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide 'make + distcheck', which can by used by developers to test that all other + targets like 'make install' and 'make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the 'configure' script does not know about. Run './configure --help' +for details on some of the pertinent environment variables. + + You can give 'configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here is +an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU 'make'. 'cd' to the +directory where you want the object files and executables to go and run +the 'configure' script. 'configure' automatically checks for the source +code in the directory that 'configure' is in and in '..'. This is known +as a "VPATH" build. + + With a non-GNU 'make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use 'make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple '-arch' options to the +compiler but only a single '-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the 'lipo' tool if you have problems. + +Installation Names +================== + + By default, 'make install' installs the package's commands under +'/usr/local/bin', include files under '/usr/local/include', etc. You +can specify an installation prefix other than '/usr/local' by giving +'configure' the option '--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option '--exec-prefix=PREFIX' to 'configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like '--bindir=DIR' to specify different values for particular +kinds of files. Run 'configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the default +for these options is expressed in terms of '${prefix}', so that +specifying just '--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to 'configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +'make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, 'make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +'${prefix}'. Any directories that were specified during 'configure', +but not in terms of '${prefix}', must each be overridden at install time +for the entire installation to be relocated. The approach of makefile +variable overrides for each directory variable is required by the GNU +Coding Standards, and ideally causes no recompilation. However, some +platforms have known limitations with the semantics of shared libraries +that end up requiring recompilation when using this method, particularly +noticeable in packages that use GNU Libtool. + + The second method involves providing the 'DESTDIR' variable. For +example, 'make install DESTDIR=/alternate/directory' will prepend +'/alternate/directory' before all installation names. The approach of +'DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of '${prefix}' +at 'configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving 'configure' the +option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. + + Some packages pay attention to '--enable-FEATURE' options to +'configure', where FEATURE indicates an optional part of the package. +They may also pay attention to '--with-PACKAGE' options, where PACKAGE +is something like 'gnu-as' or 'x' (for the X Window System). The +'README' should mention any '--enable-' and '--with-' options that the +package recognizes. + + For packages that use the X Window System, 'configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the 'configure' options '--x-includes=DIR' and +'--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of 'make' will be. For these packages, running './configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with 'make V=1'; while running './configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with 'make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC +is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX 'make' updates targets which have the same time stamps as their +prerequisites, which makes it generally unusable when shipped generated +files such as 'configure' are involved. Use GNU 'make' instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its '' header file. The option '-nodtk' can be used as a +workaround. If GNU CC is not installed, it is therefore recommended to +try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put '/usr/ucb' early in your 'PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in '/usr/bin'. So, if you need '/usr/ucb' +in your 'PATH', put it _after_ '/usr/bin'. + + On Haiku, software installed for all users goes in '/boot/common', +not '/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features 'configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, 'configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +'--build=TYPE' option. TYPE can either be a short name for the system +type, such as 'sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file 'config.sub' for the possible values of each field. If +'config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option '--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with '--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for 'configure' scripts to share, +you can create a site shell script called 'config.site' that gives +default values for variables like 'CC', 'cache_file', and 'prefix'. +'configure' looks for 'PREFIX/share/config.site' if it exists, then +'PREFIX/etc/config.site' if it exists. Or, you can set the +'CONFIG_SITE' environment variable to the location of the site script. +A warning: not all 'configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to 'configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the 'configure' command line, using 'VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified 'gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an +Autoconf limitation. Until the limitation is lifted, you can use this +workaround: + + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + +'configure' Invocation +====================== + + 'configure' recognizes the following options to control how it +operates. + +'--help' +'-h' + Print a summary of all of the options to 'configure', and exit. + +'--help=short' +'--help=recursive' + Print a summary of the options unique to this package's + 'configure', and exit. The 'short' variant lists options used only + in the top level, while the 'recursive' variant lists options also + present in any nested packages. + +'--version' +'-V' + Print the version of Autoconf used to generate the 'configure' + script, and exit. + +'--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally 'config.cache'. FILE defaults to '/dev/null' to + disable caching. + +'--config-cache' +'-C' + Alias for '--cache-file=config.cache'. + +'--quiet' +'--silent' +'-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to '/dev/null' (any error + messages will still be shown). + +'--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + 'configure' can determine that directory automatically. + +'--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: for + more details, including other options available for fine-tuning the + installation locations. + +'--no-create' +'-n' + Run the configure checks, but stop before creating any output + files. + +'configure' also accepts some other, not widely useful, options. Run +'configure --help' for more details. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..c3a63e1c890bbddd21268a89a22e1e58d84c2572 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = src src/lib +dist_doc_DATA = docs/README.md \ No newline at end of file diff --git a/Makefile.content b/Makefile.content deleted file mode 100644 index 581bed4a68b01fd32cf688755a225e58a2f87fc1..0000000000000000000000000000000000000000 --- a/Makefile.content +++ /dev/null @@ -1,35 +0,0 @@ - -AST_SRCS := $(wildcard compiler/ast/*.cpp) -AST_OBJS_BUILD := $(addprefix build/,$(AST_SRCS:.cpp=.o)) -OBJ_DIR = build/ - -aloc: build/compiler/cppfront.o build/compiler/preprocessor.o build/compiler/utils.o build/compiler/code_parser.o build/compiler/code_gen.o $(AST_OBJS_BUILD) readytomake - $(CC) $(CFLAG) build/compiler/cppfront.o build/compiler/preprocessor.o build/compiler/utils.o build/compiler/code_parser.o build/compiler/code_gen.o $(AST_OBJS_BUILD) -lLLVM-10 -o aloc - -build/compiler/preprocessor.o: compiler/preprocessor.cpp compiler/compileerror.hpp readytomake - $(CC) $(CFLAG) -c -I ./compiler/ compiler/preprocessor.cpp -o build/compiler/preprocessor.o - -build/compiler/cppfront.o: compiler/cppfront.cpp readytomake - $(CC) $(CFLAG) -c -I ./compiler/ compiler/cppfront.cpp -o build/compiler/cppfront.o - -build/compiler/utils.o: compiler/utils.cpp readytomake - $(CC) $(CFLAG) -c -I ./compiler/ compiler/utils.cpp -o build/compiler/utils.o - -build/compiler/code_parser.o: compiler/code_parser.cpp readytomake - $(CC) $(CFLAG) -c -I ./compiler/ compiler/code_parser.cpp -o build/compiler/code_parser.o - -build/compiler/code_gen.o: compiler/code_gen.cpp readytomake - $(CC) $(CFLAG) -c -I ./compiler/ compiler/code_gen.cpp -o build/compiler/code_gen.o - -$(AST_OBJS_BUILD):$(OBJ_DIR)%.o : %.cpp readytomake - $(CC) $(CFLAG) -c $< -o $@ - -.PHONY : clean,install,readytomake -install: aloc readytomake - mv aloc /usr/bin/ -clean: - -rm -r aloc build -readytomake: - mkdir -p build - mkdir -p build/compiler - mkdir -p build/compiler/ast diff --git a/NEWS b/NEWS new file mode 100644 index 0000000000000000000000000000000000000000..685facbb0738c7a1ef9f2e754a9b2efbaf967d22 --- /dev/null +++ b/NEWS @@ -0,0 +1 @@ +AloLang Compiler News \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000000000000000000000000000000000000..a559c2a21699465471384fb46237f11827283275 --- /dev/null +++ b/README @@ -0,0 +1,20 @@ +AloLang Compiler Readme + +Distributed under the Lesser General Public License V3 + +To compile, we suggest that you have the project made in a dedicated directory. +Use the following commands. + +mkdir -p build +cd build +../configure +make + +Now that you should see a file called aloc within the build directory. + +To install that to your system, run the following command + +make install + +It will copy the associated file to your system's program directory(possibly be +/usr/local/bin). \ No newline at end of file diff --git a/change.md b/change.md deleted file mode 100644 index 1da8191e82860f92434ffa0469bf06f2ab0da749..0000000000000000000000000000000000000000 --- a/change.md +++ /dev/null @@ -1,9 +0,0 @@ -alolang->C++对照表 - -1.int->long long - -2.%def->#define - -3.complex->complex - -4. \ No newline at end of file diff --git a/compiler/ast/ExprAST.cpp b/compiler/ast/ExprAST.cpp deleted file mode 100644 index 4b46f10e3858f07614b94484b66c86e9af5e69c0..0000000000000000000000000000000000000000 --- a/compiler/ast/ExprAST.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "ExprAST.h" - -ExprAST::ExprAST() { - // TODO Auto-generated constructor stub - -} - -ExprAST::~ExprAST() { - // TODO Auto-generated destructor stub -} - diff --git a/compiler/ast/ExprAST.h b/compiler/ast/ExprAST.h deleted file mode 100644 index e0ca413b0555e8e12eb5aaaf7bbdcb1ca65059da..0000000000000000000000000000000000000000 --- a/compiler/ast/ExprAST.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef COMPILER_AST_ASTEXPR_H_ -#define COMPILER_AST_ASTEXPR_H_ - -#include "BaseAST.h" - -class ExprAST: public BaseAST { -public: - ExprAST(); - virtual ~ExprAST(); - virtual llvm::Value *Codegen() = 0; -}; - -#endif /* COMPILER_AST_ASTEXPR_H_ */ diff --git a/compiler/ast/FunctionAST.cpp b/compiler/ast/FunctionAST.cpp deleted file mode 100644 index 0f576fd6167523bad5df39518782ae15acaaf4cf..0000000000000000000000000000000000000000 --- a/compiler/ast/FunctionAST.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * FunctionAST.cpp - * - * Created on: Aug 28, 2020 - * Author: zbc - */ - -#include "FunctionAST.h" - -FunctionAST::FunctionAST() { - // TODO Auto-generated constructor stub - -} - -FunctionAST::~FunctionAST() { - // TODO Auto-generated destructor stub -} - -llvm::Function* FunctionAST::Codegen() { - //todo:待实现 - return nullptr; -} - -FunctionAST* FunctionAST::ParseDefinition() { - next_tok(); // eat def. - /*PrototypeAST *Proto = ParsePrototype(); - if (Proto == 0) - return 0; - - if (ExprAST *E = ParseExpression()) - return new FunctionAST(Proto, E);*/ - return 0; -} - diff --git a/compiler/ast/IntExprAST.cpp b/compiler/ast/IntExprAST.cpp deleted file mode 100644 index cbb4bc924f0855c7e050ecfe465dcece3fbba2e5..0000000000000000000000000000000000000000 --- a/compiler/ast/IntExprAST.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* - * NumberExprAST.cpp - * - * Created on: Aug 28, 2020 - * Author: zbc - */ - -#include "IntExprAST.h" - -NumberExprAST::NumberExprAST() { - // TODO Auto-generated constructor stub - -} - -NumberExprAST::~NumberExprAST() { - // TODO Auto-generated destructor stub -} - diff --git a/compiler/ast/VariableExprAST.cpp b/compiler/ast/VariableExprAST.cpp deleted file mode 100644 index e9012ade8e7dbaf427b7a5d3af9f81d2473e4773..0000000000000000000000000000000000000000 --- a/compiler/ast/VariableExprAST.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * VariableExprAST.cpp - * - * Created on: Aug 28, 2020 - * Author: zbc - */ - -#include "VariableExprAST.h" - -VariableExprAST::VariableExprAST() { - // TODO Auto-generated constructor stub - -} - -VariableExprAST::~VariableExprAST() { - // TODO Auto-generated destructor stub -} - -llvm::Value* VariableExprAST::Codegen() { - //todo:待实现 - return nullptr; -} - diff --git a/compiler/ast/VariableExprAST.h b/compiler/ast/VariableExprAST.h deleted file mode 100644 index af34f2631560bb4334e49bbfa7013696dae4fd5b..0000000000000000000000000000000000000000 --- a/compiler/ast/VariableExprAST.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * VariableExprAST.h - * - * Created on: Aug 28, 2020 - * Author: zbc - */ - -#ifndef COMPILER_AST_VARIABLEEXPRAST_H_ -#define COMPILER_AST_VARIABLEEXPRAST_H_ - -#include "ExprAST.h" - -class VariableExprAST: public ExprAST { -public: - VariableExprAST(); - virtual ~VariableExprAST(); - virtual llvm::Value *Codegen(); -}; - -#endif /* COMPILER_AST_VARIABLEEXPRAST_H_ */ diff --git a/compiler/code_gen.cpp b/compiler/code_gen.cpp deleted file mode 100644 index a559b522202d9079d163ee8863e24fa043882345..0000000000000000000000000000000000000000 --- a/compiler/code_gen.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include - -using namespace llvm; - -void createIRWithIRBuilder() { - LLVMContext Context; - Module *mod = new Module("test.ll", Context); - - //1、创建IRBuilder - IRBuilder<> builder(Context); - //2、创建main函数 - FunctionType *ft = FunctionType::get(builder.getInt32Ty(), false); - Function *mainfunc = Function::Create(ft, Function::ExternalLinkage, "main", - mod); - //到此为止之创建了main函数,但是函数体内的包含的Instruction没有添加,因此需要添加。 - - //3、创建基本块(这个基本块是空的无内容) - BasicBlock *entry = BasicBlock::Create(Context, "entrypoint", mainfunc); - - //4、设置插入点:插入点设置成相应BasicBlock,<#后面用builder创建的指令都会追加到这个BasicBlock里了#> - //!!!: - 理解:上面的方式是通过直接往BasicBloock中添加Instruction方式来构造基本的basicBlock,这里借助IRBuilder方式,往basicBlock中添加命令。 - builder.SetInsertPoint(entry); - - //5、添加全局字符串(IR中字符串全部为全局变量,使用数据序列来表示,每个元素是一个char类型) - Value *helloWorld = builder.CreateGlobalStringPtr("hi world!\n"); - //6、创建put函数 - //1)指定函数参数类型,装在一个数组中` - std::vector putsargs; - putsargs.push_back(builder.getInt8Ty()->getPointerTo()); - ArrayRef argsRef(putsargs); - //2)指定函数返回值类型 - FunctionType *putsType = FunctionType::get(builder.getInt32Ty(), argsRef, - false); - //FunctionType *mainType = FunctionType::get(builder.getInt32Ty(), false); - //3)创建“函数调用”,而不是创建函数 - //FunctionCallee mainFunc = mod->getOrInsertFunction("_alolang_4main",); - FunctionCallee putsFunc = mod->getOrInsertFunction("puts", putsType); - - //7、调用函数(<#理解:通过createXXX创建出来的所有指令都在SetInsertPoint后面#>) - builder.CreateCall(putsFunc, helloWorld); //这是创建方法的指令 - //8、创建返回ret指令 - ConstantInt *zero = ConstantInt::get(IntegerType::getInt32Ty(Context), 0); - builder.CreateRet(zero); - - //9、验证。这一步待定! - llvm::VerifierAnalysis::Result Res; - Res.IRBroken = llvm::verifyModule(*mod, &dbgs(), &Res.DebugInfoBroken); - std::error_code EC; - llvm::raw_fd_ostream OS("module", EC, llvm::sys::fs::F_None); - llvm::WriteBitcodeToFile(*mod, OS); - OS.flush(); - //mod->print(llvm::errs(), nullptr); -} diff --git a/compiler/code_parser.cpp b/compiler/code_parser.cpp deleted file mode 100644 index 2a005df98bacb93c17bbeb6d7c2ec96e45a0a3d7..0000000000000000000000000000000000000000 --- a/compiler/code_parser.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * code_parser.cpp - * - * Created on: Aug 10, 2020 - * Author: zbc - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void createIRWithIRBuilder(); - -std::istringstream sis; - -double numVal; -std::string identifierStr; -int curTok; - -//获取下一个Token -int next_tok() { - skipSpace(sis); - char lastChar = sis.get(); - if (std::isalpha(lastChar) || lastChar == '-' || lastChar == '>') { // 标志符: [a-zA-Z][a-zA-Z0-9]* - identifierStr = lastChar; - while (std::isalnum((lastChar = sis.get()))) - identifierStr += lastChar; - if (identifierStr == "fun") - return tok_fun; - if (identifierStr == "extern") - return tok_extern; - if (identifierStr == "return") - return tok_return; - if (identifierStr == "->") - return tok_return_type; - return tok_identifier; - } - if (std::isdigit(lastChar) || lastChar == '.') { // 数字: [0-9.]+ - std::string NumStr; - do { - NumStr += lastChar; - lastChar = sis.get(); - } while (std::isdigit(lastChar) || lastChar == '.'); - numVal = strtod(NumStr.c_str(), 0); - return tok_number; - } - if (lastChar == EOF) - return tok_eof; - return 0; //todo:错误处理 -} - -/*static ExprAST* ParseIdentifierExpr() { - std::string IdName = identifierStr; - - next_tok(); // eat identifier. - - if (curTok != '(') // Simple variable ref. - return new VariableExprAST(IdName); - - // Call. - next_tok(); // eat ( - std::vector Args; - if (CurTok != ')') { - while (1) { - ExprAST *Arg = ParseExpression(); - if (!Arg) - return 0; - Args.push_back(Arg); - - if (CurTok == ')') - break; - - if (CurTok != ',') - return Error("Expected ')' or ',' in argument list"); - getNextToken(); - } - } - }*/ - -void compile(const std::string &source) { - sis = std::istringstream(source); - do { - curTok = next_tok(); - switch (curTok) { - case tok_fun: - FunctionAST::ParseDefinition(); - break; - } - std::cout << "Read token:" << curTok << std::endl; - } while (curTok != tok_eof); - createIRWithIRBuilder(); -} diff --git a/compiler/cppfront.cpp b/compiler/cppfront.cpp deleted file mode 100644 index 907d1d3b72029a051a910d92772a55d23f7c0e3e..0000000000000000000000000000000000000000 --- a/compiler/cppfront.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "compileerror.hpp" -#include "preprocessor.h" -#include "utils.h" - -std::ifstream fin; -std::ofstream fout; - -using std::cout; -using std::cerr; -using std::endl; - -std::string input_file_name; -std::string output_file_name; - -// Start Compiler -// 替换字符串中所有给定序列 - -void compile(const std::string &source); - -std::string& replace_all(std::string &str, const std::string &old_value, - const std::string &new_value) { - for (std::string::size_type pos(0); pos != std::string::npos; pos += - new_value.length()) { - if ((pos = str.find(old_value, pos)) != std::string::npos) - str.replace(pos, old_value.length(), new_value); - else - break; - } - return str; -} - -int main(int argc, char *argv[]) { - std::string args[argc]; - for (int i = 1; i < argc; i++) - args[i - 1] = argv[i]; - if (argc == 1) { //检测参数不足并报错退出 - cerr << argv[0] - << ": fatal error: no input files\ncompilation terminated\n"; - return 1; - } else if (argc > 2) { //监测参数过多并报错退出 - cerr << argv[0] - << ": fatal error: too many arguments\ncompilation terminated\n"; - return 1; - } else { - if (args[0] == "--help" || args[0] == "-h") { //显示帮助信息 - cout << "Usage: " << argv[0] << " file_name\n"; - return 0; - } else { //确定源文件名 - input_file_name = args[0]; - output_file_name = input_file_name + ".ac"; - } - fin.open(input_file_name); - if (!fin.is_open()) { - cerr << argv[0] - << ": fatal error: file not found\ncompilation terminated\n"; - return 1; - } - std::string buff; //源码 - std::getline(fin, buff, char(EOF)); - std::string preProcessed; - fin.close(); - //std::string header = "%import types\n"; - //buff = header + buff; - try { - preProcessed = preProcess(buff, 0); - //cout << preProcessed; - //todo:这行代码写的极不规范,尽快修改 - compile(preProcessed); - //下面代码仅用来方便调试 - system("llc ./module --relocation-model=pic"); - system("gcc ./module.s -fPIE"); - } catch (const CompileError &e) { - cerr << "Compile Error: " << e.what() << endl - << "Compilation Terminated\n"; - return 1; - } - //todo: 编译用代码放下面 - //std::string compiled = compile(preProcessed); - //将编译结果输出到文件 - //fout.open(output_file_name); - //fout << compiled; - } - return 0; -} diff --git a/compiler/preprocessor.cpp b/compiler/preprocessor.cpp deleted file mode 100644 index 32b81b17c4fe6e82bdecf5be532c255bb63ebd56..0000000000000000000000000000000000000000 --- a/compiler/preprocessor.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#include "preprocessor.h" -#include "compileerror.hpp" -#include -#include "utils.h" -std::ifstream t_fin__; - -std::map variable; -int closeifstack = 0; -int currentifstack = 0; - -std::string preProcess(std::string code, int cnt); - -std::pair genFactor(std::string line) { - //std::pair result;//分别为指令和参数 - int len = line.length(); - if (len < 2) { - CompileError e("empty % indicator"); - throw e; - } - int i = 1; - for (; i < len; i++) { - if (line[i] == ' ') { - break; - } - } - if (i == len) { - //预编译指令没有参数 - return std::pair(line.substr(1, len - 1), ""); - } else { - //预编译指令有参数 - return std::pair(line.substr(1, i - 1), - line.substr(i + 1, len - i - 1)); - } - -} - -std::string processPreInstruction(std::string line, int cnt) { - std::pair instruction = genFactor(line); //解析后的预编译指令 - if (instruction.first == "import") { - t_fin__.open(instruction.second); - if (!t_fin__.is_open()) { - CompileError e("import file " + instruction.second + " not found"); - throw e; - } - std::getline(t_fin__, line, char(EOF)); - t_fin__.close(); - return preProcess(line, cnt + 1); - } else if (instruction.first == "def") { - //解析宏定义 - std::string var, data; - int len = instruction.second.length(); - if (len == 0) { - CompileError e("no second instruction"); - throw e; - } - int i = 1; - for (; i < len; i++) { - if (instruction.second[i] == ' ') { - break; - } - } - if (i == len) { - var = instruction.second.substr(0, len); - data = ""; - } else { - var = instruction.second.substr(0, i); - data = instruction.second.substr(i + 1, len - i - 1); - } - variable[var] = data; - return ""; - } else if (instruction.first == "rmdef") { - if (instruction.second.length() == 0) { - CompileError e("no second instruction"); - throw e; - } - if (!variable.erase(instruction.second)) { - CompileError e( - "removing macro " + instruction.second - + " that doent exist"); - throw e; - //找不到宏定义 - } - return ""; - } else if (instruction.first == "ifdef") { - if (instruction.second.length() == 0) { - CompileError e("no second instruction"); - throw e; - } - if (closeifstack > 0) { - closeifstack++; - } - if (variable.find(instruction.second) == variable.end()) { - closeifstack++; - } - currentifstack++; - return ""; - } else if (instruction.first == "ifndef") { - if (instruction.second.length() == 0) { - CompileError e("no second instruction"); - throw e; - } - if (closeifstack > 0) { - closeifstack++; - } - if (variable.find(instruction.second) != variable.end()) { - closeifstack++; - } - currentifstack++; - return ""; - } else if (instruction.first == "endif") { - if (currentifstack == 0) { - CompileError e("no second instruction"); - throw e; - } - if (closeifstack > 0) { - closeifstack--; - } - currentifstack--; - return ""; - } else { - CompileError e("Unrecognized preprocessor command"); - throw e; - } -} - -std::string findRealData(std::string key) { - std::map::iterator iter = variable.find(key); - if (iter != variable.end()) { - return findRealData(iter->second); - } else { - return key; - } -} -//宏替换 -std::string doReplace(std::string line) { - std::vector words; - bool flag = false; //判断栈顶元素状态 - for (long unsigned int i = 0; i < line.length(); i++) { - if (isSyntax(line[i])) { - words.push_back(std::string(1, line[i])); - flag = false; - } else { - if (!flag) { - words.push_back(std::string(1, line[i])); - flag = true; - } else { - words[words.size() - 1] += std::string(1, line[i]); - } - } - } - std::stringstream ss; - for (std::string tmp : words) { - ss << findRealData(tmp); - } - return ss.str(); -} - -//递归预处理 -std::string preProcess(std::string code, int cnt) { - if (cnt == 128) { - CompileError e("preprocessor recursion too deep"); - throw e; - } - std::istringstream buft_fin__(code); - std::stringstream preprocessoroutput; - std::string temp; - bool isCommented = false; - while (std::getline(buft_fin__, temp)) { - if (closeifstack > 0 && temp.substr(0, 6) != "%endif" - && temp.substr(0, 7) != "%ifndef" - && temp.substr(0, 6) != "%ifdef") { - continue; - } - if (temp[0] == '%') { - std::string processedPreInstruction = processPreInstruction(temp, - cnt); - if (processedPreInstruction.size() > 0) - preprocessoroutput << processedPreInstruction << std::endl; - } else { - std::string replaced = doReplace(temp); - //处理块注释 - long unsigned int position = replaced.find("*/"); - if (position != replaced.npos) { - if (!isCommented) { - //TODO:错误处理 - } - replaced = replaced.substr(position + 2, - replaced.length() - position - 2); - isCommented = false; - } - if (isCommented) { - replaced = ""; - } - position = replaced.find("/*"); - if (position != replaced.npos) { - replaced = replaced.substr(0, position); - isCommented = true; - } - - //处理行注释 - position = replaced.find("//"); - if (position != replaced.npos) { - replaced = replaced.substr(0, position); - } - - int plen = replaced.length(); - if (plen > 0) { - preprocessoroutput << replaced << std::endl; - } - } - temp.erase(); - } - return preprocessoroutput.str(); -} diff --git a/compiler/test/test01.alo b/compiler/test/test01.alo deleted file mode 100644 index 567c7cd92dc552046a2ba7c0281dcf20c4922855..0000000000000000000000000000000000000000 --- a/compiler/test/test01.alo +++ /dev/null @@ -1,11 +0,0 @@ - -%import test02.alo -%def con const -%rmdef PI -%def PI TAO - -fun main(int argc, char **argv) -> int{ - con int a = 123; - print PI * a; - return 0; -} \ No newline at end of file diff --git a/compiler/token.h b/compiler/token.h deleted file mode 100644 index 685f5ffbc7a301197abfd94f15ef0dd0fc77c5d5..0000000000000000000000000000000000000000 --- a/compiler/token.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * token.h - * - * Created on: Aug 28, 2020 - * Author: zbc - */ - -#ifndef COMPILER_TOKEN_H_ -#define COMPILER_TOKEN_H_ - -enum Token { - tok_eof = -1, - tok_fun = -2, tok_extern = -3, - tok_identifier = -4, tok_number = -5, tok_type = -6, - tok_return = -7,tok_return_type=-8 -}; - - -#endif /* COMPILER_TOKEN_H_ */ diff --git a/compiler/utils.cpp b/compiler/utils.cpp deleted file mode 100644 index 63522649c2800c8be0153acbcf048c76431beedc..0000000000000000000000000000000000000000 --- a/compiler/utils.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * utils.cpp - * - * Created on: May 2, 2020 - * Author: zbc - */ -#include -#include -#include - -char syntax[] = { '!', '%', '^', '&', '*', '(', ')', '-', '+', '=', '{', '}', - '|', '~', '[', ']', '\\', ';', '\'', ':', '"', ',', '<', '>', '?', '.', - '/', '#', ' ' }; - -bool isSyntax(char c) { - for (char tmp : syntax) { - if (c == tmp) { - return true; - } - } - return false; -} -//从pos查找到下一个非空格字段 -void skipSpace(const std::vector &words, long unsigned int& i) { - while (true) { - i++; - if (i >= words.size()) { - //TODO:异常处理(未期待的结尾) - } - if (words[i] != " ") { - break; - } - } -} - -void skipSpace(std::istream& in) -{ - while (in.good() && isspace(in.peek())) - { - // Read and discard the space character - in.ignore(); - in.get(); - } -} diff --git a/config.h.in~ b/config.h.in~ new file mode 100644 index 0000000000000000000000000000000000000000..e2993a5e4a460ca4ec793365c992529b5a6fa859 --- /dev/null +++ b/config.h.in~ @@ -0,0 +1,122 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `boost_program_options' library + (-lboost_program_options). */ +#undef HAVE_LIBBOOST_PROGRAM_OPTIONS + +/* Define to 1 if you have the `LLVM-11' library (-lLLVM-11). */ +#undef HAVE_LIBLLVM_11 + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if your system has a GNU libc compatible `realloc' function, + and to 0 otherwise. */ +#undef HAVE_REALLOC + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#undef STDC_HEADERS + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#undef YYTEXT_POINTER + +/* Define for Solaris 2.5.1 so the uint32_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT32_T + +/* Define for Solaris 2.5.1 so the uint8_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT8_T + +/* Define to the type of a signed integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#undef int16_t + +/* Define to the type of a signed integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef int32_t + +/* Define to the type of a signed integer type of width exactly 8 bits if such + a type exists and the standard includes do not define it. */ +#undef int8_t + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define to rpl_realloc if the replacement function should be used. */ +#undef realloc + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#undef uint16_t + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef uint32_t + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ +#undef uint8_t diff --git a/configure b/configure deleted file mode 100755 index 57c1b6aa1f5f832fea328e723522217733adaf74..0000000000000000000000000000000000000000 --- a/configure +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -./make-config > tmpcfg -cat tmpcfg Makefile.content > Makefile -rm tmpcfg \ No newline at end of file diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000000000000000000000000000000000000..1a8290500ce4a4654cba69de3f64b9fb51ed3a76 --- /dev/null +++ b/configure.ac @@ -0,0 +1,51 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.70]) +AC_INIT([AloLang Compiler], [Dev Beta], [https://github.com/XJTU-Youth/AloLang-Dev/issues]) + +AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug],[debug program(default is no)])], + [CFLAGS="${CFLAGS} -g -O0"], + [CFLAGS="-g -O2"]) + +AC_CONFIG_SRCDIR([src/aloc.cpp]) +AC_CONFIG_HEADERS([config.h]) + +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC +AC_PROG_LEX(noyywrap) +AC_PROG_RANLIB + +# Checks for libraries. +# FIXME: Replace 'main' with a function in '-lboost_program_options': +AC_CHECK_LIB([boost_program_options], [boost::program_options::strip_prefixes]) +AC_CHECK_LIB([LLVM-11], [llvm::demangle]) + +# Checks for header files. +AC_CHECK_HEADERS([inttypes.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_CHECK_HEADER_STDBOOL +AC_TYPE_INT16_T +AC_TYPE_INT32_T +AC_TYPE_INT8_T +AC_TYPE_SIZE_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT8_T + +# Checks for library functions. +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_CHECK_FUNCS([memset strtol]) + +AC_CONFIG_FILES([ + Makefile + src/Makefile + src/lib/Makefile +]) + +AM_INIT_AUTOMAKE +AC_OUTPUT diff --git a/compiler/lex.l b/docs/.nojekyll similarity index 100% rename from compiler/lex.l rename to docs/.nojekyll diff --git a/compiler/test/test03.alo.ac b/docs/.spa similarity index 100% rename from compiler/test/test03.alo.ac rename to docs/.spa diff --git a/docs/CNAME b/docs/CNAME new file mode 100644 index 0000000000000000000000000000000000000000..d5c1c80d837fa97dccd5186751896321cedb9a82 --- /dev/null +++ b/docs/CNAME @@ -0,0 +1 @@ +doc.alolang.org.cn \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0e44d732cef78827bc6d850b04d5af4e87c540bb --- /dev/null +++ b/docs/README.md @@ -0,0 +1,3 @@ +# AloLang + +> 为算法而生的语言 diff --git a/docs/_coverpage.md b/docs/_coverpage.md new file mode 100644 index 0000000000000000000000000000000000000000..32296644f92a3269e522c5a73b379d282e0889b6 --- /dev/null +++ b/docs/_coverpage.md @@ -0,0 +1,11 @@ + + +# AloLang语言参考文档 +> Make algorithm programming easy and comfortable + +* 静态编译强类型语言 +* 多语言协作方便 +* 语法简洁 + +[快速开始](index) +[Git Hub](https://github.com/xjtu-youth/AloLang/) \ No newline at end of file diff --git a/docs/_media/logo.png b/docs/_media/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..779f719259aabe1c9f249e11e3ef3f591cb5d9c4 Binary files /dev/null and b/docs/_media/logo.png differ diff --git a/docs/_media/logo.webp b/docs/_media/logo.webp new file mode 100644 index 0000000000000000000000000000000000000000..f0babfa0a2531423001e719eafc2e94159786b09 Binary files /dev/null and b/docs/_media/logo.webp differ diff --git a/docs/_sidebar.md b/docs/_sidebar.md new file mode 100644 index 0000000000000000000000000000000000000000..5a680f317a65b94323cc494175b1bdab7f961590 --- /dev/null +++ b/docs/_sidebar.md @@ -0,0 +1,70 @@ +* [AloLang语言参考文档](/index) + * [标准库](library/index) + * [alolang库:图](library/graph/index) + * [alolang库:math](library/math/index) + * [语言](language/index) + * [预处理器](language/preprocessor/index) + * [条件包含](language/preprocessor/conditional/index) + * [宏定义](language/preprocessor/replace/index) + * [源文件包含](language/preprocessor/import/index) + * [函数](language/functions/index) + * [TODO](language/initialization/index) + * [Alolang关键字](language/keyword/index) + * [类型关键字](language/keyword/type/index) + * [alolang关键字:long](language/keyword/type/long/index) + * [alolang关键字:anytype](language/keyword/type/anytype/index) + * [alolang关键字:float](language/keyword/type/float/index) + * [alolang关键字:enum](language/keyword/type/enum/index) + * [alolang关键字:void](language/keyword/type/void/index) + * [alolang关键字:char](language/keyword/type/char/index) + * [alolang关键字:bool](language/keyword/type/bool/index) + * [alolang关键字:struct](language/keyword/type/struct/index) + * [alolang关键字:string](language/keyword/type/string/index) + * [alolang关键字:signed](language/keyword/type/signed/index) + * [alolang关键字:double](language/keyword/type/double/index) + * [alolang关键字:int8_t](language/keyword/type/int8_t/index) + * [alolang关键词:unsigned](language/keyword/type/unsigned/index) + * [alolang关键字:int](language/keyword/type/int/index) + * [alolang关键字:int16_t](language/keyword/type/int16_t/index) + * [alolang关键字:array](language/keyword/type/array/index) + * [alolang关键字:int32_t](language/keyword/type/int32_t/index) + * [alolang关键词:auto](language/keyword/type/auto/index) + * [代用运算符的关键字](language/keyword/alternative/index) + * [alolang关键字:and](language/keyword/alternative/and/index) + * [alolang关键字:not](language/keyword/alternative/not/index) + * [alolang关键字:xor](language/keyword/alternative/xor/index) + * [alolang关键字:or](language/keyword/alternative/or/index) + * [运算符](language/keyword/operators/index) + * [自修改运算符](language/keyword/operators/self_change/index) + * [常量](language/keyword/literal/index) + * [alolang关键字:EOF](language/keyword/literal/EOF/index) + * [alolang关键字:false](language/keyword/literal/false/index) + * [alolang关键字:true](language/keyword/literal/true/index) + * [语句声明关键字](language/keyword/statements/index) + * [alolang关键字:if](language/keyword/statements/if/index) + * [alolang关键字:for](language/keyword/statements/for/index) + * [alolang关键字:while](language/keyword/statements/while/index) + * [alolang关键字:do](language/keyword/statements/do/index) + * [alolang关键字:extern](language/keyword/statements/extern/index) + * [alolang关键字:else](language/keyword/statements/else/index) + * [alolang关键字:break](language/keyword/statements/break/index) + * [alolang关键字:goto](language/keyword/statements/goto/index) + * [alolang关键字:case](language/keyword/statements/case/index) + * [alolang关键字:foreach](language/keyword/statements/foreach/index) + * [alolang关键字:continue](language/keyword/statements/continue/index) + * [alolang关键字:export](language/keyword/statements/export/index) + * [alolang关键字:return](language/keyword/statements/return/index) + * [alolang关键字:catch](language/keyword/statements/catch/index) + * [alolang关键字:switch](language/keyword/statements/switch/index) + * [alolang关键字:try](language/keyword/statements/try/index) + * [TODO](language/translation_phases/index) + * [TODO](language/expressions/index) + * [TODO](language/declarations/index) + * [基本概念](language/basic_concepts/index) + * [基本数据类型](language/basic_concepts/basic_types/index) + * [复合数据类型](language/basic_concepts/type/index) + * [整型字面量](language/basic_concepts/literal/index) + * [ASCII码表](language/basic_concepts/ascii/index) + * [语句](language/statements/index) + * [跨语言通信语句](language/statements/linkage/communicate/index) + * [链接语句](language/statements/linkage/basic/index) diff --git a/docs/favicon.ico b/docs/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..8b761b86f04ce25c02175fa3ef28f1346eeb2ebe Binary files /dev/null and b/docs/favicon.ico differ diff --git a/docs/gen_sidebar.py b/docs/gen_sidebar.py new file mode 100644 index 0000000000000000000000000000000000000000..256c9779d417e559cbd1d802f88d83cf9abb0a73 --- /dev/null +++ b/docs/gen_sidebar.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os +import os.path + +import queue + +ignore = ["_sidebar.md","sidebar.md"] + +#translate = {"language": "语言","preprocessor":"预处理器", "conditional": "条件编译"} + + +def dfs_showdir(path, depth): + q=queue.Queue() + + for item in os.listdir(path): + if item in ignore: + continue + + newitem = path + '/' + item + if os.path.isdir(newitem): + q.put(newitem) + else: + if item != "index.md": + continue + show_item="未定义" + with open(path + '/' + item, encoding='utf-8') as file: + for line in file.readlines(): + line = line.strip('\n') + #print(line[0:2]) + if line[0:2]=='# ': + show_item=line[2:] + break + print(" " * depth + "* [" + show_item + + "](" + path[2:] + "/index)") + while not q.empty(): + dfs_showdir(q.get(), depth + 1) + +if __name__ == '__main__': + dfs_showdir('.', 0) diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000000000000000000000000000000000000..30e018f007364814b54ccbc656cd0ee61ff62f24 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,35 @@ + + + + + AloLang参考文档 + + + + + + + + +
+ + + + + + + + + + + + diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000000000000000000000000000000000000..8c91d1ba6d6c43c68792e613560187c60e8147d2 --- /dev/null +++ b/docs/index.md @@ -0,0 +1 @@ +# AloLang语言参考文档 \ No newline at end of file diff --git a/docs/language/basic_concepts/ascii/index.md b/docs/language/basic_concepts/ascii/index.md new file mode 100644 index 0000000000000000000000000000000000000000..ac26d89015ceb694a79e2f706f3e313114e99911 --- /dev/null +++ b/docs/language/basic_concepts/ascii/index.md @@ -0,0 +1,36 @@ +# ASCII码表 + +| `dec` | `oct` | `hex` | `ch` | | `dec` | `oct` | `hex` | `ch` | | `dec` | `oct` | `hex` | `ch` | | `dec` | `oct` | `hex` | `ch` | +|--------|--------|--------|------------------|---|--------|--------|--------|--------|---|--------|--------|--------|-------|---|--------|--------|--------|---------------| +| `0` | `0` | `00` | `NUL` \(空\) | \| | `32` | `40` | `20` | \(空格\) | \| | `64` | `100` | `40` | `@` | \| | `96` | `140` | `60` | ``` | +| `1` | `1` | `01` | `SOH` \(标题开始\) | \| | `33` | `41` | `21` | `\!` | \| | `65` | `101` | `41` | `A` | \| | `97` | `141` | `61` | `a` | +| `2` | `2` | `02` | `STX` \(正文开始\) | \| | `34` | `42` | `22` | `"` | \| | `66` | `102` | `42` | `B` | \| | `98` | `142` | `62` | `b` | +| `3` | `3` | `03` | `ETX` \(正文结束\) | \| | `35` | `43` | `23` | `\#` | \| | `67` | `103` | `43` | `C` | \| | `99` | `143` | `63` | `c` | +| `4` | `4` | `04` | `EOT` \(传送结束\) | \| | `36` | `44` | `24` | `$` | \| | `68` | `104` | `44` | `D` | \| | `100` | `144` | `64` | `d` | +| `5` | `5` | `05` | `ENQ` \(询问\) | \| | `37` | `45` | `25` | `%` | \| | `69` | `105` | `45` | `E` | \| | `101` | `145` | `65` | `e` | +| `6` | `6` | `06` | `ACK` \(确认\) | \| | `38` | `46` | `26` | `&` | \| | `70` | `106` | `46` | `F` | \| | `102` | `146` | `66` | `f` | +| `7` | `7` | `07` | `BEL` \(响铃\) | \| | `39` | `47` | `27` | `'` | \| | `71` | `107` | `47` | `G` | \| | `103` | `147` | `67` | `g` | +| `8` | `10` | `08` | `BS` \(退格\) | \| | `40` | `50` | `28` | `\(` | \| | `72` | `110` | `48` | `H` | \| | `104` | `150` | `68` | `h` | +| `9` | `11` | `09` | `HT` \(横向制表\) | \| | `41` | `51` | `29` | `\)` | \| | `73` | `111` | `49` | `I` | \| | `105` | `151` | `69` | `i` | +| `10` | `12` | `0a` | `LF` \(换行\) | \| | `42` | `52` | `2a` | `\*` | \| | `74` | `112` | `4a` | `J` | \| | `106` | `152` | `6a` | `j` | +| `11` | `13` | `0b` | `VT` \(纵向制表\) | \| | `43` | `53` | `2b` | `\+` | \| | `75` | `113` | `4b` | `K` | \| | `107` | `153` | `6b` | `k` | +| `12` | `14` | `0c` | `FF` \(换页\) | \| | `44` | `54` | `2c` | `,` | \| | `76` | `114` | `4c` | `L` | \| | `108` | `154` | `6c` | `l` | +| `13` | `15` | `0d` | `CR` \(回车\) | \| | `45` | `55` | `2d` | `\-` | \| | `77` | `115` | `4d` | `M` | \| | `109` | `155` | `6d` | `m` | +| `14` | `16` | `0e` | `SO` \(移出\) | \| | `46` | `56` | `2e` | `\.` | \| | `78` | `116` | `4e` | `N` | \| | `110` | `156` | `6e` | `n` | +| `15` | `17` | `0f` | `SI` \(移入\) | \| | `47` | `57` | `2f` | `/` | \| | `79` | `117` | `4f` | `O` | \| | `111` | `157` | `6f` | `o` | +| `16` | `20` | `10` | `DLE` \(退出数据链\) | \| | `48` | `60` | `30` | `0` | \| | `80` | `120` | `50` | `P` | \| | `112` | `160` | `70` | `p` | +| `17` | `21` | `11` | `DC1` \(设备控制1\) | \| | `49` | `61` | `31` | `1` | \| | `81` | `121` | `51` | `Q` | \| | `113` | `161` | `71` | `q` | +| `18` | `22` | `12` | `DC2` \(设备控制2\) | \| | `50` | `62` | `32` | `2` | \| | `82` | `122` | `52` | `R` | \| | `114` | `162` | `72` | `r` | +| `19` | `23` | `13` | `DC3` \(设备控制3\) | \| | `51` | `63` | `33` | `3` | \| | `83` | `123` | `53` | `S` | \| | `115` | `163` | `73` | `s` | +| `20` | `24` | `14` | `DC4` \(设备控制4\) | \| | `52` | `64` | `34` | `4` | \| | `84` | `124` | `54` | `T` | \| | `116` | `164` | `74` | `t` | +| `21` | `25` | `15` | `NAK` \(反确认\) | \| | `53` | `65` | `35` | `5` | \| | `85` | `125` | `55` | `U` | \| | `117` | `165` | `75` | `u` | +| `22` | `26` | `16` | `SYN` \(同步空闲\) | \| | `54` | `66` | `36` | `6` | \| | `86` | `126` | `56` | `V` | \| | `118` | `166` | `76` | `v` | +| `23` | `27` | `17` | `ETB` \(传输块结束\) | \| | `55` | `67` | `37` | `7` | \| | `87` | `127` | `57` | `W` | \| | `119` | `167` | `77` | `w` | +| `24` | `30` | `18` | `CAN` \(取消\) | \| | `56` | `70` | `38` | `8` | \| | `88` | `130` | `58` | `X` | \| | `120` | `170` | `78` | `x` | +| `25` | `31` | `19` | `EM` \(媒介结束\) | \| | `57` | `71` | `39` | `9` | \| | `89` | `131` | `59` | `Y` | \| | `121` | `171` | `79` | `y` | +| `26` | `32` | `1a` | `SUB` \(替换\) | \| | `58` | `72` | `3a` | `:` | \| | `90` | `132` | `5a` | `Z` | \| | `122` | `172` | `7a` | `z` | +| `27` | `33` | `1b` | `ESC` \(退出\) | \| | `59` | `73` | `3b` | `;` | \| | `91` | `133` | `5b` | `\[` | \| | `123` | `173` | `7b` | `\{` | +| `28` | `34` | `1c` | `FS` \(文件分隔符\) | \| | `60` | `74` | `3c` | `<` | \| | `92` | `134` | `5c` | `\\` | \| | `124` | `174` | `7c` | ` | +| `29` | `35` | `1d` | `GS` \(组分隔符\) | \| | `61` | `75` | `3d` | `=` | \| | `93` | `135` | `5d` | `\]` | \| | `125` | `175` | `7d` | `\}` | +| `30` | `36` | `1e` | `RS` \(记录分隔符\) | \| | `62` | `76` | `3e` | `>` | \| | `94` | `136` | `5e` | `^` | \| | `126` | `176` | `7e` | `~` | +| `31` | `37` | `1f` | `US` \(单元分隔符\) | \| | `63` | `77` | `3f` | `?` | \| | `95` | `137` | `5f` | `\_` | \| | `127` | `177` | `7f` | `DEL` \(删除\) | diff --git a/docs/language/basic_concepts/basic_types/index.md b/docs/language/basic_concepts/basic_types/index.md index b45f9810ac45dd2ad14195ee357b3b0ae7f4641d..e8b0eecefeac88317a6a9aa00a91576743be122a 100644 --- a/docs/language/basic_concepts/basic_types/index.md +++ b/docs/language/basic_concepts/basic_types/index.md @@ -1,5 +1,4 @@ - -### 基本数据类型 +# 基本数据类型 | 名称 | 关键字 | 说明 | | ------------ | ------ | ---------------------- | @@ -7,7 +6,6 @@ | 整数 | int | 64位整型 | | 高精整数 | long | 无限精度整数 | | 双精度浮点数 | double | | -| 实数 | real | 可表示所有分数 待定 | | 布尔值 | bool | | diff --git a/docs/language/basic_concepts/index.md b/docs/language/basic_concepts/index.md index 7152943f4dddfbd9045b864117d766d606c8b15e..e98ad9e568ae571b39851797d7b0aac8e7b83496 100644 --- a/docs/language/basic_concepts/index.md +++ b/docs/language/basic_concepts/index.md @@ -5,13 +5,13 @@ 在 Alolang 程序中,一些被称为关键词的词语有着特殊的含义。其它词语可以被用作标识符。在翻译的过程中,注释会被忽略。程序中的某些特定字符必须通过转义序列表示。 -Alolang 程序中的实体包括值、对象、函数、类型、类成员。预处理器宏不是 C++ 实体。 +Alolang 程序中的实体包括值、对象、函数、类型、类成员。预处理器宏不是 Alolang 实体。 函数的定义通常包括一系列的语句,其中部分会包含表达式。表达式指定了程序需要进行的运算。 程序中遇到的名字通过名字查找与引入它们的声明关联起来。每个名字都只在称为其作用域的程序部分中有效。有些名字有链接,这使得它们即使出现在不同的作用域或翻译单元时也代表相同的实体。 -C++ 中的每一个对象、函数和表达式都会关联一个类型。类型可以分为基础类型,复合类型,或自定义类型。 +Alolang 中的每一个对象、函数和表达式都会关联一个类型。类型可以分为基础类型,复合类型,或自定义类型。 被声明的且不是非静态数据成员的对象和引用是变量。 diff --git a/docs/language/basic_concepts/literal/index.md b/docs/language/basic_concepts/literal/index.md new file mode 100644 index 0000000000000000000000000000000000000000..481a2649c5155f78d3582778fd510b7cffbfa437 --- /dev/null +++ b/docs/language/basic_concepts/literal/index.md @@ -0,0 +1,20 @@ +# 整型字面量 + +* 用于程序中的整型常量表示 + +十进制字面值以1-9开头,后面接不定长度的0-9。 + +十六进制字面值以0x开头,后接不定长度的0-9或a-f(A-F)。 + +八进制字面值以0开头,后面接不定长度的0-7。 + +二进制字面值以0b开头,后面接不定长度的0或1。 + +### 示例 + +```alolang +int a = 65537; +int b = 0xABCabc; +int c = 0100000007; +int d =10101010100001; +``` \ No newline at end of file diff --git a/docs/language/basic_concepts/type/index.md b/docs/language/basic_concepts/type/index.md index c7ad97bfc7ba67b7e78535205e4ce444a9817690..8178e290678ba86266471fd1742a0b7e257938de 100644 --- a/docs/language/basic_concepts/type/index.md +++ b/docs/language/basic_concepts/type/index.md @@ -1,8 +1,8 @@ - -### 复合数据类型 +# 复合数据类型 | 名称 | 关键字 | 说明 | | -------- | ---------- | ---------------------------------------- | +| 分数 | rational | 用于表示分数 | | 字符串 | string | 要求同char | | 数组 | array | 一组相同类型的数据,可嵌套,定长 | | 变长数组 | vector | 可变长度数组 | diff --git a/docs/language/functions/index.md b/docs/language/functions/index.md index c5c83ad248f4abf86a802aa214476ba61455a0bf..fec24f9baba080f70cd98e2c8f0882a9c9faae20 100644 --- a/docs/language/functions/index.md +++ b/docs/language/functions/index.md @@ -5,7 +5,7 @@ // 函数名:“isodd” // 形参列表拥有一个形参,具有名字“n”和类型 int // 返回类型是 bool -isodd(int n) -> bool // 函数名(参数列表) -> 返回类型列表 +func isodd(int n) -> bool // 函数名(参数列表) -> 返回类型列表 { // 函数体的开始 return n % 2; // 函数体 } // 函数体的结束 @@ -14,7 +14,7 @@ isodd(int n) -> bool // 函数名(参数列表) -> 返回类型列表 调用函数时,例如在函数调用表达式中,以各个实参(argument)(可为调用场所提供的,或为默认的)来初始化各个形参,然后执行函数体中的语句。 ``` -main() -> int +func main() -> int { for(int arg : {-3, -2, -1, 0, 1, 2, 3}) output(stdout)({isodd(arg),' '}); // isodd 被调用 7 次, @@ -34,5 +34,16 @@ main() -> int 可以用 lambda 表达式产生无名函数。 同一作用域中,多个函数可有相同名称,只要其形参列表,以及对于非静态成员函数的 cv 限定不同即可。这被称作函数重载。仅以返回类型相区别的函数声明之间无法重载。 +## 名称修饰 + +修饰规则: + +1.加上_alolang_前缀 + +2.加上原函数名称 + +2.加上每个参数类型的名称长度以及该类型的名称 + +比如`fun foobar(long a, int b)`修饰为`_alolang_6foobar4long3int` # TODO \ No newline at end of file diff --git a/docs/language/index.md b/docs/language/index.md index f87f5c14cbbd7d462ab7c5ed4f7b4b822d3254a4..4f9415ce4943cc1dcad015b4445ca757118b6edc 100644 --- a/docs/language/index.md +++ b/docs/language/index.md @@ -1 +1,9 @@ -# TODO \ No newline at end of file +# 语言 +当这行字正确显示是说明CI测试好了 + +
+ 邮箱地址: + +
+ +# TODO diff --git a/docs/language/keyword/alternative/and/index.md b/docs/language/keyword/alternative/and/index.md new file mode 100644 index 0000000000000000000000000000000000000000..3ff2b5e5c36b229fd23a35ae11251aa78a420632 --- /dev/null +++ b/docs/language/keyword/alternative/and/index.md @@ -0,0 +1,12 @@ +# alolang关键字:and +## 用法 +* 代用运算符:&& +## 示例 +``` +main() ->int +{ + int n; + if(n>0 and n<10) + output(stdout)({"n is small and positive\n"}); +} +``` \ No newline at end of file diff --git a/docs/language/keyword/alternative/index.md b/docs/language/keyword/alternative/index.md new file mode 100644 index 0000000000000000000000000000000000000000..1b416fdb88454bb39a9e06c956254fd403908198 --- /dev/null +++ b/docs/language/keyword/alternative/index.md @@ -0,0 +1,11 @@ +# 代用运算符的关键字 + +用于作为某个符号的替代。 + +``` +and +or +xor +not +``` + diff --git a/docs/language/keyword/alternative/not/index.md b/docs/language/keyword/alternative/not/index.md new file mode 100644 index 0000000000000000000000000000000000000000..d821decbf599f097956a525bbcd593b4b1ace1f1 --- /dev/null +++ b/docs/language/keyword/alternative/not/index.md @@ -0,0 +1,12 @@ +# alolang关键字:not +## 用法 +* 代用运算符:! +## 示例 +``` +main() ->int +{ + bool n; + if(not n) + output(stdout)({"n is false\n"}); +} +``` \ No newline at end of file diff --git a/docs/language/keyword/alternative/or/index.md b/docs/language/keyword/alternative/or/index.md new file mode 100644 index 0000000000000000000000000000000000000000..22494f62e553ad17b1998f2597d7bbefc93b2ad7 --- /dev/null +++ b/docs/language/keyword/alternative/or/index.md @@ -0,0 +1,12 @@ +# alolang关键字:or +## 用法 +* 代用运算符:|| +## 示例 +``` +main() ->int +{ + int n; + if(n<0 or n%2==0) + output(stdout)({"n is not a positive odd number\n"}); +} +``` \ No newline at end of file diff --git a/docs/language/keyword/alternative/xor/index.md b/docs/language/keyword/alternative/xor/index.md new file mode 100644 index 0000000000000000000000000000000000000000..fae51451a1eb7b6d3c920d3ab0d7181ccf2a6c1c --- /dev/null +++ b/docs/language/keyword/alternative/xor/index.md @@ -0,0 +1,3 @@ +# alolang关键字:xor +## 用法 +* 代用运算符:^ \ No newline at end of file diff --git a/docs/language/keyword/index.md b/docs/language/keyword/index.md new file mode 100644 index 0000000000000000000000000000000000000000..672e3ff875a33facfef6d9e771e2dc17232f2220 --- /dev/null +++ b/docs/language/keyword/index.md @@ -0,0 +1,6 @@ +# Alolang关键字 + +这是alolang的保留字列表,因为它们为语言所用,故这些关键词不可用于重定义或重载。 + + + diff --git a/docs/language/keyword/literal/EOF/index.md b/docs/language/keyword/literal/EOF/index.md new file mode 100644 index 0000000000000000000000000000000000000000..c0e89ce50189e5a9f6e045ae11fcc88e814ed629 --- /dev/null +++ b/docs/language/keyword/literal/EOF/index.md @@ -0,0 +1,5 @@ +# alolang关键字:EOF + +* 文件尾标识符 + +表明读入时读入到了文件尾,在命令行读入时可以通过ctrl+z输入。 \ No newline at end of file diff --git a/docs/language/keyword/literal/false/index.md b/docs/language/keyword/literal/false/index.md new file mode 100644 index 0000000000000000000000000000000000000000..92187baec48338197f1c1f1c7976f38c07e8c7f5 --- /dev/null +++ b/docs/language/keyword/literal/false/index.md @@ -0,0 +1,5 @@ +# alolang关键字:false + +* 布尔字面量 + +表明一个bool值为0。 \ No newline at end of file diff --git a/docs/language/keyword/literal/index.md b/docs/language/keyword/literal/index.md new file mode 100644 index 0000000000000000000000000000000000000000..ed8b3b5f528435b994efbe849f6b32740b523366 --- /dev/null +++ b/docs/language/keyword/literal/index.md @@ -0,0 +1,3 @@ +# 常量 + +用于表示某些常量。 \ No newline at end of file diff --git a/docs/language/keyword/literal/true/index.md b/docs/language/keyword/literal/true/index.md new file mode 100644 index 0000000000000000000000000000000000000000..f48833c1acf9590cd16cb6adbd233ef9d56d56d1 --- /dev/null +++ b/docs/language/keyword/literal/true/index.md @@ -0,0 +1,5 @@ +# alolang关键字:true + +* 布尔字面量 + +用于表示一个bool值为1。 \ No newline at end of file diff --git a/docs/language/keyword/operators/index.md b/docs/language/keyword/operators/index.md new file mode 100644 index 0000000000000000000000000000000000000000..6e444559c952039b3c3b00aafb81754d78641b97 --- /dev/null +++ b/docs/language/keyword/operators/index.md @@ -0,0 +1,3 @@ +# 运算符 + +用于数字或变量之间的运算。 \ No newline at end of file diff --git a/docs/language/keyword/operators/self_change/index.md b/docs/language/keyword/operators/self_change/index.md new file mode 100644 index 0000000000000000000000000000000000000000..a74972f338997db396ba90ff28dc8f7c7cc9e9ac --- /dev/null +++ b/docs/language/keyword/operators/self_change/index.md @@ -0,0 +1,83 @@ +# 自修改运算符 + +自修改运算符可以修改对象的值 + +| 运算符名 | 语法 | 可重载 | 原型示例 | 原型示例 | +| :------: | :---: | :----: | :------: | :------: | +| | | | 类内定义 | 类外定义 | +| 前自增 | `++a` | 是 | | | +| 前自减 | `--a` | 是 | | | +| 后自增 | `a++` | 是 | | | +| 后自减 | `a--` | 是 | | | + +注解:对于任意一个二元运算符”(T)“,“(T)=”均为不可重载的自修改运算符。 + +## 解释 + + 前自增 与 前自减 运算符增加或减小对象的值,并返回到其结果的引用。 + +后自增 与 后自减 创建对象的副本,增加或减小对象的值,并返回自增或自减前的副本。 + +## 前置运算符 + +对于非布尔操作数$x$,表达式$++x$严格等价于$x+=1$,表达式$--x$严格等价于$x-=1$ + +若其中的$x$为bool类型,则操作无效。 + +## 后置运算符 + +内建后置自增或自减运算符的操作数表达式必须是非布尔的算术类型或指向完整定义的对象类型的指针类型的可修改左值。结果是操作数原值的纯右值副本。 + +若操做数位布尔类型,则操作无效。 + +## 示例 + +``` +main() -> int +{ + int n1 = 1; + int n2 = ++n1; + int n3 = ++(++n1); + int n4 = n1++; + output(stdout)({"n1 = ",n1,"\n"}); + output(stdout)({"n2 = ",n2,"\n"}); + output(stdout)({"n3 = ",n3,"\n"}); + output(stdout)({"n4 = ",n4,"\n"}); +} +``` + +输出: + +``` +n1 = 5 +n2 = 2 +n3 = 4 +n4 = 4 +``` + +## 警告 + +在同一个计算语句中出现可能导致不同结果的对同一个变量的多次自修改操作为未定义行为。 + +### 示例 + +``` +int a=1; + +/*以下每行中的操作都是未定义行为*/ +int a1=(a++)*(++a)*(a++)*(++a); +int a2=(a-=1)*(a+=1)*(a*=2)+(a/=2); +int a3,a4;a3,a4=a++,++a; +//值得注意的是,","并不表示逗号运算符,而是元组的标志,因此不同于C语言,这行代码并不合法 + +/*以下每行的操作没有任何问题,并且可以得到正确结果*/ +int a5=(a+=0)+(a-=0)*(a*=1)*(a/=1);//a3=2 +int a6=++(++a);//a6=3 + +/*以下操作会因符号无法匹配而编译错误*/ +int a7=a+++++++++++++++++++++; +int a8=++ ++ ++ ++ a; +//上面这行代码在C中是合法的,但在alolang中,应该表示为a8=++(++(++(++a))); +int a9=a++ + ++a; +``` + diff --git a/docs/language/keyword/statements/break/index.md b/docs/language/keyword/statements/break/index.md new file mode 100644 index 0000000000000000000000000000000000000000..4c671581c59aa7c233b395c1874c802c2345af3d --- /dev/null +++ b/docs/language/keyword/statements/break/index.md @@ -0,0 +1,5 @@ +# alolang关键字:break +* break语句: +*1:break语句可以结束当前循环执行 +*2:执行完break语句后,循环体中位于break语句就不会被执行 +*3:多重循环中,break语句只向外跳一层 \ No newline at end of file diff --git a/docs/language/keyword/statements/case/index.md b/docs/language/keyword/statements/case/index.md new file mode 100644 index 0000000000000000000000000000000000000000..4706a939b9b10d04aa17c8ffecf045f255834408 --- /dev/null +++ b/docs/language/keyword/statements/case/index.md @@ -0,0 +1,2 @@ +# alolang关键字:case +* switch 语句:用作 case 标号的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/catch/index.md b/docs/language/keyword/statements/catch/index.md new file mode 100644 index 0000000000000000000000000000000000000000..9180827c05a78a3c8bf41d8eb93dc18e44ea7b46 --- /dev/null +++ b/docs/language/keyword/statements/catch/index.md @@ -0,0 +1,2 @@ +# alolang关键字:catch +* 用于try-catch块 \ No newline at end of file diff --git a/docs/language/keyword/statements/continue/index.md b/docs/language/keyword/statements/continue/index.md new file mode 100644 index 0000000000000000000000000000000000000000..5b17c45e68c900d6ff0ec798ce2a7f445db0840b --- /dev/null +++ b/docs/language/keyword/statements/continue/index.md @@ -0,0 +1,2 @@ +# alolang关键字:continue +* continue语句:跳过当前循环中的代码,强迫开始下一次循环。 \ No newline at end of file diff --git a/docs/language/keyword/statements/do/index.md b/docs/language/keyword/statements/do/index.md new file mode 100644 index 0000000000000000000000000000000000000000..0cc3655790d0ff854c2adb89bf6cd2866d7e6cbe --- /dev/null +++ b/docs/language/keyword/statements/do/index.md @@ -0,0 +1,2 @@ +# alolang关键字:do +* do-while 循环:该循环循环内容的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/else/index.md b/docs/language/keyword/statements/else/index.md new file mode 100644 index 0000000000000000000000000000000000000000..26b9314279d5d3328566080501cf79d0068ba0fa --- /dev/null +++ b/docs/language/keyword/statements/else/index.md @@ -0,0 +1,2 @@ +# alolang关键字:else +* if语句:用于另一分支的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/export/index.md b/docs/language/keyword/statements/export/index.md new file mode 100644 index 0000000000000000000000000000000000000000..7243710099cdb57048f164d496510246f46bf1d1 --- /dev/null +++ b/docs/language/keyword/statements/export/index.md @@ -0,0 +1,2 @@ +# alolang关键字:export +* 语言链接语句。 diff --git a/docs/language/keyword/statements/extern/index.md b/docs/language/keyword/statements/extern/index.md new file mode 100644 index 0000000000000000000000000000000000000000..f9ca999a2d7b9c029ef8a3fe2ee0149e353db9c4 --- /dev/null +++ b/docs/language/keyword/statements/extern/index.md @@ -0,0 +1,2 @@ +# alolang关键字:extern +* 语言链接语句。 diff --git a/docs/language/keyword/statements/for/index.md b/docs/language/keyword/statements/for/index.md new file mode 100644 index 0000000000000000000000000000000000000000..e63ffa858ae07dc45fa3be4498451877a83fe67d --- /dev/null +++ b/docs/language/keyword/statements/for/index.md @@ -0,0 +1,2 @@ +# alolang关键字:for +* for循环:用于此循环的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/foreach/index.md b/docs/language/keyword/statements/foreach/index.md new file mode 100644 index 0000000000000000000000000000000000000000..154b3bb9b781262950281fc4ab4cf5e9d6f0bcee --- /dev/null +++ b/docs/language/keyword/statements/foreach/index.md @@ -0,0 +1,2 @@ +# alolang关键字:foreach +* foreach循环:用于带有范围限制的foreach循环的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/goto/index.md b/docs/language/keyword/statements/goto/index.md new file mode 100644 index 0000000000000000000000000000000000000000..d9d94ec964a4ffa181880b4b2e12184a807d562b --- /dev/null +++ b/docs/language/keyword/statements/goto/index.md @@ -0,0 +1,22 @@ +# alolang关键字:goto +* goto语句:用于goto语句的声明 + +例子: + +```AloLang +func main() -> int +{ + int a = 0; + while (statements){ + if (statement) + goto LAB1; + } +LAB1: + //After loop +} + +``` + +建议仅用于跳出多层循环使用 + +!> 注意:使用goto语句跳过变量声明/初始化语句是未定义行为,可能会有危险后果 diff --git a/docs/language/keyword/statements/if/index.md b/docs/language/keyword/statements/if/index.md new file mode 100644 index 0000000000000000000000000000000000000000..88fbb741f166ca12d6177267f6d6784bce72480d --- /dev/null +++ b/docs/language/keyword/statements/if/index.md @@ -0,0 +1,2 @@ +# alolang关键字:if +* if语句:用于if语句的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/index.md b/docs/language/keyword/statements/index.md new file mode 100644 index 0000000000000000000000000000000000000000..c6318b620ec389f7354a8404b8833ed66366583f --- /dev/null +++ b/docs/language/keyword/statements/index.md @@ -0,0 +1,23 @@ +# 语句声明关键字 + +用于声明语句和语句块的关键字。 + +包含以下几种 + +``` +break +continue +case +do +else +for +foreach +goto +if +return +switch +try +catch +while +``` + diff --git a/docs/language/keyword/statements/return/index.md b/docs/language/keyword/statements/return/index.md new file mode 100644 index 0000000000000000000000000000000000000000..07c8cc23446a1047f176f03236e33e999bd19adc --- /dev/null +++ b/docs/language/keyword/statements/return/index.md @@ -0,0 +1,2 @@ +# alolang关键字:return +* return语句:用于语句的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/switch/index.md b/docs/language/keyword/statements/switch/index.md new file mode 100644 index 0000000000000000000000000000000000000000..5c2cdb409e346fca9b2ac5699e05bb8dac35136b --- /dev/null +++ b/docs/language/keyword/statements/switch/index.md @@ -0,0 +1,2 @@ +# alolang关键字:switch +* switch语句:用于该语句的声明 \ No newline at end of file diff --git a/docs/language/keyword/statements/try/index.md b/docs/language/keyword/statements/try/index.md new file mode 100644 index 0000000000000000000000000000000000000000..20af4b166e9f6ecebbfb02c0a8d1bcef10963d0a --- /dev/null +++ b/docs/language/keyword/statements/try/index.md @@ -0,0 +1,2 @@ +# alolang关键字:try +* 用于try-catch块 \ No newline at end of file diff --git a/docs/language/keyword/statements/while/index.md b/docs/language/keyword/statements/while/index.md new file mode 100644 index 0000000000000000000000000000000000000000..a65549e6ef1df3417a0a016cfc40cc62e2d521e8 --- /dev/null +++ b/docs/language/keyword/statements/while/index.md @@ -0,0 +1,3 @@ +# alolang关键字:while +* while 循环:该循环的声明 +* do-while 循环:该循环终止条件的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/anytype/index.md b/docs/language/keyword/type/anytype/index.md new file mode 100644 index 0000000000000000000000000000000000000000..2488a8716ef27f439fb4f2cdd5ae04736630600a --- /dev/null +++ b/docs/language/keyword/type/anytype/index.md @@ -0,0 +1,42 @@ +# alolang关键字:anytype + +* 用于函数的任意类型传入,传出 +* 用于接收函数传出值的临时变量,占位符类型说明符,等效于auto + +### 使用 +``` +anytype +``` +当在传入列表时,表示传入函数的某一个参数类型为type1,type2,type3的一种。 + +当在传出列表时,返回值需要自己指定一个类型。 + +若指定的类型与实际传出类型不一致,则将传出的数据截取并复制到使用者指定的变量中,并不保证截取后数据的准确性。 + +例如 + +``` +test(int a) -> anytype +{ + if(a>0) + return 1; + else + return 2.0; +} +int k1=test(1); +array(int,3) k2=test(1); +anytype k3=test(1); +anytype k4=test(-1); +array(int,2) k5=test(-1); +``` + +此时 + +``` +k1为int类型,k1=1 +k2为array类型,k2=2.0 +k3被限制为int类型,k3=1 +k4被限制为double类型,k4=2.0 +此时有k5[0]为返回值的前四个字节,k5[1]为返回值的后四个字节,我们不保证这样的操作结果的准确性 +``` + diff --git a/docs/language/keyword/type/array/index.md b/docs/language/keyword/type/array/index.md new file mode 100644 index 0000000000000000000000000000000000000000..10857c783090331dbc2f3af3977007312096c130 --- /dev/null +++ b/docs/language/keyword/type/array/index.md @@ -0,0 +1,6 @@ +# alolang关键字:array + +用于对数组的声明,使用方法为array(元素类型,长度)。 + +#### 备注 +alolang 不支持 "元素类型[长度]" 的方式定义数组。 diff --git a/docs/language/keyword/type/auto/index.md b/docs/language/keyword/type/auto/index.md new file mode 100644 index 0000000000000000000000000000000000000000..c94c56e5eb2b4b2e94acdb6d69f309c4e56fad3d --- /dev/null +++ b/docs/language/keyword/type/auto/index.md @@ -0,0 +1,6 @@ +# alolang关键词:auto + +* 占位符类型说明符 + +从初始化器推导某一个变量的类型。 +不可用于函数返回值的声明。 \ No newline at end of file diff --git a/docs/language/keyword/type/bool/index.md b/docs/language/keyword/type/bool/index.md new file mode 100644 index 0000000000000000000000000000000000000000..6a66e009f6f21c366fb355a7d5d6e3ee29ceaa68 --- /dev/null +++ b/docs/language/keyword/type/bool/index.md @@ -0,0 +1,3 @@ +# alolang关键字:bool + +*用于对bool类型的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/char/index.md b/docs/language/keyword/type/char/index.md new file mode 100644 index 0000000000000000000000000000000000000000..eb657d28151aeb0baae6d80505af726ca18b9ee8 --- /dev/null +++ b/docs/language/keyword/type/char/index.md @@ -0,0 +1,5 @@ +# alolang关键字:char + +* 用于char类型的声明。 + +* 备注:声明的array不能作为字符串来使用。 \ No newline at end of file diff --git a/docs/language/keyword/type/double/index.md b/docs/language/keyword/type/double/index.md new file mode 100644 index 0000000000000000000000000000000000000000..6767579ae5052aec2c9cf58f93118dc2d53ba9e7 --- /dev/null +++ b/docs/language/keyword/type/double/index.md @@ -0,0 +1,3 @@ +# alolang关键字:double + +* 用于对双精度浮点数double类型的声明。 diff --git a/docs/language/keyword/type/enum/index.md b/docs/language/keyword/type/enum/index.md new file mode 100644 index 0000000000000000000000000000000000000000..254e144459021ee330bf131dfb565b83914ff49e --- /dev/null +++ b/docs/language/keyword/type/enum/index.md @@ -0,0 +1,3 @@ +# alolang关键字:enum + +* 用于对枚举的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/float/index.md b/docs/language/keyword/type/float/index.md new file mode 100644 index 0000000000000000000000000000000000000000..0d028a703fe3bd4b281e27fd3e30f6d5e3a0b0a3 --- /dev/null +++ b/docs/language/keyword/type/float/index.md @@ -0,0 +1,3 @@ +# alolang关键字:float + +* 用于对单精度浮点数类型float的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/index.md b/docs/language/keyword/type/index.md new file mode 100644 index 0000000000000000000000000000000000000000..8dad771cb8305724c4d589f2dc95cbf428c5a34e --- /dev/null +++ b/docs/language/keyword/type/index.md @@ -0,0 +1,24 @@ +# 类型关键字 + +用于基础类型的声明和修饰的关键字。 + +包含下面这几种 + +``` +anytype +array +auto +bool +char +double +enum +float +long +int +signed +string +struct +unsigned +void +``` + diff --git a/docs/language/keyword/type/int/index.md b/docs/language/keyword/type/int/index.md new file mode 100644 index 0000000000000000000000000000000000000000..034f8af3419caef14f487f649f3816da0adf5a72 --- /dev/null +++ b/docs/language/keyword/type/int/index.md @@ -0,0 +1,3 @@ +# alolang关键字:int + +* 用于对64位整数int类型的声明。 \ No newline at end of file diff --git a/docs/language/keyword/type/int16_t/index.md b/docs/language/keyword/type/int16_t/index.md new file mode 100644 index 0000000000000000000000000000000000000000..273d20bd42a30503fcfbadb8fda5fe2241e8665e --- /dev/null +++ b/docs/language/keyword/type/int16_t/index.md @@ -0,0 +1,3 @@ +# alolang关键字:int16_t + +* 用于对16位整数类型的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/int32_t/index.md b/docs/language/keyword/type/int32_t/index.md new file mode 100644 index 0000000000000000000000000000000000000000..5d7f43f8140b8979c60d70077d7d11ab2503b778 --- /dev/null +++ b/docs/language/keyword/type/int32_t/index.md @@ -0,0 +1,3 @@ +# alolang关键字:int32_t + +* 用于对32位整数类型的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/int8_t/index.md b/docs/language/keyword/type/int8_t/index.md new file mode 100644 index 0000000000000000000000000000000000000000..9955c017f9619666803fd68ad6d93fa757d5c72c --- /dev/null +++ b/docs/language/keyword/type/int8_t/index.md @@ -0,0 +1,3 @@ +# alolang关键字:int8_t + +* 等效于char \ No newline at end of file diff --git a/docs/language/keyword/type/long/index.md b/docs/language/keyword/type/long/index.md new file mode 100644 index 0000000000000000000000000000000000000000..9d50199cf3dc8f60ab9c6d54ed4b14df9907accc --- /dev/null +++ b/docs/language/keyword/type/long/index.md @@ -0,0 +1,3 @@ +# alolang关键字:long + +* 用于对long类型的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/signed/index.md b/docs/language/keyword/type/signed/index.md new file mode 100644 index 0000000000000000000000000000000000000000..3715571ec56836611a9072c968251f43b094228a --- /dev/null +++ b/docs/language/keyword/type/signed/index.md @@ -0,0 +1,5 @@ +# alolang关键字:signed + +* 用于表明一个变量位有符号类型 + +可以省略,默认为有符号类型。 \ No newline at end of file diff --git a/docs/language/keyword/type/string/index.md b/docs/language/keyword/type/string/index.md new file mode 100644 index 0000000000000000000000000000000000000000..935151aed68f8436f795fb9bc13e1a041e9cabe1 --- /dev/null +++ b/docs/language/keyword/type/string/index.md @@ -0,0 +1,3 @@ +# alolang关键字:string + +* 用于对字符串类型的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/struct/index.md b/docs/language/keyword/type/struct/index.md new file mode 100644 index 0000000000000000000000000000000000000000..73bdaaed104cc5cd1b477d088ff8c64fb813a5fc --- /dev/null +++ b/docs/language/keyword/type/struct/index.md @@ -0,0 +1,3 @@ +# alolang关键字:struct + +* 用于对结构体的声明 \ No newline at end of file diff --git a/docs/language/keyword/type/unsigned/index.md b/docs/language/keyword/type/unsigned/index.md new file mode 100644 index 0000000000000000000000000000000000000000..e60152442ccb88d3f39d6aa5667eef344b0142aa --- /dev/null +++ b/docs/language/keyword/type/unsigned/index.md @@ -0,0 +1,5 @@ +# alolang关键词:unsigned + +* 用于表明某个变量为无符号类型 + +unsigned bool无效。 \ No newline at end of file diff --git a/docs/language/keyword/type/void/index.md b/docs/language/keyword/type/void/index.md new file mode 100644 index 0000000000000000000000000000000000000000..513e5bcdcb2427d1bf6f7bc6a67cfc6754a67af7 --- /dev/null +++ b/docs/language/keyword/type/void/index.md @@ -0,0 +1,5 @@ +# alolang关键字:void + +* void类型,但是不能用于定义一个void类型的对象 +* 无形参函数的传入列表(可省略) +* 无返回值函数的返回值列表 \ No newline at end of file diff --git a/docs/language/preprocessor/conditional/index.md b/docs/language/preprocessor/conditional/index.md new file mode 100644 index 0000000000000000000000000000000000000000..5d67ba41a2af8970d44193893f46ee4d4d7f591e --- /dev/null +++ b/docs/language/preprocessor/conditional/index.md @@ -0,0 +1,51 @@ +# 条件包含 +预处理器支持有条件地编译源文件的某些部分。这一行为由 #if、#else、#elif、#ifdef、#ifndef 与 #endif 指令所控制。 + +## 语法 +``` +%ifdef 标识符 +%ifndef 标识符 +%endif +``` +## 解释 +条件预处理块由`%ifdef`或`%ifndef`指令开始,并以`%endif`指令结束。嵌套的条件预处理块会被单独处理。 + +`%ifdef` 和 `%ifndef` 指令所控制的代码块在第一个不属于内部嵌套的条件预处理块的 `%endif` 指令处结束。 + +`%ifdef` 和 `%ifndef` 指令测试其所指定的条件(见下文),如果条件求值为真,则编译其控制的代码块。否则,如果所指定的条件求值为假,则跳过其所控制的代码块。 +## 条件的求值 +`%ifdef`, `%ifndef`检查标识符是否被定义为宏名。 + +## 示例(TODO:待更改) + +``` +#define ABCD 2 +#include + +int main() +{ + +#ifdef ABCD + std::cout << "1: yes\n"; +#else + std::cout << "1: no\n"; +#endif + +#ifndef ABCD + std::cout << "2: no1\n"; +#elif ABCD == 2 + std::cout << "2: yes\n"; +#else + std::cout << "2: no2\n"; +#endif + +#if !defined(DCBA) && (ABCD < 2*4-3) + std::cout << "3: yes\n"; +#endif +} +输出: + +1: yes +2: yes +3: yes +``` \ No newline at end of file diff --git a/docs/language/preprocessor/import/index.md b/docs/language/preprocessor/import/index.md index 4f21e09f6805abba1e4b631694ac8c76729be9ac..2b4f8492e9560ae8bcb5d5b7f4ec90bdf64e737a 100644 --- a/docs/language/preprocessor/import/index.md +++ b/docs/language/preprocessor/import/index.md @@ -7,3 +7,6 @@ 解释 (1) 将 文件名 所标识的源文件包含到当前源文件中紧随指令后的一行。找不到文件的情况下,报编译期致命错误。 + +##注意 +`%import`递归引用的最大深度为128层 \ No newline at end of file diff --git a/docs/language/preprocessor/index.md b/docs/language/preprocessor/index.md index f87f5c14cbbd7d462ab7c5ed4f7b4b822d3254a4..906345d33860e13a3737593101dad8848f38a12a 100644 --- a/docs/language/preprocessor/index.md +++ b/docs/language/preprocessor/index.md @@ -1 +1,18 @@ -# TODO \ No newline at end of file +# 预处理器 +预处理的结果是单个文件,接下来它会被传递给实际编译器。 + +## 指令 +预处理指令控制预处理器的行为。每个指令占据一行并拥有下列格式: +``` +%预处理指令(import、def、rmdef、ifdef、ifndef、endif之一) 实参(取决于指令) +``` +不允许空指令(即在 # 后直接换行)。 + +## 能力 +预处理器有能力翻译源文件: + +1.有条件地编译源文件的某些部分(由 `%ifdef`、`%ifndef`和 `%endif` 指令控制),参见[“条件编译”](language/preprocessor/conditional/index)。 + +2.替换文本宏,同时可能对标识符进行拼接或加引号(由 `%def` 和 `%rmdef` 指令与 % 运算符控制),参见[“宏定义”](language/preprocessor/replace/index)。 + +3.包含其他文件(由 `%import` 指令控制),参见[“包含”](language/preprocessor/import/index)。 \ No newline at end of file diff --git a/docs/language/preprocessor/replace/index.md b/docs/language/preprocessor/replace/index.md new file mode 100644 index 0000000000000000000000000000000000000000..34ebd579a07675c0f1c32582b12c758441412b6d --- /dev/null +++ b/docs/language/preprocessor/replace/index.md @@ -0,0 +1,2 @@ +# 宏定义 +# TODO \ No newline at end of file diff --git a/docs/language/statements/index.md b/docs/language/statements/index.md index f56660bdaf8613ddfc033e84de446fc675f1354b..50c2d8d389fdb426b62d5dfd3127b9cd48c03de7 100644 --- a/docs/language/statements/index.md +++ b/docs/language/statements/index.md @@ -1,26 +1,10 @@ -## 控制语句 - -支持`while(): ... end while`、`for(): ... end for`等 - -``` alolang -while (i-->0): - //do - //something -end while -``` - -以及代码块 - -同时,应有for each的支持,如: - -``` alolang -vector items; -items.assign({1,2,3,4,5}); -for each item in items: - printf(item); -end for -``` - -支持goto控制语句,支持行标 - -# TODO:待完善 \ No newline at end of file +# 语句 +语句表示依照一定顺序执行的程序片段。函数同样被视为语句。 + +alolang包含以下几种类型的语句 +* 1.预处理语句(见“预处理”部分) +* 2.表达式语句 +* 3.操作语句 +* 4.错误处理语句 +* 5.链接与跨语言通信语句 +* 6.语句块 \ No newline at end of file diff --git a/docs/language/statements/linkage/basic/index.md b/docs/language/statements/linkage/basic/index.md new file mode 100644 index 0000000000000000000000000000000000000000..a9a4e0064e4fcb4f14a36773fd96ddb44a95964c --- /dev/null +++ b/docs/language/statements/linkage/basic/index.md @@ -0,0 +1,55 @@ +# 链接语句 +用于资源的引用和导出。 + +使用方法: + +```alolang +extern(optional"language")type identifier; +export identifier; +``` + +## 1.extern:用于c,cpp内容的链接 + +#### 链接规则: + +1.在同一文件中具有相同名字和相同形参列表的两个函数,不能拥有两个不同的语言链接(形参的链接允许重载)。 + +2.一个外部语言变量不能与一个外部语言函数具有相同的名称。 + +3.当链接内容相互调用的时候,遵从cpp的链接规则 + +#### 注解: + +一般仅用于系统底层的调用,不建议在正常的代码中使用 + +#### 例子: + +``` +extern("C") func puts(const char*)->int; +``` + +用于表示puts原型为C函数,编译器会将其封装为alolang函数,使其可以在alolang程序中被调用。 + +## 2.extern:用于alolang内容的链接 + +* 表明某个变量或者函数在其他地方定义并export + +#### 例子: + +``` +extern("alolang") func add(int a,int b)->int; +``` + +## 3.export:用于alolang内容的导出 + +* 用于导出某个声明 + +#### 例子: + +``` +export func add(int a,int b)->int +{ + return a+b; +} +``` + diff --git a/docs/language/statements/linkage/communicate/index.md b/docs/language/statements/linkage/communicate/index.md new file mode 100644 index 0000000000000000000000000000000000000000..44134657bd41fa6f556daa73c19c289165180494 --- /dev/null +++ b/docs/language/statements/linkage/communicate/index.md @@ -0,0 +1,3 @@ +# 跨语言通信语句 + +## TODO \ No newline at end of file diff --git a/docs/library/graph/index.md b/docs/library/graph/index.md new file mode 100644 index 0000000000000000000000000000000000000000..63456fbd3d9a7636308945db9210f786e7bb06d4 --- /dev/null +++ b/docs/library/graph/index.md @@ -0,0 +1,44 @@ +# alolang库:图 + +* 数据结构类型:图 + +声明:Graph(变量类型) 变量名 ; + +Graph类中包含两个结构体数组point和side,分别表示点和边,点本身是无序的,不支持根据点的序号来进行删除/添加边的操作。 + +``` +struct point +{ + type x; + type y; +}; +struct side +{ + point a; + point b; +}; +``` + + + +Graph类中包含的函数如下: + + getPointsNum() -> int 返回点的数目 + getSidesNum() -> int 返回边的数目(带方向) + + //以下的四个函数可以保证安全 + addSide(point x,point y) -> bool 表示在坐标为的间加一条边为x->y,返回false为添加失败 + delSide(point x,point y) ->bool 表示删掉x->y的边,返回false为添加失败 + addPoint(point i) ->bool //表示添加一个坐标为i的点,返回false为添加失败 + delPoint(point i) ->bool //表示删除坐标为i的点,返回false为删除失败 + + operator && (Graph x1,Graph x2) ->Graph //表示将两个图的边集合取交集,顶点数按最大的计算 + operator || (Graph x1,Graph x2) ->Graph //表示将两个图的边集合取并集,顶点数按最大的计算 + operator ! () -> Graph //表示将一个图取补 + + isConnected() -> bool //返回是否为连通图 + isCompleted() -> bool //返回是否为完全图 + getCircleNum() -> unsigned int //返回欧拉回路的数量 + max_completed_part() -> int //返回最大完全图的顶点数 +# TODO + diff --git a/docs/library/index.md b/docs/library/index.md new file mode 100644 index 0000000000000000000000000000000000000000..5cd3bf19f802340d01483a18061f1071c5ddda1b --- /dev/null +++ b/docs/library/index.md @@ -0,0 +1,4 @@ +# 标准库 + +# Todo + diff --git a/docs/library/math/index.md b/docs/library/math/index.md new file mode 100644 index 0000000000000000000000000000000000000000..291ae7af0d693bec13bcedcd76c3f7a2fced509e --- /dev/null +++ b/docs/library/math/index.md @@ -0,0 +1,57 @@ +# alolang库:math + +#### **abs(x)** + +* 参数: + + x: int型或long型或double型 + +返回x的绝对值。 + +* 返回值: + + int型或long型或double型(与x的类型相同) + + + +#### **ceil(x)** + +* 参数: + + x: double型 + +返回大于或等于x的最小整数。 + +* 返回值: + + long型 + + + +#### **comb(x)** + +* 参数: + + m: int型 + + n: int型 + +返回从m个物品中选n个的排列数。 + +* 返回值: + + long型 + + + +#### **floor(x)** + +* 参数: + + x: double型 + +返回小于或等于x的最大整数。 + +* 返回值: + + long型 \ No newline at end of file diff --git a/libraries/CSharp.cpp b/libraries/CSharp.cpp deleted file mode 100644 index 15b530a7d3fd1d114d3e79af45bb96548c3a5109..0000000000000000000000000000000000000000 --- a/libraries/CSharp.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#define CSharp -#define Csharp -#define csharp - -#include -#include -#include -#include - -#if defined(_WIN32) || defined(WIN32) || defined(__WIN32__) - -#include - -string CSCompilerPath; - - - - -#elif defined(__linux) || defined(__linux__) || defined(linux) - -#include -#include - diff --git a/make-config b/make-config deleted file mode 100755 index dd5c8b3b38e0158ac593996c268369109fddfba0..0000000000000000000000000000000000000000 Binary files a/make-config and /dev/null differ diff --git a/make-config.cc b/make-config.cc deleted file mode 100644 index 56f0ea17f6b370fb69809f83ab39ad648dbcfada..0000000000000000000000000000000000000000 --- a/make-config.cc +++ /dev/null @@ -1,25 +0,0 @@ -#include -using namespace std; - -int main() -{ - string tmp1, tmp2; - cerr << "Specifi compiler path: "; - getline(cin, tmp1); - tmp2 = "CC = "; - tmp2 += tmp1; - cout << tmp2 << endl; - - cerr << "Specifi ar path: "; - getline(cin, tmp1); - tmp2 = "AR = "; - tmp2 += tmp1; - cout << tmp2 << endl; - - cerr << "Specifi compile flag(include include path): "; - getline(cin, tmp1); - tmp2 = "CFLAG = "; - tmp2 += tmp1; - cout << tmp2 << endl; - -} \ No newline at end of file diff --git a/compiler/compileerror.hpp b/src/CompileError.hpp similarity index 34% rename from compiler/compileerror.hpp rename to src/CompileError.hpp index f9f3b8789a86d646b3951db6a391e651e494bc9b..89acd1b415fae05f1f718755a21687e6f6be288e 100644 --- a/compiler/compileerror.hpp +++ b/src/CompileError.hpp @@ -1,25 +1,17 @@ // compileerror.hpp header for CompileError exeption class #ifndef _COMPILE_ERROR_ #define _COMPILE_ERROR_ -#include #include +#include -class CompileError: public std::exception { -private: - std::string error; -public: - const char *what() const throw() - { - return error.c_str(); - } - CompileError(const char *whatError) - { - error = whatError; - } - CompileError(const std::string &whatError) - { - error = whatError; - } +class CompileError : public std::exception +{ + private: + std::string error; + public: + const char *what() const throw() { return error.c_str(); } + CompileError(const char *whatError) { error = whatError; } + CompileError(const std::string &whatError) { error = whatError; } }; #endif diff --git a/src/CompileUnit.cpp b/src/CompileUnit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2b25b39ba4b06aa31bef2febd7537dcf5aa60819 --- /dev/null +++ b/src/CompileUnit.cpp @@ -0,0 +1,145 @@ +/* + * CompileUnit.cpp + * + * Created on: Dec 16, 2020 + * Author: zbc + */ + +#include "CompileUnit.h" +#include "CompileError.hpp" +#include +#include +#include +#include +#include +#include + +#include "ast/ExprAST.h" +#include "ast/ExternAST.h" +#include "ast/FunctionAST.h" +#include "ast/TypeAST.h" +#include "utils.h" +#include +#include + +void initInnerType(CompileUnit *unit) +{ + unit->types.insert( + std::pair("int", new TypeAST(unit, "int"))); + unit->types.insert( + std::pair("bool", new TypeAST(unit, "bool"))); +} + +void scanToken(CompileUnit *unit) +{ + Token token; + do { + int tokenid = unit->lexer->yylex(); + token.type = TokenType(tokenid); + token.lineno = unit->lexer->lineno(); + switch (token.type) { + tok_fun: + tok_extern: + tok_return: + tok_return_type: + tok_eof: + break; + default: + token.tokenValue = unit->lexer->YYText(); + } + // Deal with numbers + if (token.type == tok_number) { + int numTypeFlag = 10; //进制数 + if (token.tokenValue.substr(0, 2) == "0x" || + token.tokenValue.substr(0, 2) == "0X") + numTypeFlag = 16; + else if (token.tokenValue.substr(0, 2) == "0b" || + token.tokenValue.substr(0, 2) == "0B") + numTypeFlag = 2; + else if (token.tokenValue.substr(0, 1) == "0") + numTypeFlag = 8; + char tmp[256]; + sprintf(tmp, "%ld", + strtol(token.tokenValue.c_str(), NULL, numTypeFlag)); + token.tokenValue = tmp; + } + + // Debug token dump + std::cout << token.dump() << std::endl; + + unit->tokenList.push_back(token); + } while (token.type != tok_eof); + + unit->icurTok = unit->tokenList.begin(); +} + +CompileUnit::CompileUnit(std::string name, std::string source) +{ + this->name = name; + this->source = source; + this->sis = std::istringstream(source); + this->lexer = new yyFlexLexer(sis, std::cerr); + context = new llvm::LLVMContext(); + module = new llvm::Module("test.ll", *context); +} + +CompileUnit::~CompileUnit() {} + +//获取下一个Token +Token CompileUnit::next_tok() +{ + icurTok++; + Token token = *icurTok; + return token; +} + +void CompileUnit::compile() +{ + std::cout << "Start compiling:" << name << std::endl; + initInnerType(this); + scanToken(this); + do { + switch (icurTok->type) { + case tok_fun: { + FunctionAST * func_ast = FunctionAST::ParseFunction(this); + llvm::Function *func = func_ast->Codegen(); + /*llvm::Type* + type=llvm::FunctionType::get(llvm::Type::getVoidTy(*context), + false); + module->getOrInsertGlobal(func_ast->proto->name, func->getType()); + + llvm::GlobalVariable + *gVar=module->getNamedGlobal(func_ast->proto->name); + gVar->setConstant(true); + gVar->setInitializer(func);*/ + break; + } + case tok_extern: { + Token token = next_tok(); + if (token.type == tok_eof) { + CompileError e("Unexpected EOF in funtion body, line " + + std::to_string(token.lineno)); + throw e; + } + if (token.type == tok_fun) { + ExternAST::ParseExtern(this)->Codegen(); + } + // todo:对导出非函数符号的处理 + break; + } + default: + + std::cerr << "unexpected token:" << icurTok->dump() << std::endl; + } + } while (next_tok().type != tok_eof); + build(); +} + +void CompileUnit::build() +{ + std::error_code EC; + // TODO:OpenFlag对LLVM11兼容性的更改 + llvm::raw_fd_ostream OS(name + ".bc", EC); + llvm::WriteBitcodeToFile(*module, OS); + OS.flush(); +} diff --git a/src/CompileUnit.h b/src/CompileUnit.h new file mode 100644 index 0000000000000000000000000000000000000000..af1c1dc3e9c655cd4448137b15aca44b5298685c --- /dev/null +++ b/src/CompileUnit.h @@ -0,0 +1,39 @@ +/* + * CompileUnit.h + * + * Created on: Dec 16, 2020 + * Author: zbc + */ + +#ifndef COMPILER_COMPILEUNIT_H_ +#define COMPILER_COMPILEUNIT_H_ + +#include "Token.h" +#include +#include +#include +#include +#include + +class TypeAST; +class CompileUnit +{ + public: + CompileUnit(std::string name, std::string source); + virtual ~CompileUnit(); + void compile(); + Token next_tok(); + void build(); + + FlexLexer * lexer; + std::string name; + std::string source; + std::istringstream sis; + llvm::LLVMContext * context; + llvm::Module * module; + std::vector tokenList; + std::vector::iterator icurTok; + std::map types; +}; + +#endif /* COMPILER_COMPILEUNIT_H_ */ diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..dc1f9b8d55a62995e0a7302f447341bff2f708a5 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,16 @@ +AUTOMAKE_OPTIONS = foreign subdir-objects +bin_PROGRAMS = aloc +aloc_SOURCES = aloc.cpp CompileUnit.cpp preprocessor.cpp Token.cpp utils.cpp\ + ast/AssignmentAST.cpp ast/BaseAST.cpp ast/BinaryExprAST.cpp ast/BoolExprAST.cpp ast/CallExprAST.cpp ast/CodeBlockAST.cpp\ + ast/ExprAST.cpp ast/ExternAST.cpp ast/FunctionAST.cpp ast/IntExprAST.cpp ast/IfExprAST.cpp ast/PrototypeAST.cpp\ + ast/TypeAST.cpp ast/VariableExprAST.cpp yacc_stuff/tokenizer.lpp + +AM_LFLAGS = -o lex.yy.c + +ldflagsLLVM := $(shell llvm-config --ldflags) +cxxflagsLLVM := $(shell llvm-config --cxxflags) +libLLVM := $(shell llvm-config --libs) +includeLLVM := $(shell llvm-config --includedir) + +aloc_CPPFLAGS = $(cxxflagsLLVM) -I$(includeLLVM) -I$(srcdir) -fexceptions +aloc_LDFLAGS = $(ldflagsLLVM) $(libLLVM) -lboost_program_options diff --git a/src/Token.cpp b/src/Token.cpp new file mode 100644 index 0000000000000000000000000000000000000000..166410f2213c92b23317e06d369e70030fbcc0f4 --- /dev/null +++ b/src/Token.cpp @@ -0,0 +1,105 @@ +/* + * Token.cpp + * + * Created on: Dec 16, 2020 + * Author: zbc + */ + +#include "Token.h" +#include +#include + +Token::Token() +{ + tokenValue = ""; + type = tok_err; + lineno = 0; +} + +Token::~Token() +{ + // TODO Auto-generated destructor stub +} + +std::string Token::dump() +{ + // TODO 先这样写着吧,反正是调试用 + std::string typeStr; + std::stringstream ss; + switch (type) { + case tok_err: + typeStr = "tok_err"; + break; + case tok_eof: + typeStr = "tok_eof"; + break; + case tok_fun: + typeStr = "tok_fun"; + break; + case tok_extern: + typeStr = "tok_extern"; + break; + case tok_identifier: + typeStr = "tok_identifier"; + break; + case tok_number: + typeStr = "tok_number"; + break; + case tok_type: + typeStr = "tok_type"; + break; + case tok_return: + typeStr = "tok_return"; + break; + case tok_return_type: + typeStr = "tok_return_type"; + break; + case tok_syntax: + typeStr = "tok_syntax"; + break; + case tok_str: + typeStr = "tok_str"; + break; + case tok_key_op: + typeStr = "tok_key_op"; + break; + case tok_key_literal: + typeStr = "tok_key_literal"; + break; + case tok_key_break: + typeStr = "tok_key_break"; + break; + case tok_key_continue: + typeStr = "tok_key_continue"; + break; + case tok_key_do: + typeStr = "tok_key_do"; + break; + case tok_key_else: + typeStr = "tok_key_else"; + break; + case tok_key_for: + typeStr = "tok_key_for"; + break; + case tok_key_foreach: + typeStr = "tok_key_foreach"; + break; + case tok_key_goto: + typeStr = "tok_key_goto"; + break; + case tok_key_if: + typeStr = "tok_key_if"; + break; + case tok_key_while: + typeStr = "tok_key_while"; + break; + case tok_key_switch: + typeStr = "tok_key_switch"; + break; + default: + typeStr = "not defined"; + } + ss << std::left << "Line " << std::setw(6) << lineno + << " type:" << std::setw(16) << typeStr << " data:" << tokenValue; + return ss.str(); +} diff --git a/src/Token.h b/src/Token.h new file mode 100644 index 0000000000000000000000000000000000000000..5eb95465b177c8d2d4ea526a6b96634a4a05f084 --- /dev/null +++ b/src/Token.h @@ -0,0 +1,50 @@ +/* + * Token.h + * + * Created on: Dec 16, 2020 + * Author: zbc + */ + +#ifndef COMPILER_TOKEN_H_ +#define COMPILER_TOKEN_H_ + +#include + +enum TokenType { + tok_err, + tok_eof, + tok_fun, + tok_extern, + tok_identifier, + tok_number, + tok_type, + tok_return, + tok_return_type, + tok_syntax, + tok_str, + tok_key_op, + tok_key_literal, + tok_key_break, + tok_key_continue, + tok_key_do, + tok_key_else, + tok_key_for, + tok_key_foreach, + tok_key_goto, + tok_key_if, + tok_key_while, + tok_key_switch +}; + +class Token +{ + public: + Token(); + virtual ~Token(); + std::string dump(); + TokenType type; + std::string tokenValue; + uint64_t lineno; +}; + +#endif /* COMPILER_TOKEN_H_ */ diff --git a/src/aloc.cpp b/src/aloc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1cacf19887b5afe66da3684d99db29e21c19a7bd --- /dev/null +++ b/src/aloc.cpp @@ -0,0 +1,145 @@ +#include "CompileError.hpp" +#include "CompileUnit.h" +#include "preprocessor.h" +#include "utils.h" +#include +#include +#include +#include +#include +#include +#include + +int opt; + +std::ifstream fin; +std::ofstream fout; + +using std::cerr; +using std::cout; +using std::endl; +using std::string; +using std::vector; + +namespace po = boost::program_options; + +std::vector input_file_names; +std::string output_file_name; +std::string alolanglibdir; + +int main(int argc, char *argv[]) +{ + try { + // Declare a group of options that will be + // allowed only on command line + po::options_description generic("Generic options"); + generic.add_options()("version,v", "print version string")( + "help", "produce help message")("static", + "Build static linked executable"); + + // Declare a group of options that will be + // allowed both on command line and in + // config file + po::options_description config("Configuration"); + config.add_options()("output,o", po::value(), "output file"); + config.add_options()( + "alolanglib,L", po::value(), + "Alolang Core Library Position, default to src/lib"); + + // Hidden options, will be allowed both on command line and + // in config file, but will not be shown to the user. + po::options_description hidden("Hidden options"); + hidden.add_options()("input-file", po::value>(), + "input file"); + po::options_description cmdline_options; + cmdline_options.add(generic).add(config).add(hidden); + + po::options_description visible("Allowed options"); + visible.add(generic).add(config); + + po::positional_options_description p; + p.add("input-file", -1); + + po::variables_map vm; + store(po::command_line_parser(argc, argv) + .options(cmdline_options) + .positional(p) + .run(), + vm); + po::notify(vm); + + if (vm.count("help")) { + cout << "Usage: " << argv[0] << " [options] input-files\n"; + cout << visible << "\n"; + return 0; + } + + if (vm.count("version")) { + cout << "AloLang compiler, pre-dev version\n"; + return 0; + } + + if (vm.count("input-file")) { + input_file_names = vm["input-file"].as>(); + + if (vm.count("alolanglib")) + alolanglibdir = vm["alolanglib"].as(); + else + output_file_name = "src/lib"; + + for (std::string input_file_name : input_file_names) { + if (vm.count("output")) + output_file_name = vm["output"].as(); + else + output_file_name = "a.out"; + fin.open(input_file_name); + if (!fin.is_open()) { + cerr << argv[0] + << ": fatal error: file not found\ncompilation " + "terminated\n"; + return 1; + } + std::string buff; //源码 + std::getline(fin, buff, char(EOF)); + std::string preProcessed; + fin.close(); + // std::string header = "%import types\n"; + // buff = header + buff; + try { + preProcessed = preProcess(buff, 0); + // cout << preProcessed; + // todo:这行代码写的极不规范,尽快修改 + CompileUnit(input_file_name, preProcessed).compile(); + system(("llc ./" + input_file_name + + ".bc --relocation-model=pic") + .c_str()); + system(("llvm-dis ./" + input_file_name + ".bc").c_str()); + + } catch (const CompileError &e) { + cerr << "Compile Error: " << e.what() << endl + << "Compilation Terminated\n"; + return 1; + } + } + //下面代码仅用来方便调试 + std::string objs = " "; + for (std::string input_file_name : input_file_names) { + objs += "./" + input_file_name + ".s "; + } + std::string cmdline = "gcc -O0" + objs + + (vm.count("static") ? "-static " : "") + + " -fPIE -L " + alolanglibdir + + " -l alolangcore" + " -o " + output_file_name; + std::cout << "debug info:" << cmdline << std::endl; + system(cmdline.c_str()); + return 0; + } else { + cout << "Usage: " << argv[0] << " [options] input-files\n"; + cout << visible << "\n"; + return 1; + } + } catch (std::exception &e) { + cout << "Exception: " << e.what() << endl; + return 1; + } +} diff --git a/src/ast/AllAST.h b/src/ast/AllAST.h new file mode 100644 index 0000000000000000000000000000000000000000..c49921dc079db84abcb896723177ff181784ec9c --- /dev/null +++ b/src/ast/AllAST.h @@ -0,0 +1,24 @@ +/* + * AllAST.h + * + * Created on: Feb 14, 2021 + * Author: tomdang + * + * Wrapper header for all AST headers + */ + +#ifndef _ALLAST_H_ +#define _ALLAST_H_ + +#include "BaseAST.h" +#include "BinaryExprAST.h" +#include "CallExprAST.h" +#include "CodeBlockAST.h" +#include "ExprAST.h" +#include "ExternAST.h" +#include "FunctionAST.h" +#include "IntExprAST.h" +#include "PrototypeAST.h" +#include "VariableExprAST.h" + +#endif diff --git a/src/ast/AssignmentAST.cpp b/src/ast/AssignmentAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bb278eee57679793c610fa70521c2a8488a1084e --- /dev/null +++ b/src/ast/AssignmentAST.cpp @@ -0,0 +1,52 @@ +/* + * AssignmentAST.cpp + * + * Created on: Feb 17, 2021 + * Author: zbc + */ + +#include "AssignmentAST.h" +#include "../CompileError.hpp" +#include "CodeBlockAST.h" +#include "VariableExprAST.h" + +AssignmentAST::AssignmentAST(CompileUnit *unit, VariableExprAST *LHS, + ExprAST *RHS) + : ExprAST(unit) +{ + this->LHS = LHS; + this->RHS = RHS; +} + +AssignmentAST::~AssignmentAST() +{ + // TODO Auto-generated destructor stub +} + +AssignmentAST *AssignmentAST::ParseAssignment(CompileUnit * unit, + CodeBlockAST * codeblock, + const std::string &LHS) +{ + + unit->next_tok(); + CodeBlockAST *curCodeBlock = codeblock; + while (curCodeBlock != nullptr) { + auto varAST = curCodeBlock->namedValues.find(LHS); + if (varAST == curCodeBlock->namedValues.end()) { + curCodeBlock = curCodeBlock->parent; + } else { + return new AssignmentAST( + unit, varAST->second, + ExprAST::ParseExpression(unit, codeblock, false)); + } + } + CompileError e("can't find variable:" + LHS); + throw e; +} + +llvm::Value *AssignmentAST::Codegen(llvm::IRBuilder<> *builder) +{ + llvm::Value *value = RHS->Codegen(builder); + builder->CreateStore(value, LHS->alloca); // todo:对函数参数赋值 + return value; +} diff --git a/src/ast/AssignmentAST.h b/src/ast/AssignmentAST.h new file mode 100644 index 0000000000000000000000000000000000000000..b4aac759ce9b352090d3e9dc99667fcd892021b9 --- /dev/null +++ b/src/ast/AssignmentAST.h @@ -0,0 +1,27 @@ +/* + * AssignmentAST.h + * + * Created on: Feb 17, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_ASSIGNMENTAST_H_ +#define SRC_AST_ASSIGNMENTAST_H_ + +#include "ExprAST.h" + +class VariableExprAST; +class AssignmentAST : public ExprAST +{ + public: + AssignmentAST(CompileUnit *unit, VariableExprAST *LHS, ExprAST *RHS); + virtual ~AssignmentAST(); + llvm::Value * Codegen(llvm::IRBuilder<> *builder); + static AssignmentAST *ParseAssignment(CompileUnit * unit, + CodeBlockAST * codeblock, + const std::string &LHS); + VariableExprAST * LHS; //左侧变量 + ExprAST * RHS; +}; + +#endif /* SRC_AST_ASSIGNMENTAST_H_ */ diff --git a/compiler/ast/BaseAST.cpp b/src/ast/BaseAST.cpp similarity index 43% rename from compiler/ast/BaseAST.cpp rename to src/ast/BaseAST.cpp index 80eeb4bf9677293d251ccb682a6aa2e3c33b72ae..29d17d0f08f15d0ee0384a684e6b711ff1398782 100644 --- a/compiler/ast/BaseAST.cpp +++ b/src/ast/BaseAST.cpp @@ -7,12 +7,9 @@ #include "BaseAST.h" -BaseAST::BaseAST() { - // TODO Auto-generated constructor stub +BaseAST::BaseAST(CompileUnit *unit) { this->unit = unit; } +BaseAST::~BaseAST() +{ + // TODO Auto-generated destructor stub } - -BaseAST::~BaseAST() { - // TODO Auto-generated destructor stub -} - diff --git a/compiler/ast/BaseAST.h b/src/ast/BaseAST.h similarity index 40% rename from compiler/ast/BaseAST.h rename to src/ast/BaseAST.h index 1f267f3e3fbc6d79619b95bbef759af3716b216f..a4d27249a8007e96819d0d0e4270d1ad41f9dd79 100644 --- a/compiler/ast/BaseAST.h +++ b/src/ast/BaseAST.h @@ -1,16 +1,20 @@ #ifndef COMPILER_AST_ASTBASE_H_ #define COMPILER_AST_ASTBASE_H_ -#include +#include "./../CompileUnit.h" +#include "./../Token.h" #include +#include +#include +#include +#include -int next_tok(); - -class BaseAST { -public: - BaseAST(); - virtual ~BaseAST(); - virtual llvm::Value *Codegen() = 0; +class BaseAST +{ + public: + BaseAST(CompileUnit *unit); + virtual ~BaseAST(); + CompileUnit *unit; }; #endif /* COMPILER_AST_ASTBASE_H_ */ diff --git a/src/ast/BinaryExprAST.cpp b/src/ast/BinaryExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b68634594180ae16aabecb0227db4fd0baaa44e1 --- /dev/null +++ b/src/ast/BinaryExprAST.cpp @@ -0,0 +1,56 @@ +/* + * BinaryExprAST.cpp + * + * Created on: Feb 12, 2021 + * Author: zbc + */ + +#include "BinaryExprAST.h" +#include "../CompileError.hpp" + +BinaryExprAST::BinaryExprAST(CompileUnit *unit, std::string binOP, ExprAST *LHS, + ExprAST *RHS) + : ExprAST(unit) +{ + this->binOP = binOP; + this->LHS = LHS; + this->RHS = RHS; + this->type = LHS->type; +} + +BinaryExprAST::~BinaryExprAST() +{ + // TODO Auto-generated destructor stub +} + +llvm::Value *BinaryExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + llvm::Value *L = LHS->Codegen(builder); + llvm::Value *R = RHS->Codegen(builder); + if (L == nullptr || R == 0) + return 0; + if (binOP == "+") { + return builder->CreateAdd(L, R); + } else if (binOP == "-") { + return builder->CreateSub(L, R); + } else if (binOP == "*") { + return builder->CreateMul(L, R); + } else if (binOP == "/") { + return builder->CreateFDiv(L, R); + } else if (binOP == "==") { + return builder->CreateICmpEQ(L, R); + } else if (binOP == "!=") { + return builder->CreateICmpNE(L, R); + } else if (binOP == ">") { + return builder->CreateICmpSGT(L, R); + } else if (binOP == "<") { + return builder->CreateICmpSLT(L, R); + } else if (binOP == ">=") { + return builder->CreateICmpSGE(L, R); + } else if (binOP == "<=") { + return builder->CreateICmpSLE(L, R); + } else { + CompileError e("Unknown operator:" + binOP); + throw e; + } +} diff --git a/src/ast/BinaryExprAST.h b/src/ast/BinaryExprAST.h new file mode 100644 index 0000000000000000000000000000000000000000..7f6113d8f3ab35c06d38a3a612b9fa099616690a --- /dev/null +++ b/src/ast/BinaryExprAST.h @@ -0,0 +1,26 @@ +/* + * BinaryExprAST.h + * + * Created on: Feb 12, 2021 + * Author: zbc + */ + +#ifndef COMPILER_AST_BINARYEXPRAST_H_ +#define COMPILER_AST_BINARYEXPRAST_H_ + +#include "ExprAST.h" + +class BinaryExprAST : public ExprAST +{ + public: + BinaryExprAST(CompileUnit *unit, std::string binOP, ExprAST *LHS, + ExprAST *RHS); + virtual ~BinaryExprAST(); + llvm::Value *Codegen(llvm::IRBuilder<> *builder); + + std::string binOP; + ExprAST * LHS; + ExprAST * RHS; +}; + +#endif /* COMPILER_AST_BINARYEXPRAST_H_ */ diff --git a/src/ast/BoolExprAST.cpp b/src/ast/BoolExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e0037e51844ec785f70fad240e0fbabd779c4e08 --- /dev/null +++ b/src/ast/BoolExprAST.cpp @@ -0,0 +1,26 @@ +/* + * BoolExprAST.cpp + * + * Created on: Feb 17, 2021 + * Author: zbc + */ + +#include "BoolExprAST.h" + +BoolExprAST::BoolExprAST(CompileUnit *unit, bool val) : ExprAST(unit) +{ + this->val = val; + type = "bool"; +} + +BoolExprAST::~BoolExprAST() +{ + // TODO Auto-generated destructor stub +} + +llvm::Value *BoolExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + llvm::IntegerType *type = llvm::IntegerType::get(*unit->context, 1); + llvm::ConstantInt *res = llvm::ConstantInt::get(type, val, true); + return res; +} diff --git a/src/ast/BoolExprAST.h b/src/ast/BoolExprAST.h new file mode 100644 index 0000000000000000000000000000000000000000..09ee1a22d79b22df5b43cf1402ac046015232aeb --- /dev/null +++ b/src/ast/BoolExprAST.h @@ -0,0 +1,22 @@ +/* + * BoolExprAST.h + * + * Created on: Feb 17, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_BOOLEXPRAST_H_ +#define SRC_AST_BOOLEXPRAST_H_ + +#include "ExprAST.h" + +class BoolExprAST : public ExprAST +{ + public: + BoolExprAST(CompileUnit *unit, bool val); + virtual ~BoolExprAST(); + llvm::Value *Codegen(llvm::IRBuilder<> *builder); + bool val; +}; + +#endif /* SRC_AST_BOOLEXPRAST_H_ */ diff --git a/src/ast/CallExprAST.cpp b/src/ast/CallExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c82dc4da3d433749b6be9e8e3b5c26d40b52f4e0 --- /dev/null +++ b/src/ast/CallExprAST.cpp @@ -0,0 +1,57 @@ +/* + * CallExprAST.cpp + * + * Created on: Dec 24, 2020 + * Author: zbc + */ + +#include "CallExprAST.h" +#include "../CompileError.hpp" + +#include + +#include "../utils.h" + +CallExprAST::CallExprAST(CompileUnit *unit, const std::string &callee, + std::vector &args) + : ExprAST(unit) +{ + std::vector argStr; + for (ExprAST *ast : args) { + argStr.push_back(ast->type); + } + if (callee != "main") { + this->callee = demangle(callee, argStr); + } + + this->args = args; + std::cout << std::left << std::setw(35) + << "Function call found:" << this->callee << std::endl; +} + +CallExprAST::~CallExprAST() +{ + // TODO Auto-generated destructor stub +} + +llvm::Value *CallExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + llvm::Function *CalleeF = unit->module->getFunction(callee); + if (CalleeF == 0) { + CompileError e("Function " + callee + " not found"); + throw e; + } + std::vector argsV; + + // If argument mismatch error. + if (CalleeF->arg_size() != args.size()) { + CompileError e("Incorrect arguments passed"); + throw e; + } + + for (unsigned i = 0, e = args.size(); i != e; ++i) { + argsV.push_back(args[i]->Codegen(builder)); + } + + return builder->CreateCall(CalleeF, argsV); +} diff --git a/src/ast/CallExprAST.h b/src/ast/CallExprAST.h new file mode 100644 index 0000000000000000000000000000000000000000..3cfdd5b140923a07681e173d8d42d55c1438097e --- /dev/null +++ b/src/ast/CallExprAST.h @@ -0,0 +1,25 @@ +/* + * CallExprAST.h + * + * Created on: Dec 24, 2020 + * Author: zbc + */ + +#ifndef COMPILER_AST_CALLEXPRAST_H_ +#define COMPILER_AST_CALLEXPRAST_H_ + +#include "ExprAST.h" + +class CallExprAST : public ExprAST +{ + public: + CallExprAST(CompileUnit *unit, const std::string &callee, + std::vector &args); + virtual ~CallExprAST(); + llvm::Value *Codegen(llvm::IRBuilder<> *builder); + + std::string callee; + std::vector args; +}; + +#endif /* COMPILER_AST_CALLEXPRAST_H_ */ diff --git a/src/ast/CodeBlockAST.cpp b/src/ast/CodeBlockAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..44374a4f6f999658629faf32fa5222aeced26b80 --- /dev/null +++ b/src/ast/CodeBlockAST.cpp @@ -0,0 +1,68 @@ +/* + * CodeBlockAST.cpp + * + * Created on: Dec 27, 2020 + * Author: zbc + */ + +#include "CodeBlockAST.h" +#include "../CompileError.hpp" +#include + +CodeBlockAST::CodeBlockAST(CompileUnit *unit, std::vector body, + std::string name, CodeBlockAST *parent) + : BaseAST(unit) +{ + this->builder = new llvm::IRBuilder<>(*unit->context); + this->body = body; + this->name = name; + this->parent = parent; + this->endBB = nullptr; +} + +CodeBlockAST::~CodeBlockAST() +{ + // TODO Auto-generated destructor stub +} + +CodeBlockAST *CodeBlockAST::ParseCodeBlock( + CompileUnit *unit, std::string name, CodeBlockAST *parent, + std::map namedValues) +{ + CodeBlockAST *codeblock = + new CodeBlockAST(unit, std::vector(), name, parent); + codeblock->namedValues = namedValues; + std::vector &body = codeblock->body; + + while (true) { + Token inBlockToken = *(unit->icurTok + 1); + if (inBlockToken.type == tok_eof) { + CompileError e("Unexpexted EOF in function body"); + throw e; + } + if (inBlockToken.type == tok_syntax && inBlockToken.tokenValue == "}") { + unit->next_tok(); + break; + } + body.push_back(ExprAST::ParseExpression(unit, codeblock, true)); + } + return codeblock; +} + +llvm::BasicBlock *CodeBlockAST::Codegen(llvm::Function *function) +{ + llvm::BasicBlock *bb = + llvm::BasicBlock::Create(*unit->context, name, function); + endBB = bb; + builder->SetInsertPoint(bb); + + for (ExprAST *expr : body) { + expr->Codegen(builder); + } + // builder->CreateRetVoid(); // todo:待处理 + if (parent == nullptr) { + builder->CreateRetVoid(); + } + + return bb; +} diff --git a/src/ast/CodeBlockAST.h b/src/ast/CodeBlockAST.h new file mode 100644 index 0000000000000000000000000000000000000000..0d976ef77d6ea8dbd5661fd12dd262903988194d --- /dev/null +++ b/src/ast/CodeBlockAST.h @@ -0,0 +1,38 @@ +/* + * CodeBlockAST.h + * + * Created on: Dec 27, 2020 + * Author: zbc + */ + +#ifndef COMPILER_AST_CODEBLOCKAST_H_ +#define COMPILER_AST_CODEBLOCKAST_H_ + +#include "BaseAST.h" +#include "ExprAST.h" +#include "llvm/IR/Instructions.h" +#include + +class VariableExprAST; +class CodeBlockAST : public BaseAST +{ + public: + CodeBlockAST(CompileUnit *unit, std::vector exprs, + std::string name, CodeBlockAST *parent = nullptr); + virtual ~CodeBlockAST(); + static CodeBlockAST * + ParseCodeBlock(CompileUnit *unit, std::string name, + CodeBlockAST * parent = nullptr, + std::map namedValues = + std::map()); + llvm::BasicBlock *Codegen(llvm::Function *function); + + llvm::IRBuilder<> * builder; + std::vector body; + std::map namedValues; + std::string name; + CodeBlockAST * parent; + llvm::BasicBlock * endBB; +}; + +#endif /* COMPILER_AST_CODEBLOCKAST_H_ */ diff --git a/src/ast/ExprAST.cpp b/src/ast/ExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c9e0524c2dd70d8ec0d78e6e9ffc82a8e733a189 --- /dev/null +++ b/src/ast/ExprAST.cpp @@ -0,0 +1,189 @@ +#include "ExprAST.h" +#include "../CompileError.hpp" +#include "../utils.h" +#include "AssignmentAST.h" +#include "BinaryExprAST.h" +#include "BoolExprAST.h" +#include "CallExprAST.h" +#include "CodeBlockAST.h" +#include "IfExprAST.h" +#include "IntExprAST.h" +#include "VariableExprAST.h" +#include + +int GetTokPrecedence(Token tok) +{ + if (tok.type != tok_syntax) { + return -1; + } + std::map BinopPrecedence; + BinopPrecedence["=="] = 100; + BinopPrecedence[">"] = 100; + BinopPrecedence["<"] = 100; + BinopPrecedence[">="] = 100; + BinopPrecedence["<="] = 100; + BinopPrecedence["+"] = 200; + BinopPrecedence["-"] = 200; + BinopPrecedence["*"] = 300; + BinopPrecedence["/"] = 300; + + int TokPrec = BinopPrecedence[tok.tokenValue]; + if (TokPrec <= 0) { + return -1; + } + return TokPrec; +} + +ExprAST::ExprAST(CompileUnit *unit) : BaseAST(unit) +{ + // TODO Auto-generated constructor stub +} + +ExprAST::~ExprAST() +{ + // TODO Auto-generated destructor stub +} + +ExprAST *ExprAST::ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock) +{ + // todo:除了函数调用之外的语句解析 + Token token = unit->next_tok(); + switch (token.type) { + case tok_number: { + return new IntExprAST(unit, strtol(token.tokenValue.c_str(), NULL, 10)); + } + case tok_key_literal: { + if (token.tokenValue == "true") { + return new BoolExprAST(unit, true); + } else { + return new BoolExprAST(unit, false); + } + break; + } + case tok_key_if: { + return IfExprAST::ParseIfExpr(unit, codeblock); + } + case tok_syntax: { + if (token.tokenValue == "(") { + ExprAST *result = ParseExpression(unit, codeblock, false); + token = unit->next_tok(); + if (token.type != tok_syntax || token.tokenValue != ")") { + CompileError e("missing ')'"); + throw e; + } + return result; + } else { + std::cerr << "error3:" << token.dump() << std::endl; + } + break; + } + case tok_identifier: { + //函数调用或定义 + std::string idName = token.tokenValue; + token = *(unit->icurTok + 1); + if (token.type == tok_identifier) { + //定义 + std::string valName = token.tokenValue; + unit->next_tok(); + VariableExprAST *varAST = + VariableExprAST::ParseVar(unit, codeblock, valName, idName); + codeblock->namedValues.insert( + std::pair(valName, varAST)); + return varAST; + } else if (token.tokenValue == "=") { + //赋值 + return AssignmentAST::ParseAssignment(unit, codeblock, idName); + } else if (token.tokenValue == "(") { + //函数调用 + unit->next_tok(); + std::vector args; + while (true) { + Token nextToken = *(unit->icurTok + 1); + + if (nextToken.type == tok_syntax && + nextToken.tokenValue == ")") { + unit->next_tok(); + break; + } + if (nextToken.type == tok_syntax && + nextToken.tokenValue == ",") { + unit->next_tok(); + continue; + } + + ExprAST *arg = ExprAST::ParseExpression(unit, codeblock, false); + args.push_back(arg); + // todo:异常处理 + } + + return new CallExprAST(unit, idName, args); + } else { + //变量 + CodeBlockAST *curCodeBlock = codeblock; + while (curCodeBlock != nullptr) { + auto varAST = curCodeBlock->namedValues.find(idName); + if (varAST == curCodeBlock->namedValues.end()) { + curCodeBlock = curCodeBlock->parent; + } else { + return varAST->second; + } + } + CompileError e("can't find variable:" + idName); + throw e; + } + break; + } + default: { + CompileError e("不期待的token:" + token.dump()); + throw e; + } + } + return nullptr; +} + +static ExprAST *ParseBinOpRHS(CompileUnit *unit, CodeBlockAST *codeblock, + int ExprPrec, ExprAST *LHS) +{ + while (1) { + Token token = *(unit->icurTok + 1); + int TokPrec = GetTokPrecedence(token); + if (TokPrec < ExprPrec) { + return LHS; + } + unit->next_tok(); + + ExprAST *RHS = ExprAST::ParsePrimary(unit, codeblock); + if (!RHS) + return nullptr; + + int NextPrec = GetTokPrecedence(*(unit->icurTok + 1)); + if (TokPrec < NextPrec) { + RHS = ParseBinOpRHS(unit, codeblock, TokPrec + 1, RHS); + if (RHS == nullptr) { + return nullptr; + } + } + LHS = new BinaryExprAST(unit, token.tokenValue, LHS, RHS); + } +} + +ExprAST *ExprAST::ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, + bool root) +{ + ExprAST *LHS = ParsePrimary(unit, codeblock); + if (LHS == nullptr) { + return nullptr; + } + ExprAST *result = ParseBinOpRHS(unit, codeblock, 0, LHS); + if (IfExprAST *v = dynamic_cast(result)) { + return result; //跳过分号 + } + if (root) { + Token token = unit->next_tok(); + if (token.type != tok_syntax || token.tokenValue != ";") { + CompileError e("丟失分号: \"" + token.dump() + "\" 前"); + throw e; + } + } + return result; +} diff --git a/src/ast/ExprAST.h b/src/ast/ExprAST.h new file mode 100644 index 0000000000000000000000000000000000000000..3bf5b6d0ee537e4ad75369aab9060415c5e435f1 --- /dev/null +++ b/src/ast/ExprAST.h @@ -0,0 +1,19 @@ +#ifndef COMPILER_AST_ASTEXPR_H_ +#define COMPILER_AST_ASTEXPR_H_ + +#include "BaseAST.h" + +class CodeBlockAST; +class ExprAST : public BaseAST +{ + public: + ExprAST(CompileUnit *unit); + virtual ~ExprAST(); + virtual llvm::Value *Codegen(llvm::IRBuilder<> *builder) = 0; + static ExprAST *ParseExpression(CompileUnit *unit, CodeBlockAST *codeblock, + bool root); + static ExprAST *ParsePrimary(CompileUnit *unit, CodeBlockAST *codeblock); + std::string type; +}; + +#endif /* COMPILER_AST_ASTEXPR_H_ */ diff --git a/src/ast/ExternAST.cpp b/src/ast/ExternAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..63823fd20e5e68bff54493ca8015cb19860e208f --- /dev/null +++ b/src/ast/ExternAST.cpp @@ -0,0 +1,33 @@ +/* + * ExternAST.cpp + * + * Created on: Dec 23, 2020 + * Author: zbc + */ + +#include "ExternAST.h" +#include "../CompileError.hpp" +#include + +ExternAST::ExternAST(CompileUnit *unit, PrototypeAST *proto) : BaseAST(unit) +{ + this->proto = proto; +} + +ExternAST::~ExternAST() +{ + // TODO Auto-generated destructor stub +} + +ExternAST *ExternAST::ParseExtern(CompileUnit *unit) +{ + PrototypeAST *proto = PrototypeAST::ParsePrototype(unit, false); + std::cout << std::left << std::setw(35) << "Function extern found:" << proto->name << std::endl; + return new ExternAST(unit, proto); +} + +llvm::Function *ExternAST::Codegen() +{ + proto->Codegen(); + return 0; +} diff --git a/src/ast/ExternAST.h b/src/ast/ExternAST.h new file mode 100644 index 0000000000000000000000000000000000000000..aa47819c6c3a7c31b3dd38208dcf10dcd4d4e2a3 --- /dev/null +++ b/src/ast/ExternAST.h @@ -0,0 +1,24 @@ +/* + * ExternAST.h + * + * Created on: Dec 23, 2020 + * Author: zbc + */ + +#ifndef COMPILER_AST_EXTERNAST_H_ +#define COMPILER_AST_EXTERNAST_H_ + +#include "BaseAST.h" +#include "PrototypeAST.h" + +class ExternAST : public BaseAST +{ + public: + ExternAST(CompileUnit *unit, PrototypeAST *prototype); + virtual ~ExternAST(); + static ExternAST *ParseExtern(CompileUnit *unit); + llvm::Function * Codegen(); + PrototypeAST * proto; +}; + +#endif /* COMPILER_AST_EXTERNAST_H_ */ diff --git a/src/ast/FunctionAST.cpp b/src/ast/FunctionAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..932dabf52029a25b95df420aea5f9de36ae945e2 --- /dev/null +++ b/src/ast/FunctionAST.cpp @@ -0,0 +1,54 @@ +/* + * FunctionAST.cpp + * + * Created on: Aug 28, 2020 + * Author: zbc + */ + +#include "FunctionAST.h" +#include "../CompileError.hpp" +#include "CodeBlockAST.h" +#include "PrototypeAST.h" +#include "VariableExprAST.h" +#include +#include +#include + +FunctionAST::FunctionAST(CompileUnit *unit, PrototypeAST *proto, + CodeBlockAST *body) + : BaseAST(unit) +{ + this->proto = proto; + this->body = body; +} + +FunctionAST::~FunctionAST() +{ + // TODO Auto-generated destructor stub +} + +llvm::Function *FunctionAST::Codegen() +{ + llvm::Function * func = proto->Codegen(); + llvm::BasicBlock *bb = body->Codegen(func); + // func->getBasicBlockList().push_back(bb); + + return func; +} + +FunctionAST *FunctionAST::ParseFunction(CompileUnit *unit) +{ + PrototypeAST *protoType = PrototypeAST::ParsePrototype(unit, true); + std::cout << std::left << std::setw(35) + << "Function definition found:" << protoType->name << std::endl; + std::map namedValues; + for (unsigned int i = 0; i < protoType->args.size(); i++) { + std::pair arg = protoType->args[i]; + namedValues.insert(std::pair( + arg.second, + new VariableExprAST(unit, arg.second, arg.first, nullptr, i))); + } + CodeBlockAST *body = + CodeBlockAST::ParseCodeBlock(unit, "entry", nullptr, namedValues); + return new FunctionAST(unit, protoType, body); +} diff --git a/compiler/ast/FunctionAST.h b/src/ast/FunctionAST.h similarity index 35% rename from compiler/ast/FunctionAST.h rename to src/ast/FunctionAST.h index 35a86db77c69d35481ba7ec4f5f1b87dedd9bf35..7e68aafd9ef48e38d703ed5fae9bd05260d10b59 100644 --- a/compiler/ast/FunctionAST.h +++ b/src/ast/FunctionAST.h @@ -9,13 +9,21 @@ #define COMPILER_AST_FUNCTIONAST_H_ #include "BaseAST.h" +#include "CodeBlockAST.h" +#include "ExprAST.h" +#include "PrototypeAST.h" +#include -class FunctionAST: public BaseAST { -public: - FunctionAST(); - virtual ~FunctionAST(); - llvm::Function *Codegen(); - static FunctionAST* ParseDefinition(); +class FunctionAST : public BaseAST +{ + public: + FunctionAST(CompileUnit *unit, PrototypeAST *proto, CodeBlockAST *body); + virtual ~FunctionAST(); + llvm::Function *Codegen(); + PrototypeAST * proto; + + CodeBlockAST * body; + static FunctionAST *ParseFunction(CompileUnit *unit); }; #endif /* COMPILER_AST_FUNCTIONAST_H_ */ diff --git a/src/ast/IfExprAST.cpp b/src/ast/IfExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f3199563aa7f5709218e4a7324e30d47929fa7f9 --- /dev/null +++ b/src/ast/IfExprAST.cpp @@ -0,0 +1,62 @@ +/* + * IfExprAST.cpp + * + * Created on: Feb 17, 2021 + * Author: zbc + */ + +#include "IfExprAST.h" +#include "../CompileError.hpp" +#include "CodeBlockAST.h" + +IfExprAST::IfExprAST(CompileUnit *unit, CodeBlockAST *parent, + ExprAST *condition, CodeBlockAST *thenBlock, + CodeBlockAST *elseBlock) + : ExprAST(unit) +{ + this->parent = parent; + this->thenBlock = thenBlock; + this->elseBlock = elseBlock; + this->condition = condition; +} + +IfExprAST::~IfExprAST() +{ + // TODO Auto-generated destructor stub +} + +IfExprAST *IfExprAST::ParseIfExpr(CompileUnit *unit, CodeBlockAST *parent) +{ + ExprAST *condition = ExprAST::ParseExpression(unit, parent, false); + unit->next_tok(); + CodeBlockAST *thenBlock = CodeBlockAST::ParseCodeBlock(unit, "", parent); + CodeBlockAST *elseBlock = nullptr; + + if ((unit->icurTok + 1)->type == tok_key_else) { + unit->next_tok(); + unit->next_tok(); + elseBlock = CodeBlockAST::ParseCodeBlock(unit, "", parent); + } + return new IfExprAST(unit, parent, condition, thenBlock, elseBlock); +} +llvm::Value *IfExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + llvm::Function * function = builder->GetInsertBlock()->getParent(); + llvm::Value * conditionValue = condition->Codegen(builder); + llvm::BasicBlock *MergeBB = + llvm::BasicBlock::Create(*unit->context, "", function); + llvm::BasicBlock *thenBB = thenBlock->Codegen(function); + if (elseBlock != nullptr) { + llvm::BasicBlock *elseBB = elseBlock->Codegen(function); + builder->CreateCondBr(condition->Codegen(builder), thenBB, elseBB); + builder->SetInsertPoint(elseBlock->endBB); + builder->CreateBr(MergeBB); + } else { + builder->CreateCondBr(conditionValue, thenBB, MergeBB); + } + builder->SetInsertPoint(thenBlock->endBB); + builder->CreateBr(MergeBB); + builder->SetInsertPoint(MergeBB); + parent->endBB = MergeBB; + return nullptr; +} diff --git a/src/ast/IfExprAST.h b/src/ast/IfExprAST.h new file mode 100644 index 0000000000000000000000000000000000000000..1919a20f9fc9979992b9d62ab75312f27a42facf --- /dev/null +++ b/src/ast/IfExprAST.h @@ -0,0 +1,28 @@ +/* + * IfExprAST.h + * + * Created on: Feb 17, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_IFEXPRAST_H_ +#define SRC_AST_IFEXPRAST_H_ + +#include "ExprAST.h" + +class CodeBlockAST; +class IfExprAST : public ExprAST +{ + public: + IfExprAST(CompileUnit *unit, CodeBlockAST *parent, ExprAST *condition, + CodeBlockAST *thenBlock, CodeBlockAST *elseBlock); + virtual ~IfExprAST(); + static IfExprAST *ParseIfExpr(CompileUnit *unit, CodeBlockAST *parent); + llvm::Value * Codegen(llvm::IRBuilder<> *builder); + ExprAST * condition; + CodeBlockAST * thenBlock; + CodeBlockAST * elseBlock; + CodeBlockAST * parent; +}; + +#endif /* SRC_AST_IFEXPRAST_H_ */ diff --git a/src/ast/IntExprAST.cpp b/src/ast/IntExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2f14ef569fc1fca81bc298634003a0048dee91d0 --- /dev/null +++ b/src/ast/IntExprAST.cpp @@ -0,0 +1,28 @@ +/* + * NumberExprAST.cpp + * + * Created on: Aug 28, 2020 + * Author: zbc + */ + +#include "IntExprAST.h" +#include +#include + +IntExprAST::IntExprAST(CompileUnit *unit, long long val) : ExprAST(unit) +{ + this->val = val; + this->type = "int"; +} + +IntExprAST::~IntExprAST() +{ + // TODO Auto-generated destructor stub +} + +llvm::Value *IntExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + llvm::IntegerType *type = llvm::IntegerType::get(*unit->context, 64); + llvm::ConstantInt *res = llvm::ConstantInt::get(type, val, true); + return res; +} diff --git a/compiler/ast/IntExprAST.h b/src/ast/IntExprAST.h similarity index 52% rename from compiler/ast/IntExprAST.h rename to src/ast/IntExprAST.h index 2cd6e3ed8f025c6c4b54095aad3f1a03abf67a0e..5f3d289230c04221481057da23f3dd87af9fb5bb 100644 --- a/compiler/ast/IntExprAST.h +++ b/src/ast/IntExprAST.h @@ -10,11 +10,14 @@ #include "ExprAST.h" -class NumberExprAST: public ExprAST { -public: - NumberExprAST(); - virtual ~NumberExprAST(); - int val; +class IntExprAST : public ExprAST +{ + public: + IntExprAST(CompileUnit *unit, long long val); + virtual ~IntExprAST(); + llvm::Value *Codegen(llvm::IRBuilder<> *builder); + + long long val; }; #endif /* COMPILER_AST_INTEXPRAST_H_ */ diff --git a/src/ast/PrototypeAST.cpp b/src/ast/PrototypeAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..44829dbc419ab138d103156caa22614efa2503ab --- /dev/null +++ b/src/ast/PrototypeAST.cpp @@ -0,0 +1,173 @@ +/* + * PrototypeAST.cpp + * + * Created on: Dec 21, 2020 + * Author: zbc + */ + +#include "PrototypeAST.h" +#include "../CompileError.hpp" +#include "../utils.h" +#include "TypeAST.h" + +#include + +PrototypeAST::PrototypeAST( + CompileUnit *unit, const std::string &name, + const std::vector> &args) + : BaseAST(unit) +{ + this->name = name; + this->args = args; +} + +PrototypeAST::~PrototypeAST() +{ + // TODO Auto-generated destructor stub +} + +PrototypeAST *PrototypeAST::ParsePrototype(CompileUnit *unit, bool hasBody) +{ + std::vector> args; + std::vector argStr; + Token token = unit->next_tok(); // identifier. + if (token.type != tok_identifier) { + std::cerr << "error1" << std::endl; + // TODO:异常处理 + } + + std::string FnName = token.tokenValue; + token = unit->next_tok(); + + if (token.type != tok_syntax || token.tokenValue != "(") { + std::cerr << "error2" << std::endl; + // TODO:异常处理 + } + + while (true) { + if (FnName == "main") { + token = unit->next_tok(); // ). + break; + } + token = unit->next_tok(); + if (token.type == tok_syntax && token.tokenValue == ",") { + continue; + } + if (token.type == tok_syntax && token.tokenValue == ")") { + break; + } + std::string type = token.tokenValue; + // todo:错误处理 + token = unit->next_tok(); + std::string name = token.tokenValue; + std::pair pair; + pair.first = type; + pair.second = name; + args.push_back(pair); + } + if (token.type != tok_syntax || token.tokenValue != ")") { + std::cout << "error3" << std::endl; + // TODO:异常处理 + } + for (std::pair pair : args) { + argStr.push_back(pair.first); + } + if (FnName != "main") { + FnName = demangle(FnName, argStr); + } + token = unit->next_tok(); // -> or ; or { + + if (token.type == tok_return_type) { + while (true) { + // todo:解析返回类型 + token = unit->next_tok(); // identifier. + if (token.type == tok_syntax) { + if (token.tokenValue == "{") { + if (!hasBody) { + CompileError e("Unexpected function body"); + throw e; + } + break; + } + if (token.tokenValue == ";") { + if (hasBody) { + CompileError e("Unexpected ;"); + throw e; + } + break; + } + } + } + } else { + if (token.tokenValue == "{") { + if (!hasBody) { + CompileError e("Unexpected function body"); + throw e; + } + } + if (token.tokenValue == ";") { + if (hasBody) { + CompileError e("Unexpected ;"); + throw e; + } + } + } + return new PrototypeAST(unit, FnName, args); +} + +llvm::Function *PrototypeAST::Codegen() +{ + // Make the function type: double(double,double) etc. + /* + llvm::FunctionType *FT = + llvm::FunctionType::get(Type::getDoubleTy(TheContext),llvm::Doubles, + false); + */ + std::vector llvmArgs; + for (int i = 0; i < args.size(); i++) { + auto typeAST = unit->types.find(args[i].first); + if (typeAST == unit->types.end()) { + CompileError e("can't find type:" + args[i].first); + throw e; + } + llvmArgs.push_back(typeAST->second->Codegen()); + } + llvm::FunctionType *FT = llvm::FunctionType::get( + llvm::Type::getVoidTy(*unit->context), llvmArgs, false); + + llvm::Function *F = llvm::Function::Create( + FT, llvm::GlobalValue::ExternalLinkage, name, unit->module); + + // If F conflicted, there was already something named 'Name'. If it has a + // body, don't allow redefinition or reextern. + // todo:重定义异常处理 + /*if (F->getName() != Name) { + // Delete the one we just made and get the existing one. + F->eraseFromParent(); + F = TheModule->getFunction(Name); + + // If F already has a body, reject this. + if (!F->empty()) { + ErrorF("redefinition of function"); + return 0; + } + + // If F took a different number of args, reject. + if (F->arg_size() != Args.size()) { + ErrorF("redefinition of function with different # args"); + return 0; + } + }*/ + // todo:参数处理 + // Set names for all arguments. + unsigned Idx = 0; + for (llvm::Function::arg_iterator AI = F->arg_begin(); Idx != args.size(); + ++AI, ++Idx) { + AI->setName(args[Idx].second); + + // Add arguments to variable symbol table. + // NamedValues[args[Idx]] = AI; + } + + return F; +} diff --git a/src/ast/PrototypeAST.h b/src/ast/PrototypeAST.h new file mode 100644 index 0000000000000000000000000000000000000000..d7a2a96c29244821d32071f0672e56a631a046d9 --- /dev/null +++ b/src/ast/PrototypeAST.h @@ -0,0 +1,25 @@ +/* + * PrototypeAST.h + * + * Created on: Dec 21, 2020 + * Author: zbc + */ + +#ifndef COMPILER_AST_PROTOTYPEAST_H_ +#define COMPILER_AST_PROTOTYPEAST_H_ + +#include "BaseAST.h" + +class PrototypeAST : public BaseAST +{ + public: + PrototypeAST(CompileUnit *unit, const std::string &name, + const std::vector> &args); + virtual ~PrototypeAST(); + llvm::Function * Codegen(); + static PrototypeAST *ParsePrototype(CompileUnit *unit, bool hasBody); + std::vector> args; + std::string name; +}; + +#endif /* COMPILER_AST_PROTOTYPEAST_H_ */ diff --git a/src/ast/TypeAST.cpp b/src/ast/TypeAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ab55cee9170a935e7a08e24106154a475b36b3b1 --- /dev/null +++ b/src/ast/TypeAST.cpp @@ -0,0 +1,37 @@ +/* + * TypeAST.cpp + * + * Created on: Feb 16, 2021 + * Author: zbc + */ + +#include "TypeAST.h" +#include "CompileUnit.h" + +TypeAST::TypeAST(CompileUnit *unit, std::string name) : BaseAST(unit) +{ + this->name = name; +} + +TypeAST::~TypeAST() +{ + // TODO Auto-generated destructor stub +} +llvm::Type *TypeAST::Codegen() +{ + //内置类型处理 + if (name == "int") { + return llvm::Type::getInt64Ty(*unit->context); + } else if (name == "bool") { + return llvm::Type::getInt1Ty(*unit->context); + } else { + //用户定义的类型 + llvm::StructType *llvm_S = + llvm::StructType::create(*unit->context, name); + std::vector members; + for (TypeAST *member : innerType) { + members.push_back(member->Codegen()); + } + return llvm_S; + } +} diff --git a/src/ast/TypeAST.h b/src/ast/TypeAST.h new file mode 100644 index 0000000000000000000000000000000000000000..111f12842c66d4a9abfa07de39c3a5c733da5390 --- /dev/null +++ b/src/ast/TypeAST.h @@ -0,0 +1,23 @@ +/* + * TypeAST.h + * + * Created on: Feb 16, 2021 + * Author: zbc + */ + +#ifndef SRC_AST_TYPEAST_H_ +#define SRC_AST_TYPEAST_H_ + +#include "BaseAST.h" + +class TypeAST : public BaseAST +{ + public: + TypeAST(CompileUnit *unit, std::string name); + virtual ~TypeAST(); + llvm::Type * Codegen(); + std::string name; + std::vector innerType; +}; + +#endif /* SRC_AST_TYPEAST_H_ */ diff --git a/src/ast/VariableExprAST.cpp b/src/ast/VariableExprAST.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c94c51174ffb3ee0e7d2fc5f0657dac54f78a631 --- /dev/null +++ b/src/ast/VariableExprAST.cpp @@ -0,0 +1,85 @@ +/* + * VariableExprAST.cpp + * + * Created on: Jan 23, 2021 + * Author: zbc + */ + +#include "VariableExprAST.h" + +#include "../CompileError.hpp" +#include "CodeBlockAST.h" +#include "IntExprAST.h" +#include "TypeAST.h" +#include + +VariableExprAST::VariableExprAST(CompileUnit *unit, const std::string &idName, + const std::string &type, ExprAST *initValue, + int argID) + : ExprAST(unit) +{ + this->idName = idName; + this->type = type; + this->alloca = nullptr; + this->initValue = initValue; + this->argID = argID; +} + +VariableExprAST::~VariableExprAST() +{ + // TODO Auto-generated destructor stub +} + +static llvm::AllocaInst *CreateEntryBlockAlloca(CompileUnit * unit, + llvm::Function * function, + const std::string &VarName, + const std::string &type) +{ + llvm::IRBuilder<> builder(&function->getEntryBlock(), + function->getEntryBlock().begin()); + auto typeAST = unit->types.find(type); + if (typeAST == unit->types.end()) { + CompileError e("can't find type:" + type); + throw e; + } + + return builder.CreateAlloca(typeAST->second->Codegen(), 0, VarName.c_str()); +} + +llvm::Value *VariableExprAST::Codegen(llvm::IRBuilder<> *builder) +{ + if (alloca == nullptr) { + llvm::BasicBlock *insertBlock = builder->GetInsertBlock(); + llvm::Function * function = insertBlock->getParent(); + alloca = CreateEntryBlockAlloca(unit, function, idName, type); + if (argID != -1) { + builder->CreateStore(function->getArg(argID), alloca); + } + if (initValue != nullptr) { + builder->CreateStore(initValue->Codegen(builder), alloca); + } + } + return builder->CreateLoad(alloca); +} + +VariableExprAST *VariableExprAST::ParseVar(CompileUnit * unit, + CodeBlockAST *codeblock, + std::string idName, std::string type) +{ + std::cout << std::left << std::setw(35) + << "Variable definition found:" << idName << " with type:" << type + << std::endl; + Token nexToken = *(unit->icurTok + 1); + ExprAST *initValue = nullptr; + + if (nexToken.type != tok_syntax || nexToken.tokenValue != ";") { + if (nexToken.type == tok_syntax && nexToken.tokenValue == "=") { + unit->next_tok(); + initValue = ExprAST::ParseExpression(unit, codeblock, false); + } else { + CompileError e("Unknown token:" + nexToken.dump()); + throw e; + } + } + return new VariableExprAST(unit, idName, type, initValue); +} diff --git a/src/ast/VariableExprAST.h b/src/ast/VariableExprAST.h new file mode 100644 index 0000000000000000000000000000000000000000..0356ad875bc3548a539757a743aa52097635dcc5 --- /dev/null +++ b/src/ast/VariableExprAST.h @@ -0,0 +1,28 @@ +/* + * VariableExprAST.h + * + * Created on: Jan 23, 2021 + * Author: zbc + */ + +#ifndef COMPILER_AST_VARIABLEEXPRAST_H_ +#define COMPILER_AST_VARIABLEEXPRAST_H_ +#include "ExprAST.h" + +class VariableExprAST : public ExprAST +{ + public: + VariableExprAST(CompileUnit *unit, const std::string &idName, + const std::string &type, ExprAST *initValue, + int argID = -1); + virtual ~VariableExprAST(); + static VariableExprAST *ParseVar(CompileUnit *unit, CodeBlockAST *codeblock, + std::string idName, std::string type); + llvm::Value * Codegen(llvm::IRBuilder<> *builder); + std::string idName; + llvm::Value * alloca; + ExprAST * initValue; + int argID; //函数的参数号,函数内变量为-1 +}; + +#endif /* COMPILER_AST_VARIABLEEXPRAST_H_ */ diff --git a/src/ast/todo b/src/ast/todo new file mode 100644 index 0000000000000000000000000000000000000000..9c6e9a80d24bbdca9320b44134efe63fd512e932 --- /dev/null +++ b/src/ast/todo @@ -0,0 +1,12 @@ +[ ] Function +[ ] Variable +[ ] Constant +[ ] Class +[ ] Array +[ ] Pointer +[ ] Exception +[ ] Control flow +[ ] Operator +- [ ] Unary +- [ ] Binocular +- [ ] Ternary \ No newline at end of file diff --git a/compiler/translate.y b/src/autoscan.log similarity index 100% rename from compiler/translate.y rename to src/autoscan.log diff --git a/src/config.log b/src/config.log new file mode 100644 index 0000000000000000000000000000000000000000..7f82c008acdc9d547bf4f1c7a281b35749448e72 --- /dev/null +++ b/src/config.log @@ -0,0 +1,159 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by AloLang Compiler configure Dev Beta, which was +generated by GNU Autoconf 2.70. Invocation command line was + + $ ./configure + +## --------- ## +## Platform. ## +## --------- ## + +hostname = Deskmini-A300 +uname -m = x86_64 +uname -r = 5.10.10-arch1-1 +uname -s = Linux +uname -v = #1 SMP PREEMPT Sat, 23 Jan 2021 23:59:48 +0000 + +/usr/bin/uname -p = unknown +/bin/uname -X = unknown + +/bin/arch = unknown +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +/usr/bin/hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /usr/local/sbin/ +PATH: /usr/local/bin/ +PATH: /usr/bin/ +PATH: /usr/lib/jvm/default/bin/ +PATH: /opt/nessus/bin/ +PATH: /opt/nessus/sbin/ +PATH: /usr/bin/site_perl/ +PATH: /usr/bin/vendor_perl/ +PATH: /usr/bin/core_perl/ +PATH: /var/lib/snapd/snap/bin/ +PATH: /home/tomdang/go/bin/ +PATH: /home/tomdang/go/bin/ + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:2735: looking for aux files: config.guess config.sub +configure:2748: trying ./ +configure:2748: trying ./../ +configure:2748: trying ./../../ +configure:2801: error: cannot find required auxiliary files: config.guess config.sub + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_env_CCC_set= +ac_cv_env_CCC_value= +ac_cv_env_CC_set= +ac_cv_env_CC_value= +ac_cv_env_CFLAGS_set= +ac_cv_env_CFLAGS_value= +ac_cv_env_CPPFLAGS_set= +ac_cv_env_CPPFLAGS_value= +ac_cv_env_CXXFLAGS_set= +ac_cv_env_CXXFLAGS_value= +ac_cv_env_CXX_set= +ac_cv_env_CXX_value= +ac_cv_env_LDFLAGS_set= +ac_cv_env_LDFLAGS_value= +ac_cv_env_LIBS_set= +ac_cv_env_LIBS_value= +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +CC='' +CFLAGS='' +CPPFLAGS='' +CXX='' +CXXFLAGS='' +DEFS='' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +EXEEXT='' +FLEX_CHECK='' +LDFLAGS='' +LIBOBJS='' +LIBS='' +LLVM_CHECK='' +LTLIBOBJS='' +OBJEXT='' +PACKAGE_BUGREPORT='https://github.com/XJTU-Youth/AloLang-Dev/issues' +PACKAGE_NAME='AloLang Compiler' +PACKAGE_STRING='AloLang Compiler Dev Beta' +PACKAGE_TARNAME='alolang-compiler' +PACKAGE_URL='' +PACKAGE_VERSION='Dev Beta' +PATH_SEPARATOR=':' +SHELL='/bin/sh' +ac_ct_CC='' +ac_ct_CXX='' +bindir='${exec_prefix}/bin' +build='' +build_alias='' +build_cpu='' +build_os='' +build_vendor='' +datadir='${datarootdir}' +datarootdir='${prefix}/share' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +dvidir='${docdir}' +exec_prefix='NONE' +host='' +host_alias='' +host_cpu='' +host_os='' +host_vendor='' +htmldir='${docdir}' +includedir='${prefix}/include' +infodir='${datarootdir}/info' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localedir='${datarootdir}/locale' +localstatedir='${prefix}/var' +mandir='${datarootdir}/man' +oldincludedir='/usr/include' +pdfdir='${docdir}' +prefix='NONE' +program_transform_name='s,x,x,' +psdir='${docdir}' +runstatedir='${localstatedir}/run' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +/* confdefs.h */ +#define PACKAGE_NAME "AloLang Compiler" +#define PACKAGE_TARNAME "alolang-compiler" +#define PACKAGE_VERSION "Dev Beta" +#define PACKAGE_STRING "AloLang Compiler Dev Beta" +#define PACKAGE_BUGREPORT "https://github.com/XJTU-Youth/AloLang-Dev/issues" +#define PACKAGE_URL "" + +configure: exit 1 diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..5b0163357e1d47acf62f7a588ca92947cb0e2cd2 --- /dev/null +++ b/src/lib/Makefile.am @@ -0,0 +1,8 @@ +AUTOMAKE_OPTIONS = foreign +lib_LIBRARIES = libalolangcore.a +libalolangcore_a_SOURCES = testPuts.c + +alolanglibdir=$(libdir) +alolanglib_PROGRAMS = libalolangcore.so +libalolangcore_so_SOURCES = testPuts.c +libalolangcore_so_LDFLAGS = -shared -fpic diff --git a/src/lib/testPuts.c b/src/lib/testPuts.c new file mode 100644 index 0000000000000000000000000000000000000000..93f61924f6a895f6a5ca7f7b0fb817028c6d4094 --- /dev/null +++ b/src/lib/testPuts.c @@ -0,0 +1,20 @@ +#include + +extern void _alolang_8testPuts(void) { puts("AloLang Test Function"); } + +extern void _alolang_12testPrintInt3int(long long a) { printf("%lld\n", a); } +extern void _alolang_13testPrintBool4bool(int a) +{ + if (a) { + printf("true\n"); + } else { + printf("false\n"); + } +} + +extern int _alolang_10testGetInt() +{ + int a; + scanf("%d", &a); + return a; +} diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0cb64e1095561e2917d330c7f25d24310fa63c01 --- /dev/null +++ b/src/preprocessor.cpp @@ -0,0 +1,216 @@ +#include "preprocessor.h" +#include "utils.h" +#include +#include +std::ifstream t_fin__; + +std::map variable; +int closeifstack = 0; +int currentifstack = 0; + +std::pair genFactor(const std::string &line) +{ + // std::pair result;//分别为指令和参数 + int len = line.length(); + if (len < 2) { + CompileError e("empty % indicator"); + throw e; + } + int i = 1; + for (; i < len; i++) { + if (line[i] == ' ') { + break; + } + } + if (i == len) { + //预编译指令没有参数 + return std::pair(line.substr(1, len - 1), ""); + } else { + //预编译指令有参数 + return std::pair( + line.substr(1, i - 1), line.substr(i + 1, len - i - 1)); + } +} + +std::string processPreInstruction(const std::string &line, int cnt) +{ + std::pair instruction = + genFactor(line); //解析后的预编译指令 + if (instruction.first == "import") { + t_fin__.open(instruction.second); + if (!t_fin__.is_open()) { + CompileError e("import file " + instruction.second + " not found"); + throw e; + } + std::string importFileContent; + std::getline(t_fin__, importFileContent, char(EOF)); + t_fin__.close(); + return preProcess(importFileContent, cnt + 1); + } else if (instruction.first == "def") { + //解析宏定义 + std::string var, data; + int len = instruction.second.length(); + if (len == 0) { + CompileError e("no second instruction"); + throw e; + } + int i = 1; + for (; i < len; i++) { + if (instruction.second[i] == ' ') { + break; + } + } + if (i == len) { + var = instruction.second.substr(0, len); + data = ""; + } else { + var = instruction.second.substr(0, i); + data = instruction.second.substr(i + 1, len - i - 1); + } + variable[var] = data; + return ""; + } else if (instruction.first == "rmdef") { + if (instruction.second.length() == 0) { + CompileError e("no second instruction"); + throw e; + } + if (!variable.erase(instruction.second)) { + CompileError e("removing macro " + instruction.second + + " that doent exist"); + throw e; + //找不到宏定义 + } + return ""; + } else if (instruction.first == "ifdef") { + if (instruction.second.length() == 0) { + CompileError e("no second instruction"); + throw e; + } + if (closeifstack > 0) { + closeifstack++; + } + if (variable.find(instruction.second) == variable.end()) { + closeifstack++; + } + currentifstack++; + return ""; + } else if (instruction.first == "ifndef") { + if (instruction.second.length() == 0) { + CompileError e("no second instruction"); + throw e; + } + if (closeifstack > 0) { + closeifstack++; + } + if (variable.find(instruction.second) != variable.end()) { + closeifstack++; + } + currentifstack++; + return ""; + } else if (instruction.first == "endif") { + if (currentifstack == 0) { + CompileError e("no second instruction"); + throw e; + } + if (closeifstack > 0) { + closeifstack--; + } + currentifstack--; + return ""; + } else { + CompileError e("Unrecognized preprocessor command"); + throw e; + } +} + +std::string findRealData(std::string &key) +{ + std::map::iterator iter = variable.find(key); + if (iter != variable.end()) { + return findRealData(iter->second); + } else { + return key; + } +} +//宏替换 +std::string doReplace(std::string &line) +{ + std::vector words; + bool flag = false; //判断栈顶元素状态 + for (long unsigned int i = 0; i < line.length(); i++) { + if (isSyntax(line[i])) { + words.push_back(std::string(1, line[i])); + flag = false; + } else { + if (!flag) { + words.push_back(std::string(1, line[i])); + flag = true; + } else { + words[words.size() - 1] += std::string(1, line[i]); + } + } + } + std::stringstream ss; + for (std::string tmp : words) { + ss << findRealData(tmp); + } + return ss.str(); +} + +//递归预处理 +std::string preProcess(const std::string &code, int cnt) +{ + if (cnt == 128) { + CompileError e("preprocessor recursion too deep"); + throw e; + } + std::istringstream buft_fin__(code); + std::stringstream preprocessoroutput; + std::string temp; + bool isCommented = false; + while (std::getline(buft_fin__, temp)) { + if (closeifstack > 0 && temp.substr(0, 6) != "%endif" && + temp.substr(0, 7) != "%ifndef" && temp.substr(0, 6) != "%ifdef") { + continue; + } + if (temp[0] == '%') { + std::string processedPreInstruction = + processPreInstruction(temp, cnt); + if (processedPreInstruction.size() > 0) + preprocessoroutput << processedPreInstruction << std::endl; + } else { + std::string replaced = doReplace(temp); + //处理块注释 + long unsigned int position = replaced.find("*/"); + if (position != replaced.npos) { + if (!isCommented) { + // TODO:错误处理 + } + replaced = replaced.substr(position + 2, + replaced.length() - position - 2); + isCommented = false; + } + if (isCommented) { + replaced = ""; + } + position = replaced.find("/*"); + if (position != replaced.npos) { + replaced = replaced.substr(0, position); + isCommented = true; + } + + //处理行注释 + position = replaced.find("//"); + if (position != replaced.npos) { + replaced = replaced.substr(0, position); + } + + int plen = replaced.length(); + if (plen > 0) { + preprocessoroutput << replaced << std::endl; + } + } + temp.erase(); + } + return preprocessoroutput.str(); +} diff --git a/compiler/preprocessor.h b/src/preprocessor.h similarity index 64% rename from compiler/preprocessor.h rename to src/preprocessor.h index b0c0df8d581b4c91b0674c2e69338f6180db9a9c..a89cba39dbf2a4a26998e8523d0211dc60472720 100644 --- a/compiler/preprocessor.h +++ b/src/preprocessor.h @@ -1,15 +1,12 @@ #ifndef _PREPROCESSOR_ #define _PREPROCESSOR_ -#include -#include -#include #include +#include +#include #include +#include +std::string preProcess(const std::string &code, int cnt); -std::string preProcess(std::string code, int cnt); - - - -#endif \ No newline at end of file +#endif diff --git a/compiler/todo.md b/src/todo.md similarity index 100% rename from compiler/todo.md rename to src/todo.md diff --git a/src/utils.cpp b/src/utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9a25a2d2d1b5d58db41fe61304ea8595b2aef6dd --- /dev/null +++ b/src/utils.cpp @@ -0,0 +1,67 @@ +/* + * utils.cpp + * + * Created on: May 2, 2020 + * Author: zbc + */ +#include "CompileError.hpp" +#include "llvm/IR/Instructions.h" +#include +#include +#include + +char syntax[] = {'!', '%', '^', '&', '*', '(', ')', '+', '=', '{', + '}', '|', '~', '[', ']', '\\', ';', '\'', ':', '"', + ',', '<', '>', '?', '.', '/', '#', ' '}; + +struct Variable { + std::string type; + llvm::AllocaInst value; +}; + +std::string demangle(const std::string & fnName, + const std::vector &argTypes) +{ + std::stringstream ss; + ss << "_alolang_"; + ss << fnName.length() << fnName; + for (std::string word : argTypes) { + ss << word.length() << word; //得到类型 + } + return ss.str(); +} + +bool isSyntax(char c) +{ + for (char tmp : syntax) { + if (c == tmp) { + return true; + } + } + return false; +} + +//从pos查找到下一个非空格字段 +void skipSpace(const std::vector &words, long unsigned int &i) +{ + while (true) { + i++; + if (i >= words.size()) { + // TODO:异常处理(未期待的结尾) + CompileError e("Unexpected EOF"); + throw e; + } + if (words[i] != " ") { + break; + } + } +} + +void skipSpace(std::istream &in) +{ + while (in.good() && isspace(in.peek())) { + // Read and discard the space character + in.ignore(); + // in.get(); + } +} diff --git a/compiler/utils.h b/src/utils.h similarity index 45% rename from compiler/utils.h rename to src/utils.h index fdb8c8abef94c1594c416d96ff293351078b6431..354081eec12f934ac26e166e165903706e40e7ed 100644 --- a/compiler/utils.h +++ b/src/utils.h @@ -9,10 +9,17 @@ #define COMPILER_UTILS_H_ #include +#include -bool isSyntax(char c); -void skipSpace(const std::vector &words, long unsigned int& i); -void skipSpace(std::istream& in); +std::string demangle(const std::string & fnName, + const std::vector &argTypes); +bool isSyntax(char c); +void skipSpace(const std::vector &words, long unsigned int &i); +void skipSpace(std::istream &in); +template inline bool instanceof (const T *) +{ + return std::is_base_of::value; +} #endif /* COMPILER_UTILS_H_ */ diff --git a/src/yacc_stuff/tokenizer.lpp b/src/yacc_stuff/tokenizer.lpp new file mode 100644 index 0000000000000000000000000000000000000000..2157e17258d2eae69b32d5f95bfc40af3a43c1f1 --- /dev/null +++ b/src/yacc_stuff/tokenizer.lpp @@ -0,0 +1,84 @@ +%{ +#include +#include +#include +int token; + +%} +%option yylineno +%option c++ + +%% +[ \t\n]+ {/*Skip spaces tabs, and line feeds*/}; + +\"(([^\"\n]|\\\"|\\\n)*[^\\])?\" token = tok_str; return token; +\"(([^\"\n]|\\\"|\\\n)*[^\\])?[^\"]\n token = tok_err; return token; + +and|or|xor|not token = tok_key_op; return token; + +true|false token = tok_key_literal; return token; + +break token = tok_key_break; return token; +continue token = tok_key_continue; return token; +do token = tok_key_do; return token; +else token = tok_key_else; return token; +for token = tok_key_for; return token; +foreach token = tok_key_foreach; return token; +goto token = tok_key_goto; return token; +if token = tok_key_if; return token; +while token = tok_key_while; return token; + +case|switch token = tok_key_switch; return token; + +-> token = tok_return_type; return token; +fun token = tok_fun; return token; +func token = tok_fun; return token; +extern token = tok_extern; return token; +return token = tok_extern; return token; +[a-zA-Z_][a-zA-Z_]* token = tok_identifier; return token; +0b[01]+ token = tok_number; return token; +0x[1-9a-fA-F][0-9a-fA-F]* token = tok_number; return token; +0B[01]+ token = tok_number; return token; +0X[1-9a-fA-F][0-9a-fA-F]* token = tok_number; return token; +0[1-7][0-7]* token = tok_number; return token; +[1-9][0-9.]* token = tok_number; return token; +0 token = tok_number; return token; + + +== token = tok_syntax; return token; +!= token = tok_syntax; return token; +\>= token = tok_syntax; return token; +\<= token = tok_syntax; return token; +! token = tok_syntax; return token; +% token = tok_syntax; return token; +\^ token = tok_syntax; return token; +& token = tok_syntax; return token; +\* token = tok_syntax; return token; +\( token = tok_syntax; return token; +\) token = tok_syntax; return token; +\+ token = tok_syntax; return token; +- token = tok_syntax; return token; += token = tok_syntax; return token; +\{ token = tok_syntax; return token; +\} token = tok_syntax; return token; +\| token = tok_syntax; return token; +~ token = tok_syntax; return token; +\[ token = tok_syntax; return token; +\] token = tok_syntax; return token; +\\ token = tok_syntax; return token; +; token = tok_syntax; return token; +' token = tok_syntax; return token; +: token = tok_syntax; return token; +\" token = tok_syntax; return token; +, token = tok_syntax; return token; +\< token = tok_syntax; return token; +\> token = tok_syntax; return token; +\? token = tok_syntax; return token; +\. token = tok_syntax; return token; +\/ token = tok_syntax; return token; +# token = tok_syntax; return token; +<> {token = tok_eof; return token;} +<*>.|\n token = tok_err; return token; +%% + +int yyFlexLexer::yywrap(){return 1;} diff --git a/syntax_highlight_plugin/vscode/alolang/.vscode/launch.json b/syntax_highlight_plugin/vscode/alolang/.vscode/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..0e191b59295d1365ccca24701bc6a35a21e250c9 --- /dev/null +++ b/syntax_highlight_plugin/vscode/alolang/.vscode/launch.json @@ -0,0 +1,17 @@ +// A launch configuration that launches the extension inside a new window +// Use IntelliSense to learn about possible attributes. +// Hover to view descriptions of existing attributes. +// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Extension", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ] + } + ] +} \ No newline at end of file diff --git a/syntax_highlight_plugin/vscode/alolang/.vscodeignore b/syntax_highlight_plugin/vscode/alolang/.vscodeignore new file mode 100644 index 0000000000000000000000000000000000000000..f369b5e55b684e5c99d8446581a52ab2d7fc0437 --- /dev/null +++ b/syntax_highlight_plugin/vscode/alolang/.vscodeignore @@ -0,0 +1,4 @@ +.vscode/** +.vscode-test/** +.gitignore +vsc-extension-quickstart.md diff --git a/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md b/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..351a4da9b45497279e23b3dfb47ba3d2dad60c37 --- /dev/null +++ b/syntax_highlight_plugin/vscode/alolang/CHANGELOG.md @@ -0,0 +1,12 @@ +# Change Log + +All notable changes to the "alolang" extension will be documented in this file. + +Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. + +## [Dev Beta 0.0.1] + +- Initial release +- Working on compiler, will integrate after compiler is stable. +- May have many bugs +- Added syntax highlighting feature \ No newline at end of file diff --git a/syntax_highlight_plugin/vscode/alolang/README.md b/syntax_highlight_plugin/vscode/alolang/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d8cad1613c03406401ccfb6e7275200dc8ae2be7 --- /dev/null +++ b/syntax_highlight_plugin/vscode/alolang/README.md @@ -0,0 +1,55 @@ +# alolang README + +VS Code Extension for AloLang language + +## AloLang + +> Make algorithm programming easy and comfortable + +* 静态编译强类型语言 +* 多语言协作方便 +* 语法简洁 + +[Git Hub](https://github.com/xjtu-youth/AloLang/) + +## Features + +Syntax highlighting for AloLang language. + +## Requirements + +Currently: None. + +Will possibly integrate with AloLang compiler in the future, which can be +installed from [Official Git Repo](https://github.com/xjtu-youth/AloLang) + +## Known Issues + +None. + +Waiting to be reported. + +## Release Notes + +### Dev Beta 0.0.3 + +- Bugfix + - Highlight for function mis behaving + +### Dev Beta 0.0.2 + +- Added support for + - Comment toggling + - Brackets definition + - Autoclosing + - Autosurrounding + - Folding + - Word pattern + - Indentation Rules + +### Dev Beta 0.0.1 + +- Initial release +- Working on compiler, will integrate after compiler is stable. +- May have many bugs +- Added syntax highlighting feature diff --git a/syntax_highlight_plugin/vscode/alolang/alolang-0.0.1.vsix b/syntax_highlight_plugin/vscode/alolang/alolang-0.0.1.vsix new file mode 100644 index 0000000000000000000000000000000000000000..09292c32029b57157aa6f6fbe86bac4077c056e3 Binary files /dev/null and b/syntax_highlight_plugin/vscode/alolang/alolang-0.0.1.vsix differ diff --git a/syntax_highlight_plugin/vscode/alolang/alolang-0.0.2.vsix b/syntax_highlight_plugin/vscode/alolang/alolang-0.0.2.vsix new file mode 100644 index 0000000000000000000000000000000000000000..b580c59d698c71069ab0750e11a36243a9af04cb Binary files /dev/null and b/syntax_highlight_plugin/vscode/alolang/alolang-0.0.2.vsix differ diff --git a/syntax_highlight_plugin/vscode/alolang/alolang-0.0.3.vsix b/syntax_highlight_plugin/vscode/alolang/alolang-0.0.3.vsix new file mode 100644 index 0000000000000000000000000000000000000000..1b91ac44d8ad06dcf1d64abc2810f44dd53f5858 Binary files /dev/null and b/syntax_highlight_plugin/vscode/alolang/alolang-0.0.3.vsix differ diff --git a/syntax_highlight_plugin/vscode/alolang/language-configuration.json b/syntax_highlight_plugin/vscode/alolang/language-configuration.json new file mode 100644 index 0000000000000000000000000000000000000000..4cd6002a4958c2fa059c2271b025924b23ae5b52 --- /dev/null +++ b/syntax_highlight_plugin/vscode/alolang/language-configuration.json @@ -0,0 +1,41 @@ +{ + "comments": { + "lineComment": "//", + "blockComment": ["/*", "*/"] + }, + "brackets": [ + ["{", "}"], + ["[", "]"], + ["(", ")"] + ], + "autoClosingPairs": [ + { "open": "{", "close": "}" }, + { "open": "[", "close": "]" }, + { "open": "(", "close": ")" }, + { "open": "'", "close": "'", "notIn": ["string", "comment"] }, + { "open": "\"", "close": "\"", "notIn": ["string"] }, + { "open": "`", "close": "`", "notIn": ["string", "comment"] }, + { "open": "/**", "close": " */", "notIn": ["string"] } + ], + "autoCloseBefore": ";:.,=}])>` \n\t", + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["'", "'"], + ["\"", "\""], + ["`", "`"] + ], + "folding": { + "markers": { + "start": "^\\s*//\\s*#?region\\b", + "end": "^\\s*//\\s*#?endregion\\b" + } + }, + "wordPattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>\\/\\?\\s]+)", + "indentationRules": { + "increaseIndentPattern": "^((?!\\/\\/).)*(\\{[^}\"'`]*|\\([^)\"'`]*|\\[[^\\]\"'`]*)$", + "decreaseIndentPattern": "^((?!.*?\\/\\*).*\\*/)?\\s*[\\}\\]].*$" + } + } + \ No newline at end of file diff --git a/syntax_highlight_plugin/vscode/alolang/package.json b/syntax_highlight_plugin/vscode/alolang/package.json new file mode 100644 index 0000000000000000000000000000000000000000..586e2c7a0a7840f994c4c7510f892194fae3dc95 --- /dev/null +++ b/syntax_highlight_plugin/vscode/alolang/package.json @@ -0,0 +1,31 @@ +{ + "name": "alolang", + "displayName": "AloLang", + "description": "Syntax Highlight for AloLang", + "version": "0.0.3", + "publisher": "AloLangDevTeam", + "license": "GPLv3", + "repository": { + "type": "git", + "url": "https://gitee.com/alolang-dev-team/AloLang-Dev.git" + }, + "engines": { + "vscode": "^1.53.0" + }, + "categories": [ + "Programming Languages" + ], + "contributes": { + "languages": [{ + "id": "alolang", + "aliases": ["AloLang", "alolang"], + "extensions": [".alo"], + "configuration": "./language-configuration.json" + }], + "grammars": [{ + "language": "alolang", + "scopeName": "source.alo", + "path": "./syntaxes/alolang.tmLanguage.json" + }] + } +} \ No newline at end of file diff --git a/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json b/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json new file mode 100644 index 0000000000000000000000000000000000000000..c6bf74977bc2153c83769158980547af6c5bc579 --- /dev/null +++ b/syntax_highlight_plugin/vscode/alolang/syntaxes/alolang.tmLanguage.json @@ -0,0 +1,293 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "AloLang", + "comment": "AloLang language, this file is inspired by the Go language", + "fileTypes": [ + "alo" + ], + "foldingStartMarker": "({|\\()\\s*$", + "foldingStopMarker": "(}|\\))\\s*$", + "patterns": [ + { + "comment": "Block comments", + "begin": "/\\*", + "end": "\\*/", + "captures": { + "0": { + "name": "punctuation.definition.comment.alolang" + } + }, + "name": "comment.block.alolang" + }, + { + "comment": "Line comments", + "begin": "//", + "beginCaptures": { + "0": { + "name": "punctuation.definition.comment.alolang" + } + }, + "end": "$", + "name": "comment.line.double-slash.alolang" + }, + { + "comment": "Interpreted string literals", + "begin": "\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.alolang" + } + }, + "end": "\"", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.alolang" + } + }, + "name": "string.quoted.double.alolang", + "patterns": [ + { + "include": "#string_escaped_char" + }, + { + "include": "#string_placeholder" + }, + { + "include": "#line_continuation_character" + } + ] + }, + { + "comment": "Raw string literals", + "begin": "`", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.alolang" + } + }, + "end": "`", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.alolang" + } + }, + "name": "string.quoted.raw.alolang", + "patterns": [ + { + "include": "#string_placeholder" + } + ] + }, + { + "comment": "Syntax error numeric literals", + "match": "\\b0[0-7]*[89]\\d*\\b", + "name": "invalid.illegal.numeric.alolang" + }, + { + "comment": "Function declarations", + "match": "^(\\bextern\\b)?\\s*(\\bfunc\\b|\\bfun\\b)(?:\\s+([a-zA-Z_]\\w*)(?=\\())?", + "captures": { + "1": { + "name": "keyword.extern.alolang" + }, + "2": { + "name": "keyword.function.alolang" + }, + "3": { + "name": "entity.name.function" + } + } + }, + { + "comment": "Functions", + "match": "(\\bfunc\\b|\\bfun\\b)|([a-zA-Z_]\\w*)(?=\\()", + "captures": { + "1": { + "name": "keyword.function.alolang" + }, + "2": { + "name": "support.function.alolang" + } + } + }, + { + "comment": "Floating-point literals", + "match": "(\\.\\d+([Ee][-+]\\d+)?i?)\\b|\\b\\d+\\.\\d*(([Ee][-+]\\d+)?i?\\b)?", + "name": "constant.numeric.floating-point.alolang" + }, + { + "comment": "Integers", + "match": "\\b((0x[0-9a-fA-F]+)|(0[0-7]+i?)|(\\d+([Ee]\\d+)?i?)|(\\d+[Ee][-+]\\d+i?))\\b", + "name": "constant.numeric.integer.alolang" + }, + { + "comment": "Language constants", + "match": "\\b(true|false|nil|iota)\\b", + "name": "constant.language.alolang" + }, + { + "comment": "Type declarations", + "match": "(?<=class|struct)\\s+([a-zA-Z_]\\w*)", + "captures": { + "1": { + "name": "entity.name.type.alolang" + } + } + }, + { + "comment": "Terminators", + "match": ";", + "name": "punctuation.terminator.alolang" + }, + { + "include": "#keywords" + }, + { + "include": "#strings" + }, + { + "include": "#storage" + }, + { + "include": "#operators" + }, + { + "include": "#brackets" + }, + { + "include": "#delimiters" + } + ], + "repository": { + "brackets": { + "patterns": [ + { + "match": "\\{|\\}", + "name": "punctuation.other.bracket.curly.alolang" + }, + { + "match": "\\(|\\)", + "name": "punctuation.other.bracket.round.alolang" + }, + { + "match": "\\[|\\]", + "name": "punctuation.other.bracket.square.alolang" + } + ] + }, + "delimiters": { + "patterns": [ + { + "match": ",", + "name": "punctuation.other.comma.alolang" + }, + { + "match": "\\.(?!\\.\\.)", + "name": "punctuation.other.period.alolang" + }, + { + "match": ":(?!=)", + "name": "punctuation.other.colon.alolang" + } + ] + }, + "keywords": { + "patterns": [ + { + "name": "keyword.control.alolang", + "match": "\\b(break|continue|do|else|for|foreach|goto|if|while)\\b" + }, + { + "name": "keyword.const.alolang", + "match": "\\bconst\\b" + } + ] + }, + "operators": { + "comment": "Note that the order here is very important!", + "patterns": [ + { + "match": "(\\*|&)(?=\\w)", + "name": "keyword.operator.address.alolang" + }, + { + "match": "\\->", + "name": "keyword.operator.returntype.alolang" + }, + { + "match": "\\-\\-", + "name": "keyword.operator.decrement.alolang" + }, + { + "match": "\\+\\+", + "name": "keyword.operator.increment.alolang" + }, + { + "match": "(==|!=|<=|>=|<[^<]|>[^>])", + "name": "keyword.operator.comparison.alolang" + }, + { + "match": "(&&|\\|\\||!)", + "name": "keyword.operator.logical.alolang" + }, + { + "match": "(=|\\+=|\\-=|\\|=|\\^=|\\*=|/=|:=|%=|<<=|>>=|&\\^=|&=)", + "name": "keyword.operator.assignment.alolang" + }, + { + "match": "(\\+|\\-|\\*|/|%)", + "name": "keyword.operator.arithmetic.alolang" + }, + { + "match": "(&(?!\\^)|\\||\\^|&\\^|<<|>>)", + "name": "keyword.operator.arithmetic.bitwise.alolang" + } + ] + }, + "storage": { + "patterns": [ + { + "name": "storage.type.alolang", + "match": "\\b(anytype|array|auto|bool|char|double|enum|float|int|int8_t|int16_t|int32_t|long|signed|string|struct|unsigned|void)\\b" + }, + { + "name": "storage.function.alolang", + "match": "\\b(fun|func)\\b" + } + ] + }, + "string_escaped_char": { + "patterns": [ + { + "match": "\\\\([0-7]{3}|[abfnrtv\\\\'\"]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})", + "name": "constant.character.escape.alolang" + }, + { + "match": "\\\\[^0-7xuUabfnrtv\\'\"\\n]", + "name": "invalid.illegal.unknown-escape.alolang" + } + ] + }, + "string_placeholder": { + "patterns": [ + { + "match": "%(\\[\\d+\\])?([\\+#\\-0\\x20]{,2}((\\d+|\\*)?(\\.?(\\d+|\\*|(\\[\\d+\\])\\*?)?(\\[\\d+\\])?)?))?[vT%tbcdoqxXUbeEfFgGsp]", + "name": "constant.other.placeholder.alolang" + } + ] + }, + "line_continuation_character": { + "patterns": [ + { + "match": "(\\\\)\\s*\\n", + "captures": { + "1": { + "name": "constant.character.escape.line-continuation.alolang" + } + } + } + ] + } + }, + "scopeName": "source.alo" +} \ No newline at end of file diff --git a/syntax_highlight_plugin/vscode/alolang/vsc-extension-quickstart.md b/syntax_highlight_plugin/vscode/alolang/vsc-extension-quickstart.md new file mode 100644 index 0000000000000000000000000000000000000000..8408bd2f9b482b368d2559c506e0b2553a198f28 --- /dev/null +++ b/syntax_highlight_plugin/vscode/alolang/vsc-extension-quickstart.md @@ -0,0 +1,29 @@ +# Welcome to your VS Code Extension + +## What's in the folder + +* This folder contains all of the files necessary for your extension. +* `package.json` - this is the manifest file in which you declare your language support and define the location of the grammar file that has been copied into your extension. +* `syntaxes/alolang.tmLanguage.json` - this is the Text mate grammar file that is used for tokenization. +* `language-configuration.json` - this is the language configuration, defining the tokens that are used for comments and brackets. + +## Get up and running straight away + +* Make sure the language configuration settings in `language-configuration.json` are accurate. +* Press `F5` to open a new window with your extension loaded. +* Create a new file with a file name suffix matching your language. +* Verify that syntax highlighting works and that the language configuration settings are working. + +## Make changes + +* You can relaunch the extension from the debug toolbar after making changes to the files listed above. +* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. + +## Add more language features + +* To add features such as intellisense, hovers and validators check out the VS Code extenders documentation at https://code.visualstudio.com/docs + +## Install your extension + +* To start using your extension with Visual Studio Code copy it into the `/.vscode/extensions` folder and restart Code. +* To share your extension with the world, read on https://code.visualstudio.com/docs about publishing an extension. diff --git a/test.alo b/test.alo deleted file mode 100644 index 48a8f71f4b74e29cd5171dcfe00787c62471ecfc..0000000000000000000000000000000000000000 --- a/test.alo +++ /dev/null @@ -1,5 +0,0 @@ -fun main() -> int{ - int a = 123; - print(2 * a); - return 0; -} \ No newline at end of file diff --git a/test.alo.ac b/test.alo.ac deleted file mode 100644 index 342ccc5a132a75d06647c2004c1938dd3ba72eac..0000000000000000000000000000000000000000 --- a/test.alo.ac +++ /dev/null @@ -1,5 +0,0 @@ -fun main(int64_targc, char **argv) -> int{ -const int64_ta = 123; -print64_t6.2831853 * a; -return 0; -} diff --git a/test/demo.alo b/test/demo.alo new file mode 100644 index 0000000000000000000000000000000000000000..301a1a0f7431e76eb4165198acd0c161555af1e7 --- /dev/null +++ b/test/demo.alo @@ -0,0 +1,22 @@ +extern func testPuts(); +extern func testPrintInt(int i); + +func demo() +{ + testPuts(); + testPrintInt(1); + testPrintInt(0xB); + testPrintInt(0777); + testPrintInt(1+1); + testPrintInt(65535+1); + testPrintInt(0-1); + testPrintInt(32768/4); + testPrintInt((1+2)*3-10); + +// demo(); +} + +func main() +{ + demo(); +} \ No newline at end of file diff --git a/test/demo.alo.bc b/test/demo.alo.bc new file mode 100644 index 0000000000000000000000000000000000000000..ffd4e6f941f3c13189aea70f4c68225e07b58813 Binary files /dev/null and b/test/demo.alo.bc differ diff --git a/test/demo.alo.ll b/test/demo.alo.ll new file mode 100644 index 0000000000000000000000000000000000000000..d7385b51352e9a6bb003ca427dff73bfc3c08a51 --- /dev/null +++ b/test/demo.alo.ll @@ -0,0 +1,26 @@ +; ModuleID = './../test/demo.alo.bc' +source_filename = "test.ll" + +declare void @_alolang_8testPuts() + +declare void @_alolang_12testPrintInt3int(i64) + +define void @_alolang_4demo() { +entry: + call void @_alolang_8testPuts() + call void @_alolang_12testPrintInt3int(i64 1) + call void @_alolang_12testPrintInt3int(i64 11) + call void @_alolang_12testPrintInt3int(i64 511) + call void @_alolang_12testPrintInt3int(i64 2) + call void @_alolang_12testPrintInt3int(i64 65536) + call void @_alolang_12testPrintInt3int(i64 -1) + call void @_alolang_12testPrintInt3int(i64 8192) + call void @_alolang_12testPrintInt3int(i64 -1) + ret void +} + +define void @main() { +entry: + call void @_alolang_4demo() + ret void +} diff --git a/test/demo.alo.s b/test/demo.alo.s new file mode 100644 index 0000000000000000000000000000000000000000..3797bac22709d5405c4f150c7ea56d989e203239 --- /dev/null +++ b/test/demo.alo.s @@ -0,0 +1,51 @@ + .text + .file "test.ll" + .globl _alolang_4demo # -- Begin function _alolang_4demo + .p2align 4, 0x90 + .type _alolang_4demo,@function +_alolang_4demo: # @_alolang_4demo + .cfi_startproc +# %bb.0: # %entry + pushq %rax + .cfi_def_cfa_offset 16 + callq _alolang_8testPuts@PLT + movl $1, %edi + callq _alolang_12testPrintInt3int@PLT + movl $11, %edi + callq _alolang_12testPrintInt3int@PLT + movl $511, %edi # imm = 0x1FF + callq _alolang_12testPrintInt3int@PLT + movl $2, %edi + callq _alolang_12testPrintInt3int@PLT + movl $65536, %edi # imm = 0x10000 + callq _alolang_12testPrintInt3int@PLT + movq $-1, %rdi + callq _alolang_12testPrintInt3int@PLT + movl $8192, %edi # imm = 0x2000 + callq _alolang_12testPrintInt3int@PLT + movq $-1, %rdi + callq _alolang_12testPrintInt3int@PLT + popq %rax + .cfi_def_cfa_offset 8 + retq +.Lfunc_end0: + .size _alolang_4demo, .Lfunc_end0-_alolang_4demo + .cfi_endproc + # -- End function + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main + .cfi_startproc +# %bb.0: # %entry + pushq %rax + .cfi_def_cfa_offset 16 + callq _alolang_4demo@PLT + popq %rax + .cfi_def_cfa_offset 8 + retq +.Lfunc_end1: + .size main, .Lfunc_end1-main + .cfi_endproc + # -- End function + .section ".note.GNU-stack","",@progbits diff --git a/test/demoa+b.alo b/test/demoa+b.alo new file mode 100644 index 0000000000000000000000000000000000000000..c99fc1282ebb823a3d71405c2a6412757f5f468a --- /dev/null +++ b/test/demoa+b.alo @@ -0,0 +1,14 @@ +extern func testPrintInt(int i); +extern func testGetInt(); + +func main() +{ + int a = 2; + int b; + int c; + + b = 9; + + c = a + b; + testPrintInt(c); +} \ No newline at end of file diff --git a/test/demoa+b.alo.bc b/test/demoa+b.alo.bc new file mode 100644 index 0000000000000000000000000000000000000000..6c8af1b2dbe4bfa2c9c82bf5b6ac876b72dd0172 Binary files /dev/null and b/test/demoa+b.alo.bc differ diff --git a/test/demoa+b.alo.ll b/test/demoa+b.alo.ll new file mode 100644 index 0000000000000000000000000000000000000000..865e9b0fa5f874a9db10a097d963702c6e794d8b --- /dev/null +++ b/test/demoa+b.alo.ll @@ -0,0 +1,25 @@ +; ModuleID = './../test/demoa+b.alo.bc' +source_filename = "test.ll" + +declare void @_alolang_12testPrintInt3int(i64) + +declare void @_alolang_10testGetInt() + +define void @main() { +entry: + %c = alloca i64, align 8 + %b = alloca i64, align 8 + %a = alloca i64, align 8 + store i64 2, i64* %a, align 4 + %0 = load i64, i64* %a, align 4 + %1 = load i64, i64* %b, align 4 + %2 = load i64, i64* %c, align 4 + store i64 9, i64* %b, align 4 + %3 = load i64, i64* %a, align 4 + %4 = load i64, i64* %b, align 4 + %5 = add i64 %3, %4 + store i64 %5, i64* %c, align 4 + %6 = load i64, i64* %c, align 4 + call void @_alolang_12testPrintInt3int(i64 %6) + ret void +} diff --git a/test/demoa+b.alo.s b/test/demoa+b.alo.s new file mode 100644 index 0000000000000000000000000000000000000000..bd3b29f00ee02e3599c76702a20b4dde466bc0bd --- /dev/null +++ b/test/demoa+b.alo.s @@ -0,0 +1,23 @@ + .text + .file "test.ll" + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main + .cfi_startproc +# %bb.0: # %entry + subq $24, %rsp + .cfi_def_cfa_offset 32 + movq $2, (%rsp) + movq $9, 8(%rsp) + movq $11, 16(%rsp) + movl $11, %edi + callq _alolang_12testPrintInt3int@PLT + addq $24, %rsp + .cfi_def_cfa_offset 8 + retq +.Lfunc_end0: + .size main, .Lfunc_end0-main + .cfi_endproc + # -- End function + .section ".note.GNU-stack","",@progbits diff --git a/test/module b/test/module new file mode 100644 index 0000000000000000000000000000000000000000..3652e2bb98e105ca5b954fdb3381dd4958d191c8 Binary files /dev/null and b/test/module differ diff --git a/test/module.ll b/test/module.ll new file mode 100644 index 0000000000000000000000000000000000000000..8eb421453407f66cab9e392b0be421781f39050e --- /dev/null +++ b/test/module.ll @@ -0,0 +1,24 @@ +; ModuleID = './module' +source_filename = "test.ll" + +@0 = private unnamed_addr constant [17 x i8] c"just for debug!\0A\00", align 1 + +define void @testPuts() { +entry: + %0 = call i32 @puts(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @0, i32 0, i32 0)) + ret void +} + +declare i32 @puts(i8*) + +define void @demo() { +entry: + call void @testPuts() + ret void +} + +define void @main() { +entry: + call void @demo() + ret void +} diff --git a/test/module.s b/test/module.s new file mode 100644 index 0000000000000000000000000000000000000000..2ec427bf097065710cb5360116c49bc62c3c6223 --- /dev/null +++ b/test/module.s @@ -0,0 +1,58 @@ + .text + .file "test.ll" + .globl testPuts # -- Begin function testPuts + .p2align 4, 0x90 + .type testPuts,@function +testPuts: # @testPuts + .cfi_startproc +# %bb.0: # %entry + pushq %rax + .cfi_def_cfa_offset 16 + leaq .L__unnamed_1(%rip), %rdi + callq puts@PLT + popq %rax + .cfi_def_cfa_offset 8 + retq +.Lfunc_end0: + .size testPuts, .Lfunc_end0-testPuts + .cfi_endproc + # -- End function + .globl demo # -- Begin function demo + .p2align 4, 0x90 + .type demo,@function +demo: # @demo + .cfi_startproc +# %bb.0: # %entry + pushq %rax + .cfi_def_cfa_offset 16 + callq testPuts@PLT + popq %rax + .cfi_def_cfa_offset 8 + retq +.Lfunc_end1: + .size demo, .Lfunc_end1-demo + .cfi_endproc + # -- End function + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main + .cfi_startproc +# %bb.0: # %entry + pushq %rax + .cfi_def_cfa_offset 16 + callq demo@PLT + popq %rax + .cfi_def_cfa_offset 8 + retq +.Lfunc_end2: + .size main, .Lfunc_end2-main + .cfi_endproc + # -- End function + .type .L__unnamed_1,@object # @0 + .section .rodata.str1.1,"aMS",@progbits,1 +.L__unnamed_1: + .asciz "just for debug!\n" + .size .L__unnamed_1, 17 + + .section ".note.GNU-stack","",@progbits diff --git a/test/recursion.alo b/test/recursion.alo new file mode 100644 index 0000000000000000000000000000000000000000..353836e829283d1efe4d525dd425d936bc9f5c37 --- /dev/null +++ b/test/recursion.alo @@ -0,0 +1,18 @@ +//int a = 0; + +extern func testPrintInt(int i); + +func rec(int a) +{ + if (a < 10) + { + testPrintInt(a); + a = a + 1; + rec(a); + } +} + +func main() +{ + rec(0); +} \ No newline at end of file diff --git a/test/recursion.alo.bc b/test/recursion.alo.bc new file mode 100644 index 0000000000000000000000000000000000000000..28a1a316d9bdb5f60fcabcb8dbbbe50153a247e4 Binary files /dev/null and b/test/recursion.alo.bc differ diff --git a/test/recursion.alo.ll b/test/recursion.alo.ll new file mode 100644 index 0000000000000000000000000000000000000000..60cd6912318db2af2149872b2d12f75745b42e7d --- /dev/null +++ b/test/recursion.alo.ll @@ -0,0 +1,32 @@ +; ModuleID = './../test/recursion.alo.bc' +source_filename = "test.ll" + +declare void @_alolang_12testPrintInt3int(i64) + +define void @_alolang_3rec3int(i64 %a) { +entry: + %a1 = alloca i64, align 8 + store i64 %a, i64* %a1, align 4 + %0 = load i64, i64* %a1, align 4 + %1 = icmp slt i64 %0, 10 + br i1 %1, label %3, label %2 + +2: ; preds = %3, %entry + ret void + +3: ; preds = %entry + %4 = load i64, i64* %a1, align 4 + call void @_alolang_12testPrintInt3int(i64 %4) + %5 = load i64, i64* %a1, align 4 + %6 = add i64 %5, 1 + store i64 %6, i64* %a1, align 4 + %7 = load i64, i64* %a1, align 4 + call void @_alolang_3rec3int(i64 %7) + br label %2 +} + +define void @main() { +entry: + call void @_alolang_3rec3int(i64 0) + ret void +} diff --git a/test/recursion.alo.s b/test/recursion.alo.s new file mode 100644 index 0000000000000000000000000000000000000000..53fd5005d0414ae01fa0dd71f840a29880595555 --- /dev/null +++ b/test/recursion.alo.s @@ -0,0 +1,46 @@ + .text + .file "test.ll" + .globl _alolang_3rec3int # -- Begin function _alolang_3rec3int + .p2align 4, 0x90 + .type _alolang_3rec3int,@function +_alolang_3rec3int: # @_alolang_3rec3int + .cfi_startproc +# %bb.0: # %entry + pushq %rax + .cfi_def_cfa_offset 16 + movq %rdi, (%rsp) + cmpq $10, %rdi + jge .LBB0_2 +# %bb.1: + movq (%rsp), %rdi + callq _alolang_12testPrintInt3int@PLT + movq (%rsp), %rdi + incq %rdi + movq %rdi, (%rsp) + callq _alolang_3rec3int@PLT +.LBB0_2: + popq %rax + .cfi_def_cfa_offset 8 + retq +.Lfunc_end0: + .size _alolang_3rec3int, .Lfunc_end0-_alolang_3rec3int + .cfi_endproc + # -- End function + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main + .cfi_startproc +# %bb.0: # %entry + pushq %rax + .cfi_def_cfa_offset 16 + xorl %edi, %edi + callq _alolang_3rec3int@PLT + popq %rax + .cfi_def_cfa_offset 8 + retq +.Lfunc_end1: + .size main, .Lfunc_end1-main + .cfi_endproc + # -- End function + .section ".note.GNU-stack","",@progbits diff --git a/test/test01.alo b/test/test01.alo new file mode 100644 index 0000000000000000000000000000000000000000..a4588592643148091a9df75f96d2e04613e07354 --- /dev/null +++ b/test/test01.alo @@ -0,0 +1,15 @@ + +//%import test02.alo +//%def con const +//%rmdef PI +//%def PI TAO + +fun main(){ + int a = 123; + int b = 0777; + int c = 0Xabcd; + int d = 0b1001; + int zero = 0; + "something"; + +} \ No newline at end of file diff --git a/compiler/test/test02.alo b/test/test02.alo similarity index 100% rename from compiler/test/test02.alo rename to test/test02.alo diff --git a/compiler/test/test03.alo b/test/test03.alo similarity index 100% rename from compiler/test/test03.alo rename to test/test03.alo diff --git a/test/test03.alo.ac b/test/test03.alo.ac new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/compiler/test/types b/test/types similarity index 100% rename from compiler/test/types rename to test/types diff --git a/test/wrongstr.alo b/test/wrongstr.alo new file mode 100644 index 0000000000000000000000000000000000000000..ace1bc5994fde34c2257e95b2fe270a79e18b18a --- /dev/null +++ b/test/wrongstr.alo @@ -0,0 +1,7 @@ +"String"; +"Another String"; +"A Multiline\ +String" + +"Invalid +String" \ No newline at end of file diff --git a/test/wrongstr.alo.bc b/test/wrongstr.alo.bc new file mode 100644 index 0000000000000000000000000000000000000000..bd350e341430fe6471df36b079fafc8b616f428b Binary files /dev/null and b/test/wrongstr.alo.bc differ diff --git a/test/wrongstr.alo.ll b/test/wrongstr.alo.ll new file mode 100644 index 0000000000000000000000000000000000000000..5dc1094f28a4ede9f212e0f4a564590742fa608a --- /dev/null +++ b/test/wrongstr.alo.ll @@ -0,0 +1,2 @@ +; ModuleID = './../test/wrongstr.alo.bc' +source_filename = "test.ll" diff --git a/test/wrongstr.alo.s b/test/wrongstr.alo.s new file mode 100644 index 0000000000000000000000000000000000000000..b86c029ff64b539e6b42e052c4644d33a01a2a54 --- /dev/null +++ b/test/wrongstr.alo.s @@ -0,0 +1,3 @@ + .text + .file "test.ll" + .section ".note.GNU-stack","",@progbits diff --git a/test02.alo b/test02.alo deleted file mode 100644 index 58fb11ca9cdd477d7486403cd68f96eb22a277d9..0000000000000000000000000000000000000000 --- a/test02.alo +++ /dev/null @@ -1,5 +0,0 @@ -%ifndef PI -%def PI 3.1415926 -%def TAO 6.2831853 -//this is a debug message -%endif \ No newline at end of file diff --git a/tools/demangle b/tools/demangle index 80d2807006a03bb99018f1a4039882680ebb027c..7e73da6f7a34a10bedc2f780789d237db2ea0fc2 100755 Binary files a/tools/demangle and b/tools/demangle differ diff --git a/tools/demangle.cpp b/tools/demangle.cpp index 2ea7dbd455186f89d494c76f40d27e4ab5a9c07f..7120a3606168623d2023aa1acdffb07b700773bc 100644 --- a/tools/demangle.cpp +++ b/tools/demangle.cpp @@ -1,30 +1,35 @@ +#include "../src/CompileError.hpp" #include using namespace std; -char syntax[] = { '!', '%', '^', '&', '*', '(', ')', '-', '+', '=', '{', '}', - '|', '~', '[', ']', '\\', ';', '\'', ':', '"', ',', '<', '>', '?', '.', - '/', '#', ' ' }; +char syntax[] = {'!', '%', '^', '&', '*', '(', ')', '-', '+', '=', + '{', '}', '|', '~', '[', ']', '\\', ';', '\'', ':', + '"', ',', '<', '>', '?', '.', '/', '#', ' '}; -bool isSyntax(char c) { - for (char tmp : syntax) { - if (c == tmp) { - return true; - } - } - return false; +bool isSyntax(char c) +{ + for (char tmp : syntax) { + if (c == tmp) { + return true; + } + } + return false; } //从pos查找到下一个非空格字段 -void skipSpace(const std::vector &words, long unsigned int& i) { - while (true) { - i++; - if (i >= words.size()) { - //TODO:异常处理(未期待的结尾) - } - if (words[i] != " ") { - break; - } - } +void skipSpace(const std::vector &words, long unsigned int &i) +{ + while (true) { + i++; + if (i >= words.size()) { + // TODO:异常处理(未期待的结尾) + CompileError e("Unexpected EOF"); + throw e; + } + if (words[i] != " ") { + break; + } + } } /* @@ -33,56 +38,69 @@ void skipSpace(const std::vector &words, long unsigned int& i) { * 每个段前面加上长度 * 比如fun foobar(long a, int b)修饰为_alolang_6foobar4long3int */ -std::string demangle(const std::string &line) { - std::vector words; - bool flag = false; //判断栈顶元素状态,如果为false则代表栈顶元素为符号 - for (long unsigned int i = 0; i < line.length(); i++) { - if (isSyntax(line[i])) { - words.push_back(std::string(1, line[i])); - flag = false; - } else { - if (!flag) { - words.push_back(std::string(1, line[i])); - flag = true; - } else { - words[words.size() - 1] += std::string(1, line[i]); - } - } - } - std::stringstream ss; - ss << "_alolang_"; - long unsigned int i = -1; //处理指针 - skipSpace(words, i); - if (words[i] != "fun") { - //TODO:异常处理 - } - skipSpace(words, i); - ss << words[i].length() << words[i]; - skipSpace(words, i); - if (words[i] != "(") { - //TODO:异常处理 - } - skipSpace(words, i); - if (words[i] != ")") { - //有参数 - while (true) { - skipSpace(words, i); - ss << words[i].length() << words[i]; //得到类型 - skipSpace(words, i); //得到变量名,但在这个阶段没用 - skipSpace(words, i); - if (words[i] == ")") { - break; - } - if (words[i] != ",") { - //TODO:异常处理(逗号) - } - } - } - return ss.str(); +std::string demangle(const std::string &line) +{ + std::vector words; + bool flag = false; //判断栈顶元素状态,如果为false则代表栈顶元素为符号 + for (long unsigned int i = 0; i < line.length(); i++) { + if (isSyntax(line[i])) { + words.push_back(std::string(1, line[i])); + flag = false; + } else { + if (!flag) { + words.push_back(std::string(1, line[i])); + flag = true; + } else { + words[words.size() - 1] += std::string(1, line[i]); + } + } + } + std::stringstream ss; + ss << "_alolang_"; + long unsigned int i = -1; //处理指针 + skipSpace(words, i); + if (words[i] != "fun") { + // TODO:异常处理 + CompileError e("some error happened"); // todo:错误信息 + throw e; + } + skipSpace(words, i); + ss << words[i].length() << words[i]; + skipSpace(words, i); + if (words[i] != "(") { + // TODO:异常处理 + CompileError e("some error happened"); // todo:错误信息 + throw e; + } + skipSpace(words, i); + if (words[i] != ")") { + //有参数 + while (true) { + skipSpace(words, i); + ss << words[i].length() << words[i]; //得到类型 + skipSpace(words, i); //得到变量名,但在这个阶段没用 + skipSpace(words, i); + if (words[i] == ")") { + break; + } + if (words[i] != ",") { + // TODO:异常处理(逗号) + CompileError e("some error happened (comma)"); // todo:错误信息 + throw e; + } + } + } + return ss.str(); } int main(int argc, char *argv[]) { - cout << demangle(argv[1]) << endl; - return 0; -} + try { + cout << demangle(argv[1]) << endl; + return 0; + } + + catch (const std::exception &e) { + std::cerr << e.what() << '\n'; + } +} \ No newline at end of file