├── .gitignore
├── Development
├── CSharpCodegenTest
│ ├── MultipleDispatchAst
│ │ ├── App.config
│ │ ├── MultipleDispatchAst.csproj
│ │ └── Properties
│ │ │ └── AssemblyInfo.cs
│ ├── StandardLibraryAst
│ │ ├── App.config
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ └── StandardLibraryAst.csproj
│ ├── TinymoeDotNet
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ ├── TinymoeDotNet.csproj
│ │ └── TinymoeObject.cs
│ ├── UnitTestAst
│ │ ├── App.config
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ ├── UnitTestAst.csproj
│ │ └── UnitTestAst.csproj.user
│ └── YieldReturnAst
│ │ ├── App.config
│ │ ├── Properties
│ │ └── AssemblyInfo.cs
│ │ └── YieldReturnAst.csproj
├── Draft
│ ├── CounterRepeat.txt
│ ├── Repeat.txt
│ ├── TryCatch.txt
│ └── TryResume.txt
├── Library
│ └── StandardLibrary.txt
├── Source
│ ├── Ast
│ │ ├── TinymoeAst.cpp
│ │ ├── TinymoeAst.h
│ │ ├── TinymoeAst_CollectSideEffectExpressions.cpp
│ │ ├── TinymoeAst_CollectUsedVariables.cpp
│ │ ├── TinymoeAst_ExpandBlock.cpp
│ │ ├── TinymoeAst_GetRootLeftValue.cpp
│ │ ├── TinymoeAst_Print.cpp
│ │ ├── TinymoeAst_RemoveUnnecessaryVariables.cpp
│ │ ├── TinymoeAst_RoughlyOptimize.cpp
│ │ └── TinymoeAst_SetParent.cpp
│ ├── Compiler
│ │ ├── TinymoeAstCodegen.cpp
│ │ ├── TinymoeAstCodegen.h
│ │ ├── TinymoeAstCodegen_Declaration.cpp
│ │ ├── TinymoeAstCodegen_Expression.cpp
│ │ ├── TinymoeAstCodegen_Statement.cpp
│ │ ├── TinymoeDeclarationAnalyzer.cpp
│ │ ├── TinymoeDeclarationAnalyzer.h
│ │ ├── TinymoeExpressionAnalyzer.cpp
│ │ ├── TinymoeExpressionAnalyzer.h
│ │ ├── TinymoeLexicalAnalyzer.cpp
│ │ ├── TinymoeLexicalAnalyzer.h
│ │ ├── TinymoeStatementAnalyzer.cpp
│ │ └── TinymoeStatementAnalyzer.h
│ ├── Tinymoe.cpp
│ ├── Tinymoe.h
│ └── TinymoeSTL.h
├── TestCases
│ ├── Coroutine.txt
│ ├── HelloWorld.txt
│ ├── MultipleDispatch.txt
│ └── UnitTest.txt
├── Tinymoe.sln
└── TinymoeUnitTest
│ ├── CSharpCodegen.cpp
│ ├── Main.cpp
│ ├── TestAstCodegen.cpp
│ ├── TestDeclarationAnalyzer.cpp
│ ├── TestExpressionAnalyzer.cpp
│ ├── TestLexicalAnalyzer.cpp
│ ├── TestStatementAnalyzer.cpp
│ ├── TinymoeUnitTest.vcxproj
│ ├── TinymoeUnitTest.vcxproj.filters
│ ├── TinymoeUnitTest.vcxproj.user
│ ├── TinymoeUnitTest.vcxproj.vspscc
│ ├── UnitTest.cpp
│ ├── UnitTest.h
│ └── makefile
├── Docx
├── vczhcp-0.docx
├── vczhcp-1.docx
├── vczhcp-2.docx
└── vczhcp-3.docx
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | *.sdf
2 | *.suo
3 | *.opensdf
4 | **/Debug/**
5 | **/Release/**
6 | **/Bin/**
7 | *.test.txt
8 | ~$*.docx
9 | ~*.tmp
10 | *~
11 | *.o
12 | GeneratedAst.txt
13 | TinymoeProgram.cs
14 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/MultipleDispatchAst/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/MultipleDispatchAst/MultipleDispatchAst.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {F6EF18A5-F9FE-4144-8B9D-71B2E29F79F6}
8 | Exe
9 | Properties
10 | MultipleDispatchAst
11 | MultipleDispatchAst
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | {c38641b3-0b11-40be-98b2-31ef800926ac}
53 | TinymoeDotNet
54 |
55 |
56 |
57 |
64 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/MultipleDispatchAst/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("MultipleDispatchAst")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft IT")]
12 | [assembly: AssemblyProduct("MultipleDispatchAst")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft IT 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("a5292d56-1390-4475-892d-a9c979fc8641")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/StandardLibraryAst/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/StandardLibraryAst/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("StandardLibraryAst")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft IT")]
12 | [assembly: AssemblyProduct("StandardLibraryAst")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft IT 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("0345342f-5178-41c5-8af3-28464085d456")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/StandardLibraryAst/StandardLibraryAst.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {9FB5DEF7-F5BB-4C2D-9515-7C6A07C40E1E}
8 | Exe
9 | Properties
10 | StandardLibraryAst
11 | StandardLibraryAst
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | {c38641b3-0b11-40be-98b2-31ef800926ac}
53 | TinymoeDotNet
54 |
55 |
56 |
57 |
64 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/TinymoeDotNet/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("TinymoeDotNet")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft IT")]
12 | [assembly: AssemblyProduct("TinymoeDotNet")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft IT 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("858627e2-6b7f-4895-bffc-4922080126b2")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/TinymoeDotNet/TinymoeDotNet.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {C38641B3-0B11-40BE-98B2-31EF800926AC}
8 | Library
9 | Properties
10 | TinymoeDotNet
11 | TinymoeDotNet
12 | v4.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
53 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/UnitTestAst/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/UnitTestAst/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("UnitTestAst")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("UnitTestAst")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("bb8e6250-56eb-457a-9eb2-6ea31768c3f5")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/UnitTestAst/UnitTestAst.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {4601BB55-CE51-4DC7-8D0B-EABA0AC71678}
8 | Exe
9 | Properties
10 | UnitTestAst
11 | UnitTestAst
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | {c38641b3-0b11-40be-98b2-31ef800926ac}
53 | TinymoeDotNet
54 |
55 |
56 |
57 |
64 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/UnitTestAst/UnitTestAst.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ProjectFiles
5 |
6 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/YieldReturnAst/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/YieldReturnAst/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("YieldReturnAst")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft IT")]
12 | [assembly: AssemblyProduct("YieldReturnAst")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft IT 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("cd04207a-42f6-4982-8d1a-0badb1000614")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Development/CSharpCodegenTest/YieldReturnAst/YieldReturnAst.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {850F7E6F-7C55-4242-832E-F677E1224B56}
8 | Exe
9 | Properties
10 | YieldReturnAst
11 | YieldReturnAst
12 | v4.5
13 | 512
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | {c38641b3-0b11-40be-98b2-31ef800926ac}
53 | TinymoeDotNet
54 |
55 |
56 |
57 |
64 |
--------------------------------------------------------------------------------
/Development/Draft/CounterRepeat.txt:
--------------------------------------------------------------------------------
1 | cps (state)
2 | block (sentence body) repeat (count) times
3 | set counter to 0
4 | repeat while counter < count
5 | body
6 | if field flag of state <> continuing repeating
7 | if field flag of state <> exiting function
8 | set continuation state state to null
9 | end
10 | break
11 | end
12 | add 1 to counter
13 | end
14 | end
15 |
16 | ============================================
17 |
18 | function repeat_$expression_times($state, body, $continuation)
19 | {
20 | var counter = 0;
21 | repeat(
22 | $state,
23 | function ($state, $continuation_1)
24 | {
25 | body(
26 | $state,
27 | function ($state)
28 | {
29 | if_$expression(
30 | $state,
31 | function ($state, $continuation_2)
32 | {
33 | if_$expression(
34 | $state,
35 | function ($state, $continuation_3)
36 | {
37 | set_continuation_state_$expression_to $expression(
38 | $state,
39 | null,
40 | $continuation_3
41 | );
42 | },
43 | function ($state, $signal)
44 | {
45 | break(
46 | $state,
47 | $continuation_2
48 | );
49 | }
50 | );
51 | },
52 | function ($state, $signal)
53 | {
54 | counter = counter + 1;
55 | $continuation_1($state);
56 | }
57 | );
58 | }
59 | );
60 | },
61 | $continuation
62 | );
63 | }
--------------------------------------------------------------------------------
/Development/Draft/Repeat.txt:
--------------------------------------------------------------------------------
1 | cps (state)
2 | block (body) repeat : repeat statement
3 | call invoke body with (state)
4 | select field flag of state
5 | case breaking repeating
6 | reset continuation state state to null
7 | case continuing repeating
8 | reset continuation state state to null
9 | tail call invoke repeat statement with (state, body)
10 | end
11 | end
12 |
13 | ============================================
14 |
15 | function repeat($state, body, $continuation)
16 | {
17 | body(
18 | $state,
19 | function ($state)
20 | {
21 | if($state.flag == breaking_repeating)
22 | {
23 | reset_continuation_state_$expression_to_$expression(
24 | &state,
25 | null,
26 | $continuation
27 | );
28 | }
29 | else if($state.flag == continuing_repeating)
30 | {
31 | reset_continuation_state_$expression_to_$expression(
32 | &state,
33 | null,
34 | function ($state)
35 | {
36 | repeat($state, body, $continuation);
37 | }
38 | );
39 | }
40 | }
41 | );
42 | }
--------------------------------------------------------------------------------
/Development/Draft/TryCatch.txt:
--------------------------------------------------------------------------------
1 | phrase main
2 | try
3 | set a to 1
4 | set b to 0
5 | set c = a / b
6 | catch the exception
7 | print the exception
8 | end
9 | end
10 |
11 | ============================================
12 |
13 | function main($state, $continuation)
14 | {
15 | try(
16 | $state,
17 | function ($state, $continuation_1)
18 | {
19 | var a = 1;
20 | var b = 0;
21 | var c = a / b;
22 | $continuation_1($state);
23 | },
24 | function ($state, $signal)
25 | {
26 | catch_$expression(
27 | $state,
28 | $signal,
29 | function ($state, $signal, the_exception, $continuation_2)
30 | {
31 | print_$expression(
32 | $state,
33 | the_exception,
34 | $$continuation_2
35 | );
36 | },
37 | $continuation
38 | );
39 | }
40 | );
41 | }
--------------------------------------------------------------------------------
/Development/Draft/TryResume.txt:
--------------------------------------------------------------------------------
1 | block (sentence body) do
2 | try
3 | body
4 | print "Succeed!"
5 | catch the exception
6 | print the exception
7 | end
8 | end
9 |
10 | phrase main
11 | do
12 | set a to 1
13 | set b to 0
14 | set c to a / b
15 | end
16 | end
17 |
18 | ============================================
19 |
20 | function do($state, body, $continuation)
21 | {
22 | try(
23 | $state,
24 | function ($state, $continuation_1)
25 | {
26 | body(
27 | $state,
28 | function ($state)
29 | {
30 | print_$expression(
31 | $state,
32 | "Succeed!",
33 | $continuation_1
34 | );
35 | }
36 | );
37 | },
38 | function ($state, $signal)
39 | {
40 | catch_$expression(
41 | $state,
42 | $signal,
43 | function ($state, $signal, the_exception, $continuation_2)
44 | {
45 | print_$expression(
46 | $state,
47 | the_exception,
48 | $continuation_2
49 | );
50 | },
51 | $continuation
52 | );
53 | }
54 | );
55 | }
56 |
57 | function main($state, $continuation)
58 | {
59 | do(
60 | $state,
61 | function ($state)
62 | {
63 | var a = 1;
64 | var b = 0;
65 | var c = a / b;
66 | },
67 | $continuation
68 | );
69 | }
--------------------------------------------------------------------------------
/Development/Source/Ast/TinymoeAst.cpp:
--------------------------------------------------------------------------------
1 | #include "TinymoeAst.h"
2 |
3 | namespace tinymoe
4 | {
5 | namespace ast
6 | {
7 | /*************************************************************
8 | AstNode
9 | *************************************************************/
10 |
11 | AstNode::AstNode()
12 | {
13 | }
14 |
15 | AstNode::~AstNode()
16 | {
17 | }
18 |
19 | /*************************************************************
20 | Visitor
21 | *************************************************************/
22 |
23 | AstVisitor::AstVisitor()
24 | {
25 | }
26 |
27 | AstVisitor::~AstVisitor()
28 | {
29 | }
30 |
31 | AstTypeVisitor::AstTypeVisitor()
32 | {
33 | }
34 |
35 | AstTypeVisitor::~AstTypeVisitor()
36 | {
37 | }
38 |
39 | AstExpressionVisitor::AstExpressionVisitor()
40 | {
41 | }
42 |
43 | AstExpressionVisitor::~AstExpressionVisitor()
44 | {
45 | }
46 |
47 | AstStatementVisitor::AstStatementVisitor()
48 | {
49 | }
50 |
51 | AstStatementVisitor::~AstStatementVisitor()
52 | {
53 | }
54 |
55 | AstDeclarationVisitor::AstDeclarationVisitor()
56 | {
57 | }
58 |
59 | AstDeclarationVisitor::~AstDeclarationVisitor()
60 | {
61 | }
62 |
63 | /*************************************************************
64 | Node
65 | *************************************************************/
66 |
67 | void AstType::Accept(AstVisitor* visitor)
68 | {
69 | visitor->Visit(this);
70 | }
71 |
72 | void AstExpression::Accept(AstVisitor* visitor)
73 | {
74 | visitor->Visit(this);
75 | }
76 |
77 | void AstStatement::Accept(AstVisitor* visitor)
78 | {
79 | visitor->Visit(this);
80 | }
81 |
82 | void AstDeclaration::Accept(AstVisitor* visitor)
83 | {
84 | visitor->Visit(this);
85 | }
86 |
87 | void AstAssembly::Accept(AstVisitor* visitor)
88 | {
89 | visitor->Visit(this);
90 | }
91 |
92 | /*************************************************************
93 | Type
94 | *************************************************************/
95 |
96 | void AstPredefinedType::Accept(AstTypeVisitor* visitor)
97 | {
98 | visitor->Visit(this);
99 | }
100 |
101 | void AstReferenceType::Accept(AstTypeVisitor* visitor)
102 | {
103 | visitor->Visit(this);
104 | }
105 |
106 | /*************************************************************
107 | Expression
108 | *************************************************************/
109 |
110 | void AstLiteralExpression::Accept(AstExpressionVisitor* visitor)
111 | {
112 | visitor->Visit(this);
113 | }
114 |
115 | void AstIntegerExpression::Accept(AstExpressionVisitor* visitor)
116 | {
117 | visitor->Visit(this);
118 | }
119 |
120 | void AstFloatExpression::Accept(AstExpressionVisitor* visitor)
121 | {
122 | visitor->Visit(this);
123 | }
124 |
125 | void AstStringExpression::Accept(AstExpressionVisitor* visitor)
126 | {
127 | visitor->Visit(this);
128 | }
129 |
130 | void AstExternalSymbolExpression::Accept(AstExpressionVisitor* visitor)
131 | {
132 | visitor->Visit(this);
133 | }
134 |
135 | void AstReferenceExpression::Accept(AstExpressionVisitor* visitor)
136 | {
137 | visitor->Visit(this);
138 | }
139 |
140 | void AstNewTypeExpression::Accept(AstExpressionVisitor* visitor)
141 | {
142 | visitor->Visit(this);
143 | }
144 |
145 | void AstTestTypeExpression::Accept(AstExpressionVisitor* visitor)
146 | {
147 | visitor->Visit(this);
148 | }
149 |
150 | void AstNewArrayExpression::Accept(AstExpressionVisitor* visitor)
151 | {
152 | visitor->Visit(this);
153 | }
154 |
155 | void AstNewArrayLiteralExpression::Accept(AstExpressionVisitor* visitor)
156 | {
157 | visitor->Visit(this);
158 | }
159 |
160 | void AstArrayLengthExpression::Accept(AstExpressionVisitor* visitor)
161 | {
162 | visitor->Visit(this);
163 | }
164 |
165 | void AstArrayAccessExpression::Accept(AstExpressionVisitor* visitor)
166 | {
167 | visitor->Visit(this);
168 | }
169 |
170 | void AstFieldAccessExpression::Accept(AstExpressionVisitor* visitor)
171 | {
172 | visitor->Visit(this);
173 | }
174 |
175 | void AstInvokeExpression::Accept(AstExpressionVisitor* visitor)
176 | {
177 | visitor->Visit(this);
178 | }
179 |
180 | void AstLambdaExpression::Accept(AstExpressionVisitor* visitor)
181 | {
182 | visitor->Visit(this);
183 | }
184 |
185 | /*************************************************************
186 | Statement
187 | *************************************************************/
188 |
189 | void AstBlockStatement::Accept(AstStatementVisitor* visitor)
190 | {
191 | visitor->Visit(this);
192 | }
193 |
194 | void AstExpressionStatement::Accept(AstStatementVisitor* visitor)
195 | {
196 | visitor->Visit(this);
197 | }
198 |
199 | void AstDeclarationStatement::Accept(AstStatementVisitor* visitor)
200 | {
201 | visitor->Visit(this);
202 | }
203 |
204 | void AstAssignmentStatement::Accept(AstStatementVisitor* visitor)
205 | {
206 | visitor->Visit(this);
207 | }
208 |
209 | void AstIfStatement::Accept(AstStatementVisitor* visitor)
210 | {
211 | visitor->Visit(this);
212 | }
213 |
214 | /*************************************************************
215 | Declaration
216 | *************************************************************/
217 |
218 | void AstSymbolDeclaration::Accept(AstDeclarationVisitor* visitor)
219 | {
220 | visitor->Visit(this);
221 | }
222 |
223 | void AstTypeDeclaration::Accept(AstDeclarationVisitor* visitor)
224 | {
225 | visitor->Visit(this);
226 | }
227 |
228 | void AstFunctionDeclaration::Accept(AstDeclarationVisitor* visitor)
229 | {
230 | visitor->Visit(this);
231 | }
232 |
233 | }
234 | }
--------------------------------------------------------------------------------
/Development/Source/Ast/TinymoeAst.h:
--------------------------------------------------------------------------------
1 | #ifndef VCZH_AST_TINYMOEAST
2 | #define VCZH_AST_TINYMOEAST
3 |
4 | #include "../TinymoeSTL.h"
5 |
6 | namespace tinymoe
7 | {
8 | namespace ast
9 | {
10 | /*************************************************************
11 | Common
12 | *************************************************************/
13 |
14 | class AstType;
15 | class AstExpression;
16 | class AstStatement;
17 | class AstDeclaration;
18 |
19 | class AstVisitor;
20 | class AstTypeVisitor;
21 | class AstExpressionVisitor;
22 | class AstStatementVisitor;
23 | class AstDeclarationVisitor;
24 |
25 | class AstNode : public enable_shared_from_this
26 | {
27 | public:
28 | typedef shared_ptr Ptr;
29 | typedef weak_ptr WeakPtr;
30 |
31 | WeakPtr parent;
32 |
33 | AstNode();
34 | virtual ~AstNode();
35 |
36 | virtual void Accept(AstVisitor* visitor) = 0;
37 | };
38 |
39 | class AstType : public AstNode
40 | {
41 | public:
42 | typedef shared_ptr Ptr;
43 | typedef weak_ptr WeakPtr;
44 | typedef vector List;
45 |
46 | void Accept(AstVisitor* visitor)override;
47 | virtual void Accept(AstTypeVisitor* visitor) = 0;
48 | };
49 |
50 | class AstExpression : public AstNode
51 | {
52 | public:
53 | typedef shared_ptr Ptr;
54 | typedef weak_ptr WeakPtr;
55 | typedef vector List;
56 |
57 | void Accept(AstVisitor* visitor)override;
58 | virtual void Accept(AstExpressionVisitor* visitor) = 0;
59 | };
60 |
61 | class AstStatement : public AstNode
62 | {
63 | public:
64 | typedef shared_ptr Ptr;
65 | typedef weak_ptr WeakPtr;
66 | typedef vector List;
67 |
68 | void Accept(AstVisitor* visitor)override;
69 | virtual void Accept(AstStatementVisitor* visitor) = 0;
70 | };
71 |
72 | class AstDeclaration : public AstNode
73 | {
74 | public:
75 | typedef shared_ptr Ptr;
76 | typedef weak_ptr WeakPtr;
77 | typedef vector List;
78 |
79 | string_t composedName;
80 |
81 | void Accept(AstVisitor* visitor)override;
82 | virtual void Accept(AstDeclarationVisitor* visitor) = 0;
83 | };
84 |
85 | /*************************************************************
86 | Declaration
87 | *************************************************************/
88 |
89 | class AstSymbolDeclaration : public AstDeclaration
90 | {
91 | public:
92 | typedef shared_ptr Ptr;
93 | typedef vector List;
94 |
95 | void Accept(AstDeclarationVisitor* visitor)override;
96 | };
97 |
98 | class AstTypeDeclaration : public AstDeclaration
99 | {
100 | public:
101 | typedef shared_ptr Ptr;
102 |
103 | AstType::WeakPtr baseType;
104 | AstSymbolDeclaration::List fields;
105 |
106 | void Accept(AstDeclarationVisitor* visitor)override;
107 | };
108 |
109 | class AstFunctionDeclaration : public AstDeclaration
110 | {
111 | public:
112 | typedef shared_ptr Ptr;
113 |
114 | AstType::Ptr ownerType; // (optional) if ownerType is not null, this function is added to this type as a virtual function.
115 | AstSymbolDeclaration::List arguments;
116 | map readArgumentAstMap;
117 | map writeArgumentAstMap;
118 | AstStatement::Ptr statement;
119 |
120 | AstSymbolDeclaration::Ptr resultVariable;
121 |
122 | AstSymbolDeclaration::Ptr stateArgument; // for function
123 | AstSymbolDeclaration::Ptr signalArgument; // (optional) for block
124 | AstSymbolDeclaration::Ptr blockBodyArgument; // (optional) for block
125 | AstSymbolDeclaration::Ptr continuationArgument; // for function
126 |
127 | void Accept(AstDeclarationVisitor* visitor)override;
128 | };
129 |
130 | /*************************************************************
131 | Expression
132 | *************************************************************/
133 |
134 | enum class AstLiteralName
135 | {
136 | Null,
137 | True,
138 | False,
139 | };
140 |
141 | class AstLiteralExpression : public AstExpression
142 | {
143 | public:
144 | AstLiteralName literalName;
145 |
146 | void Accept(AstExpressionVisitor* visitor)override;
147 | };
148 |
149 | class AstIntegerExpression : public AstExpression
150 | {
151 | public:
152 | int64_t value;
153 |
154 | void Accept(AstExpressionVisitor* visitor)override;
155 | };
156 |
157 | class AstFloatExpression : public AstExpression
158 | {
159 | public:
160 | double value;
161 |
162 | void Accept(AstExpressionVisitor* visitor)override;
163 | };
164 |
165 | class AstStringExpression : public AstExpression
166 | {
167 | public:
168 | string_t value;
169 |
170 | void Accept(AstExpressionVisitor* visitor)override;
171 | };
172 |
173 | class AstExternalSymbolExpression : public AstExpression
174 | {
175 | public:
176 | string_t name;
177 |
178 | void Accept(AstExpressionVisitor* visitor)override;
179 | };
180 |
181 | class AstReferenceExpression : public AstExpression
182 | {
183 | public:
184 | AstDeclaration::WeakPtr reference; // could be
185 | // AstSymbolDeclaration
186 | // AstFunctionDeclaration
187 |
188 | void Accept(AstExpressionVisitor* visitor)override;
189 | };
190 |
191 | class AstNewTypeExpression : public AstExpression
192 | {
193 | public:
194 | AstType::Ptr type;
195 | AstExpression::List fields;
196 |
197 | void Accept(AstExpressionVisitor* visitor)override;
198 | };
199 |
200 | class AstTestTypeExpression : public AstExpression
201 | {
202 | public:
203 | AstExpression::Ptr target;
204 | AstType::Ptr type;
205 |
206 | void Accept(AstExpressionVisitor* visitor)override;
207 | };
208 |
209 | class AstNewArrayExpression : public AstExpression
210 | {
211 | public:
212 | AstExpression::Ptr length;
213 |
214 | void Accept(AstExpressionVisitor* visitor)override;
215 | };
216 |
217 | class AstNewArrayLiteralExpression : public AstExpression
218 | {
219 | public:
220 | AstExpression::List elements;
221 |
222 | void Accept(AstExpressionVisitor* visitor)override;
223 | };
224 |
225 | class AstArrayLengthExpression : public AstExpression
226 | {
227 | public:
228 | AstExpression::Ptr target;
229 |
230 | void Accept(AstExpressionVisitor* visitor)override;
231 | };
232 |
233 | class AstArrayAccessExpression : public AstExpression
234 | {
235 | public:
236 | AstExpression::Ptr target;
237 | AstExpression::Ptr index;
238 |
239 | void Accept(AstExpressionVisitor* visitor)override;
240 | };
241 |
242 | class AstFieldAccessExpression : public AstExpression
243 | {
244 | public:
245 | AstExpression::Ptr target;
246 | string_t composedFieldName;
247 |
248 | void Accept(AstExpressionVisitor* visitor)override;
249 | };
250 |
251 | class AstInvokeExpression : public AstExpression
252 | {
253 | public:
254 | AstExpression::Ptr function;
255 | AstExpression::List arguments;
256 |
257 | void Accept(AstExpressionVisitor* visitor)override;
258 | };
259 |
260 | class AstLambdaExpression : public AstExpression
261 | {
262 | public:
263 | AstSymbolDeclaration::List arguments;
264 | AstStatement::Ptr statement;
265 |
266 | void Accept(AstExpressionVisitor* visitor)override;
267 | };
268 |
269 | /*************************************************************
270 | Statement
271 | *************************************************************/
272 |
273 | class AstBlockStatement : public AstStatement
274 | {
275 | public:
276 | AstStatement::List statements;
277 |
278 | void Accept(AstStatementVisitor* visitor)override;
279 | };
280 |
281 | class AstExpressionStatement : public AstStatement
282 | {
283 | public:
284 | AstExpression::Ptr expression;
285 |
286 | void Accept(AstStatementVisitor* visitor)override;
287 | };
288 |
289 | class AstDeclarationStatement : public AstStatement
290 | {
291 | public:
292 | AstDeclaration::Ptr declaration;
293 |
294 | void Accept(AstStatementVisitor* visitor)override;
295 | };
296 |
297 | class AstAssignmentStatement : public AstStatement
298 | {
299 | public:
300 | AstExpression::Ptr target; // could be
301 | // AstReferenceExpression
302 | // AstFieldAccessExpression
303 | // AstArrayAccessExpression
304 | AstExpression::Ptr value;
305 |
306 | void Accept(AstStatementVisitor* visitor)override;
307 | };
308 |
309 |
310 | class AstIfStatement : public AstStatement
311 | {
312 | public:
313 | AstExpression::Ptr condition;
314 | AstStatement::Ptr trueBranch;
315 | AstStatement::Ptr falseBranch; // (optional)
316 |
317 | void Accept(AstStatementVisitor* visitor)override;
318 | };
319 |
320 | /*************************************************************
321 | Type
322 | *************************************************************/
323 |
324 | enum class AstPredefinedTypeName
325 | {
326 | Object,
327 | Symbol,
328 | Array,
329 | Boolean,
330 | Integer,
331 | Float,
332 | String,
333 | Function,
334 | };
335 |
336 | class AstPredefinedType : public AstType
337 | {
338 | public:
339 | AstPredefinedTypeName typeName;
340 |
341 | void Accept(AstTypeVisitor* visitor)override;
342 | };
343 |
344 | class AstReferenceType : public AstType
345 | {
346 | public:
347 | weak_ptr typeDeclaration;
348 |
349 | void Accept(AstTypeVisitor* visitor)override;
350 | };
351 |
352 | /*************************************************************
353 | Assembly
354 | *************************************************************/
355 |
356 | class AstAssembly : public AstNode
357 | {
358 | public:
359 | typedef shared_ptr Ptr;
360 |
361 | AstDeclaration::List declarations;
362 |
363 | void Accept(AstVisitor* visitor)override;
364 | };
365 |
366 | /*************************************************************
367 | Visitors
368 | *************************************************************/
369 |
370 | class AstVisitor
371 | {
372 | public:
373 | AstVisitor();
374 | virtual ~AstVisitor();
375 |
376 | virtual void Visit(AstType* node) = 0;
377 | virtual void Visit(AstExpression* node) = 0;
378 | virtual void Visit(AstStatement* node) = 0;
379 | virtual void Visit(AstDeclaration* node) = 0;
380 | virtual void Visit(AstAssembly* node) = 0;
381 | };
382 |
383 | class AstTypeVisitor
384 | {
385 | public:
386 | AstTypeVisitor();
387 | virtual ~AstTypeVisitor();
388 |
389 | virtual void Visit(AstPredefinedType* node) = 0;
390 | virtual void Visit(AstReferenceType* node) = 0;
391 | };
392 |
393 | class AstExpressionVisitor
394 | {
395 | public:
396 | AstExpressionVisitor();
397 | virtual ~AstExpressionVisitor();
398 |
399 | virtual void Visit(AstLiteralExpression* node) = 0;
400 | virtual void Visit(AstIntegerExpression* node) = 0;
401 | virtual void Visit(AstFloatExpression* node) = 0;
402 | virtual void Visit(AstStringExpression* node) = 0;
403 | virtual void Visit(AstExternalSymbolExpression* node) = 0;
404 | virtual void Visit(AstReferenceExpression* node) = 0;
405 | virtual void Visit(AstNewTypeExpression* node) = 0;
406 | virtual void Visit(AstTestTypeExpression* node) = 0;
407 | virtual void Visit(AstNewArrayExpression* node) = 0;
408 | virtual void Visit(AstNewArrayLiteralExpression* node) = 0;
409 | virtual void Visit(AstArrayLengthExpression* node) = 0;
410 | virtual void Visit(AstArrayAccessExpression* node) = 0;
411 | virtual void Visit(AstFieldAccessExpression* node) = 0;
412 | virtual void Visit(AstInvokeExpression* node) = 0;
413 | virtual void Visit(AstLambdaExpression* node) = 0;
414 | };
415 |
416 | class AstStatementVisitor
417 | {
418 | public:
419 | AstStatementVisitor();
420 | virtual ~AstStatementVisitor();
421 |
422 | virtual void Visit(AstBlockStatement* node) = 0;
423 | virtual void Visit(AstExpressionStatement* node) = 0;
424 | virtual void Visit(AstDeclarationStatement* node) = 0;
425 | virtual void Visit(AstAssignmentStatement* node) = 0;
426 | virtual void Visit(AstIfStatement* node) = 0;
427 | };
428 |
429 | class AstDeclarationVisitor
430 | {
431 | public:
432 | AstDeclarationVisitor();
433 | virtual ~AstDeclarationVisitor();
434 |
435 | virtual void Visit(AstSymbolDeclaration* node) = 0;
436 | virtual void Visit(AstTypeDeclaration* node) = 0;
437 | virtual void Visit(AstFunctionDeclaration* node) = 0;
438 | };
439 |
440 | /*************************************************************
441 | Helper Functions
442 | *************************************************************/
443 |
444 | extern void SetParent(AstNode::Ptr node, AstNode::WeakPtr _parent = AstNode::WeakPtr());
445 | extern void Print(AstNode::Ptr node, ostream_t& o, int indentation, AstNode::WeakPtr _parent = AstNode::WeakPtr());
446 |
447 | extern void CollectSideEffectExpressions(AstExpression::Ptr node, AstExpression::List& exprs);
448 | extern void CollectUsedVariables(AstExpression::Ptr node, bool rightValue, set>& defined, set>& used);
449 | extern void CollectUsedVariables(AstStatement::Ptr node, set>& defined, set>& used);
450 | extern void ExpandBlock(AstStatement::Ptr node, AstStatement::List& stats, bool lastStatement);
451 | extern AstDeclaration::Ptr GetRootLeftValue(AstExpression::Ptr node);
452 | extern void RemoveUnnecessaryVariables(AstExpression::Ptr node, set>& defined, set>& used);
453 | extern void RemoveUnnecessaryVariables(AstStatement::Ptr node, set>& defined, set>& used, AstStatement::Ptr& replacement);
454 |
455 | extern void RoughlyOptimize(AstDeclaration::Ptr node);
456 | extern void RoughlyOptimize(AstExpression::Ptr node, AstExpression::Ptr& _replacement);
457 | extern void RoughlyOptimize(AstStatement::Ptr node, AstStatement::Ptr& _replacement);
458 | extern void RoughlyOptimize(AstAssembly::Ptr node);
459 | }
460 | }
461 |
462 | #endif
--------------------------------------------------------------------------------
/Development/Source/Ast/TinymoeAst_CollectSideEffectExpressions.cpp:
--------------------------------------------------------------------------------
1 | #include "TinymoeAst.h"
2 |
3 | namespace tinymoe
4 | {
5 | namespace ast
6 | {
7 | /*************************************************************
8 | AstExpression::CollectSideEffectExpressions
9 | *************************************************************/
10 |
11 | class AstExpression_CollectSideEffectExpressions : public AstExpressionVisitor
12 | {
13 | private:
14 | AstExpression::List& exprs;
15 |
16 | public:
17 | AstExpression_CollectSideEffectExpressions(AstExpression::List& _exprs)
18 | :exprs(_exprs)
19 | {
20 | }
21 |
22 | void Visit(AstLiteralExpression* node)override
23 | {
24 | }
25 |
26 | void Visit(AstIntegerExpression* node)override
27 | {
28 | }
29 |
30 | void Visit(AstFloatExpression* node)override
31 | {
32 | }
33 |
34 | void Visit(AstStringExpression* node)override
35 | {
36 | }
37 |
38 | void Visit(AstExternalSymbolExpression* node)override
39 | {
40 | }
41 |
42 | void Visit(AstReferenceExpression* node)override
43 | {
44 | }
45 |
46 | void Visit(AstNewTypeExpression* node)override
47 | {
48 | for (auto field : node->fields)
49 | {
50 | CollectSideEffectExpressions(field, exprs);
51 | }
52 | }
53 |
54 | void Visit(AstTestTypeExpression* node)override
55 | {
56 | CollectSideEffectExpressions(node->target, exprs);
57 | }
58 |
59 | void Visit(AstNewArrayExpression* node)override
60 | {
61 | CollectSideEffectExpressions(node->length, exprs);
62 | }
63 |
64 | void Visit(AstNewArrayLiteralExpression* node)override
65 | {
66 | for (auto element : node->elements)
67 | {
68 | CollectSideEffectExpressions(element, exprs);
69 | }
70 | }
71 |
72 | void Visit(AstArrayLengthExpression* node)override
73 | {
74 | CollectSideEffectExpressions(node->target, exprs);
75 | }
76 |
77 | void Visit(AstArrayAccessExpression* node)override
78 | {
79 | CollectSideEffectExpressions(node->target, exprs);
80 | CollectSideEffectExpressions(node->index, exprs);
81 | }
82 |
83 | void Visit(AstFieldAccessExpression* node)override
84 | {
85 | CollectSideEffectExpressions(node->target, exprs);
86 | }
87 |
88 | void Visit(AstInvokeExpression* node)override
89 | {
90 | exprs.push_back(dynamic_pointer_cast(node->shared_from_this()));
91 | }
92 |
93 | void Visit(AstLambdaExpression* node)override
94 | {
95 | }
96 | };
97 |
98 | /*************************************************************
99 | AstExpression::CollectSideEffectExpressions
100 | *************************************************************/
101 |
102 | void CollectSideEffectExpressions(AstExpression::Ptr node, AstExpression::List& exprs)
103 | {
104 | AstExpression_CollectSideEffectExpressions visitor(exprs);
105 | node->Accept(&visitor);
106 | }
107 | }
108 | }
--------------------------------------------------------------------------------
/Development/Source/Ast/TinymoeAst_CollectUsedVariables.cpp:
--------------------------------------------------------------------------------
1 | #include "TinymoeAst.h"
2 |
3 | namespace tinymoe
4 | {
5 | namespace ast
6 | {
7 | /*************************************************************
8 | AstExpression::CollectUsedVariables
9 | *************************************************************/
10 |
11 | class AstExpression_CollectUsedVariables : public AstExpressionVisitor
12 | {
13 | private:
14 | bool rightValue;
15 | set>& defined;
16 | set>& used;
17 | public:
18 | AstExpression_CollectUsedVariables(bool _rightValue, set>& _defined, set>& _used)
19 | :rightValue(_rightValue), defined(_defined), used(_used)
20 | {
21 |
22 | }
23 |
24 | void Visit(AstLiteralExpression* node)override
25 | {
26 | }
27 |
28 | void Visit(AstIntegerExpression* node)override
29 | {
30 | }
31 |
32 | void Visit(AstFloatExpression* node)override
33 | {
34 | }
35 |
36 | void Visit(AstStringExpression* node)override
37 | {
38 | }
39 |
40 | void Visit(AstExternalSymbolExpression* node)override
41 | {
42 | }
43 |
44 | void Visit(AstReferenceExpression* node)override
45 | {
46 | if (rightValue)
47 | {
48 | used.insert(node->reference.lock());
49 | }
50 | }
51 |
52 | void Visit(AstNewTypeExpression* node)override
53 | {
54 | for (auto field : node->fields)
55 | {
56 | CollectUsedVariables(field, true, defined, used);
57 | }
58 | }
59 |
60 | void Visit(AstTestTypeExpression* node)override
61 | {
62 | CollectUsedVariables(node->target, true, defined, used);
63 | }
64 |
65 | void Visit(AstNewArrayExpression* node)override
66 | {
67 | CollectUsedVariables(node->length, true, defined, used);
68 | }
69 |
70 | void Visit(AstNewArrayLiteralExpression* node)override
71 | {
72 | for (auto element : node->elements)
73 | {
74 | CollectUsedVariables(element, true, defined, used);
75 | }
76 | }
77 |
78 | void Visit(AstArrayLengthExpression* node)override
79 | {
80 | CollectUsedVariables(node->target, true, defined, used);
81 | }
82 |
83 | void Visit(AstArrayAccessExpression* node)override
84 | {
85 | CollectUsedVariables(node->target, rightValue, defined, used);
86 | CollectUsedVariables(node->index, true, defined, used);
87 | }
88 |
89 | void Visit(AstFieldAccessExpression* node)override
90 | {
91 | if (rightValue)
92 | {
93 | CollectUsedVariables(node->target, true, defined, used);
94 | }
95 | }
96 |
97 | void Visit(AstInvokeExpression* node)override
98 | {
99 | CollectUsedVariables(node->function, true, defined, used);
100 | for (auto argument : node->arguments)
101 | {
102 | CollectUsedVariables(argument, true, defined, used);
103 | }
104 | }
105 |
106 | void Visit(AstLambdaExpression* node)override
107 | {
108 | CollectUsedVariables(node->statement, defined, used);
109 | }
110 | };
111 |
112 | /*************************************************************
113 | AstStatement::CollectUsedVariables
114 | *************************************************************/
115 |
116 | class AstStatement_CollectUsedVariables : public AstStatementVisitor
117 | {
118 | private:
119 | set>& defined;
120 | set>& used;
121 | public:
122 | AstStatement_CollectUsedVariables(set>& _defined, set>& _used)
123 | :defined(_defined), used(_used)
124 | {
125 |
126 | }
127 |
128 | void Visit(AstBlockStatement* node)override
129 | {
130 | for (auto stat : node->statements)
131 | {
132 | CollectUsedVariables(stat, defined, used);
133 | }
134 | }
135 |
136 | void Visit(AstExpressionStatement* node)override
137 | {
138 | CollectUsedVariables(node->expression, true, defined, used);
139 | }
140 |
141 | void Visit(AstDeclarationStatement* node)override
142 | {
143 | defined.insert(node->declaration);
144 | }
145 |
146 | void Visit(AstAssignmentStatement* node)override
147 | {
148 | CollectUsedVariables(node->target, false, defined, used);
149 | CollectUsedVariables(node->value, true, defined, used);
150 | }
151 |
152 | void Visit(AstIfStatement* node)override
153 | {
154 | CollectUsedVariables(node->condition, true, defined, used);
155 | CollectUsedVariables(node->trueBranch, defined, used);
156 | if (node->falseBranch)
157 | {
158 | CollectUsedVariables(node->falseBranch, defined, used);
159 | }
160 | }
161 | };
162 |
163 | /*************************************************************
164 | CollectUsedVariables
165 | *************************************************************/
166 |
167 | void CollectUsedVariables(AstExpression::Ptr node, bool rightValue, set>& defined, set>& used)
168 | {
169 | AstExpression_CollectUsedVariables visitor(rightValue, defined, used);
170 | node->Accept(&visitor);
171 | }
172 |
173 | void CollectUsedVariables(AstStatement::Ptr node, set>& defined, set>& used)
174 | {
175 | AstStatement_CollectUsedVariables visitor(defined, used);
176 | node->Accept(&visitor);
177 | }
178 | }
179 | }
--------------------------------------------------------------------------------
/Development/Source/Ast/TinymoeAst_ExpandBlock.cpp:
--------------------------------------------------------------------------------
1 | #include "TinymoeAst.h"
2 |
3 | namespace tinymoe
4 | {
5 | namespace ast
6 | {
7 | /*************************************************************
8 | AstStatement::ExpandBlock
9 | *************************************************************/
10 |
11 | class AstStatement_ExpandBlock : public AstStatementVisitor
12 | {
13 | private:
14 | AstStatement::List& stats;
15 | bool lastStatement;
16 |
17 | public:
18 | AstStatement_ExpandBlock(AstStatement::List& _stats, bool _lastStatement)
19 | :stats(_stats), lastStatement(_lastStatement)
20 | {
21 |
22 | }
23 |
24 | void Visit(AstBlockStatement* node)override
25 | {
26 | if (!lastStatement)
27 | {
28 | for (auto stat : node->statements)
29 | {
30 | if (dynamic_pointer_cast(stat))
31 | {
32 | stats.push_back(dynamic_pointer_cast(node->shared_from_this()));
33 | return;
34 | }
35 | }
36 | }
37 |
38 | for (auto stat : node->statements)
39 | {
40 | ExpandBlock(stat, stats, stat == *(node->statements.end() - 1));
41 | }
42 | }
43 |
44 | void Visit(AstExpressionStatement* node)override
45 | {
46 | stats.push_back(dynamic_pointer_cast(node->shared_from_this()));
47 | }
48 |
49 | void Visit(AstDeclarationStatement* node)override
50 | {
51 | stats.push_back(dynamic_pointer_cast(node->shared_from_this()));
52 | }
53 |
54 | void Visit(AstAssignmentStatement* node)override
55 | {
56 | stats.push_back(dynamic_pointer_cast(node->shared_from_this()));
57 | }
58 |
59 | void Visit(AstIfStatement* node)override
60 | {
61 | stats.push_back(dynamic_pointer_cast(node->shared_from_this()));
62 | }
63 | };
64 |
65 | /*************************************************************
66 | ExpandBlock
67 | *************************************************************/
68 |
69 | void ExpandBlock(AstStatement::Ptr node, AstStatement::List& stats, bool lastStatement)
70 | {
71 | AstStatement_ExpandBlock visitor(stats, lastStatement);
72 | node->Accept(&visitor);
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/Development/Source/Ast/TinymoeAst_GetRootLeftValue.cpp:
--------------------------------------------------------------------------------
1 | #include "TinymoeAst.h"
2 |
3 | namespace tinymoe
4 | {
5 | namespace ast
6 | {
7 | /*************************************************************
8 | AstExpression::GetRootLeftValue
9 | *************************************************************/
10 |
11 | class AstExpression_GetRootLeftValue : public AstExpressionVisitor
12 | {
13 | public:
14 | shared_ptr result;
15 |
16 | void Visit(AstLiteralExpression* node)override
17 | {
18 | }
19 |
20 | void Visit(AstIntegerExpression* node)override
21 | {
22 | }
23 |
24 | void Visit(AstFloatExpression* node)override
25 | {
26 | }
27 |
28 | void Visit(AstStringExpression* node)override
29 | {
30 | }
31 |
32 | void Visit(AstExternalSymbolExpression* node)override
33 | {
34 | }
35 |
36 | void Visit(AstReferenceExpression* node)override
37 | {
38 | result = node->reference.lock();
39 | }
40 |
41 | void Visit(AstNewTypeExpression* node)override
42 | {
43 | }
44 |
45 | void Visit(AstTestTypeExpression* node)override
46 | {
47 | }
48 |
49 | void Visit(AstNewArrayExpression* node)override
50 | {
51 | }
52 |
53 | void Visit(AstNewArrayLiteralExpression* node)override
54 | {
55 | }
56 |
57 | void Visit(AstArrayLengthExpression* node)override
58 | {
59 | }
60 |
61 | void Visit(AstArrayAccessExpression* node)override
62 | {
63 | result = GetRootLeftValue(node->target);
64 | }
65 |
66 | void Visit(AstFieldAccessExpression* node)override
67 | {
68 | result = GetRootLeftValue(node->target);
69 | }
70 |
71 | void Visit(AstInvokeExpression* node)override
72 | {
73 | }
74 |
75 | void Visit(AstLambdaExpression* node)override
76 | {
77 | }
78 | };
79 |
80 | /*************************************************************
81 | GetRootLeftValue
82 | *************************************************************/
83 |
84 | AstDeclaration::Ptr GetRootLeftValue(AstExpression::Ptr node)
85 | {
86 | AstExpression_GetRootLeftValue visitor;
87 | node->Accept(&visitor);
88 | return visitor.result;
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/Development/Source/Ast/TinymoeAst_Print.cpp:
--------------------------------------------------------------------------------
1 | #include "TinymoeAst.h"
2 |
3 | // find: void (\w+)::PrintInternal\(ostream_t& o, int indentation\)
4 | // replace: void Visit($1* node)override
5 |
6 | namespace tinymoe
7 | {
8 | namespace ast
9 | {
10 | string_t Indent(int indentation)
11 | {
12 | string_t s;
13 | for (int i = 0; i < indentation; i++)
14 | {
15 | s += T(" ");
16 | }
17 | return s;
18 | }
19 |
20 | /*************************************************************
21 | AstDeclaration::Print
22 | *************************************************************/
23 |
24 | class AstDeclaration_Print : public AstDeclarationVisitor
25 | {
26 | private:
27 | ostream_t& o;
28 | int indentation;
29 | public:
30 | AstDeclaration_Print(ostream_t& _o, int _indentation)
31 | :o(_o), indentation(_indentation)
32 | {
33 | }
34 |
35 | void Visit(AstSymbolDeclaration* node)override
36 | {
37 | o << Indent(indentation) << T("$symbol ") << node->composedName << T(";");
38 | }
39 |
40 | void Visit(AstTypeDeclaration* node)override
41 | {
42 | o << Indent(indentation) << T("$type ") << node->composedName;
43 | if (!node->baseType.expired())
44 | {
45 | o << T(" : ");
46 | Print(node->baseType.lock(), o, indentation);
47 | }
48 | o << endl << Indent(indentation) << T("{") << endl;
49 | for (auto field : node->fields)
50 | {
51 | Print(field, o, indentation + 1, node->shared_from_this());
52 | o << endl;
53 | }
54 | o << Indent(indentation) << T("}");
55 | }
56 |
57 | void Visit(AstFunctionDeclaration* node)override
58 | {
59 | o << Indent(indentation) << T("$procedure ");
60 | if (node->ownerType)
61 | {
62 | o << T("(");
63 | Print(node->ownerType, o, indentation, node->shared_from_this());
64 | o << T(").");
65 | }
66 | o << node->composedName << T("(");
67 | for (auto it = node->arguments.begin(); it != node->arguments.end(); it++)
68 | {
69 | o << (*it)->composedName;
70 | if (it + 1 != node->arguments.end())
71 | {
72 | o << T(", ");
73 | }
74 | }
75 |
76 | o << T(")") << endl;
77 | Print(node->statement, o, indentation, node->shared_from_this());
78 | }
79 | };
80 |
81 | /*************************************************************
82 | AstExpression::Print
83 | *************************************************************/
84 |
85 | class AstExpression_Print : public AstExpressionVisitor
86 | {
87 | private:
88 | ostream_t& o;
89 | int indentation;
90 | public:
91 | AstExpression_Print(ostream_t& _o, int _indentation)
92 | :o(_o), indentation(_indentation)
93 | {
94 | }
95 |
96 | void Visit(AstLiteralExpression* node)override
97 | {
98 | switch (node->literalName)
99 | {
100 | case AstLiteralName::Null:
101 | o << T("$null");
102 | break;
103 | case AstLiteralName::True:
104 | o << T("$true");
105 | break;
106 | case AstLiteralName::False:
107 | o << T("$false");
108 | break;
109 | }
110 | }
111 |
112 | void Visit(AstIntegerExpression* node)override
113 | {
114 | o << node->value;
115 | }
116 |
117 | void Visit(AstFloatExpression* node)override
118 | {
119 | o << node->value;
120 | }
121 |
122 | void Visit(AstStringExpression* node)override
123 | {
124 | o << T("\"") << node->value << T("\"");
125 | }
126 |
127 | void Visit(AstExternalSymbolExpression* node)override
128 | {
129 | o << T("$external (\"") << node->name << T("\")");
130 | }
131 |
132 | void Visit(AstReferenceExpression* node)override
133 | {
134 | o << node->reference.lock()->composedName;
135 | }
136 |
137 | void Visit(AstNewTypeExpression* node)override
138 | {
139 | o << T("new ");
140 | Print(node->type, o, indentation, node->shared_from_this());
141 | o << T("(");
142 | for (auto it = node->fields.begin(); it != node->fields.end(); it++)
143 | {
144 | Print((*it), o, indentation, node->shared_from_this());
145 | if (it + 1 != node->fields.end())
146 | {
147 | o << T(", ");
148 | }
149 | }
150 | o << T(")");
151 | }
152 |
153 | void Visit(AstTestTypeExpression* node)override
154 | {
155 | o << T("(");
156 | Print(node->target, o, indentation, node->shared_from_this());
157 | o << T(" is ");
158 | Print(node->type, o, indentation, node->shared_from_this());
159 | o << T(")");
160 | }
161 |
162 | void Visit(AstNewArrayExpression* node)override
163 | {
164 | o << T("new $Array(");
165 | Print(node->length, o, indentation, node->shared_from_this());
166 | o << T(")");
167 | }
168 |
169 | void Visit(AstNewArrayLiteralExpression* node)override
170 | {
171 | o << T("[");
172 | for (auto it = node->elements.begin(); it != node->elements.end(); it++)
173 | {
174 | Print((*it), o, indentation, node->shared_from_this());
175 | if (it + 1 != node->elements.end())
176 | {
177 | o << T(", ");
178 | }
179 | }
180 | o << T("]");
181 | }
182 |
183 | void Visit(AstArrayLengthExpression* node)override
184 | {
185 | o << T("$ArrayLength(");
186 | Print(node->target, o, indentation, node->shared_from_this());
187 | o << T(")");
188 | }
189 |
190 | void Visit(AstArrayAccessExpression* node)override
191 | {
192 | Print(node->target, o, indentation, node->shared_from_this());
193 | o << T("[");
194 | Print(node->index, o, indentation, node->shared_from_this());
195 | o << T("]");
196 | }
197 |
198 | void Visit(AstFieldAccessExpression* node)override
199 | {
200 | Print(node->target, o, indentation, node->shared_from_this());
201 | o << T(".") << node->composedFieldName;
202 | }
203 |
204 | void Visit(AstInvokeExpression* node)override
205 | {
206 | Print(node->function, o, indentation, node->shared_from_this());
207 | o << T("(") << endl;
208 | for (auto it = node->arguments.begin(); it != node->arguments.end(); it++)
209 | {
210 | o << Indent(indentation + 1);
211 | Print((*it), o, indentation + 1, node->shared_from_this());
212 | if (it + 1 != node->arguments.end())
213 | {
214 | o << T(", ");
215 | }
216 | o << endl;
217 | }
218 | o << Indent(indentation + 1) << T(")");
219 | }
220 |
221 | void Visit(AstLambdaExpression* node)override
222 | {
223 | o << T("$lambda (");
224 | for (auto it = node->arguments.begin(); it != node->arguments.end(); it++)
225 | {
226 | o << (*it)->composedName;
227 | if (it + 1 != node->arguments.end())
228 | {
229 | o << T(", ");
230 | }
231 | }
232 | o << T(")") << endl;
233 | Print(node->statement, o, indentation + 1, node->shared_from_this());
234 | }
235 | };
236 |
237 | /*************************************************************
238 | AstStatement::Print
239 | *************************************************************/
240 |
241 | class AstStatement_Print : public AstStatementVisitor
242 | {
243 | private:
244 | ostream_t& o;
245 | int indentation;
246 | public:
247 | AstStatement_Print(ostream_t& _o, int _indentation)
248 | :o(_o), indentation(_indentation)
249 | {
250 | }
251 |
252 | void Visit(AstBlockStatement* node)override
253 | {
254 | o << Indent(indentation) << T("{") << endl;
255 | for (auto statement : node->statements)
256 | {
257 | Print(statement, o, indentation + 1, node->shared_from_this());
258 | o << endl;
259 | }
260 | o << Indent(indentation) << T("}");
261 | }
262 |
263 | void Visit(AstExpressionStatement* node)override
264 | {
265 | o << Indent(indentation);
266 | Print(node->expression, o, indentation, node->shared_from_this());
267 | o << T(";");
268 | }
269 |
270 | void Visit(AstDeclarationStatement* node)override
271 | {
272 | Print(node->declaration, o, indentation, node->shared_from_this());
273 | }
274 |
275 | void Visit(AstAssignmentStatement* node)override
276 | {
277 | o << Indent(indentation);
278 | Print(node->target, o, indentation, node->shared_from_this());
279 | o << T(" = ");
280 | Print(node->value, o, indentation, node->shared_from_this());
281 | o << T(";");
282 | }
283 |
284 | void Visit(AstIfStatement* node)override
285 | {
286 | o << Indent(indentation) << T("if (");
287 | Print(node->condition, o, indentation, node->shared_from_this());
288 | o << endl;
289 | Print(node->trueBranch, o, indentation + 1, node->shared_from_this());
290 | if (node->falseBranch)
291 | {
292 | o << endl << Indent(indentation) << T("else") << endl;
293 | Print(node->falseBranch, o, indentation + 1, node->shared_from_this());
294 | }
295 | }
296 | };
297 |
298 | /*************************************************************
299 | AstType::Print
300 | *************************************************************/
301 |
302 | class AstType_Print : public AstTypeVisitor
303 | {
304 | private:
305 | ostream_t& o;
306 | int indentation;
307 | public:
308 | AstType_Print(ostream_t& _o, int _indentation)
309 | :o(_o), indentation(_indentation)
310 | {
311 | }
312 |
313 | void Visit(AstPredefinedType* node)override
314 | {
315 | switch (node->typeName)
316 | {
317 | case AstPredefinedTypeName::Object:
318 | o << T("$Object");
319 | break;
320 | case AstPredefinedTypeName::Symbol:
321 | o << T("$Symbol");
322 | break;
323 | case AstPredefinedTypeName::Array:
324 | o << T("$Array");
325 | break;
326 | case AstPredefinedTypeName::Boolean:
327 | o << T("$Boolean");
328 | break;
329 | case AstPredefinedTypeName::Integer:
330 | o << T("$Integer");
331 | break;
332 | case AstPredefinedTypeName::Float:
333 | o << T("$Float");
334 | break;
335 | case AstPredefinedTypeName::String:
336 | o << T("$Function");
337 | break;
338 | }
339 | }
340 |
341 | void Visit(AstReferenceType* node)override
342 | {
343 | o << node->typeDeclaration.lock()->composedName;
344 | }
345 | };
346 |
347 | /*************************************************************
348 | AstAssembly::Print
349 | *************************************************************/
350 |
351 | class AstNode_Print : public AstVisitor
352 | {
353 | private:
354 | ostream_t& o;
355 | int indentation;
356 | public:
357 | AstNode_Print(ostream_t& _o, int _indentation)
358 | :o(_o), indentation(_indentation)
359 | {
360 | }
361 |
362 | void Visit(AstType* node)override
363 | {
364 | AstType_Print visitor(o, indentation);
365 | node->Accept(&visitor);
366 | }
367 |
368 | void Visit(AstExpression* node)override
369 | {
370 | AstExpression_Print visitor(o, indentation);
371 | node->Accept(&visitor);
372 | }
373 |
374 | void Visit(AstStatement* node)override
375 | {
376 | AstStatement_Print visitor(o, indentation);
377 | node->Accept(&visitor);
378 | }
379 |
380 | void Visit(AstDeclaration* node)override
381 | {
382 | AstDeclaration_Print visitor(o, indentation);
383 | node->Accept(&visitor);
384 | }
385 |
386 | void Visit(AstAssembly* node)override
387 | {
388 | for (auto decl : node->declarations)
389 | {
390 | Print(decl, o, indentation, node->shared_from_this());
391 | o << endl << endl;
392 | }
393 | }
394 | };
395 |
396 | /*************************************************************
397 | Print
398 | *************************************************************/
399 |
400 | void Print(AstNode::Ptr node, ostream_t& o, int indentation, AstNode::WeakPtr _parent)
401 | {
402 | ASSERT(_parent.expired() || node->parent.lock() == _parent.lock());
403 | AstNode_Print visitor(o, indentation);
404 | node->Accept(&visitor);
405 | }
406 | }
407 | }
--------------------------------------------------------------------------------
/Development/Source/Ast/TinymoeAst_RemoveUnnecessaryVariables.cpp:
--------------------------------------------------------------------------------
1 | #include "TinymoeAst.h"
2 |
3 | namespace tinymoe
4 | {
5 | namespace ast
6 | {
7 | /*************************************************************
8 | AstExpression::RemoveUnnecessaryVariables
9 | *************************************************************/
10 |
11 | class AstExpression_RemoveUnnecessaryVariables : public AstExpressionVisitor
12 | {
13 | private:
14 | set>& defined;
15 | set>& used;
16 | public:
17 | AstExpression_RemoveUnnecessaryVariables(set>& _defined, set>& _used)
18 | :defined(_defined), used(_used)
19 | {
20 | }
21 |
22 | void Visit(AstLiteralExpression* node)override
23 | {
24 | }
25 |
26 | void Visit(AstIntegerExpression* node)override
27 | {
28 | }
29 |
30 | void Visit(AstFloatExpression* node)override
31 | {
32 | }
33 |
34 | void Visit(AstStringExpression* node)override
35 | {
36 | }
37 |
38 | void Visit(AstExternalSymbolExpression* node)override
39 | {
40 | }
41 |
42 | void Visit(AstReferenceExpression* node)override
43 | {
44 | }
45 |
46 | void Visit(AstNewTypeExpression* node)override
47 | {
48 | for (auto field : node->fields)
49 | {
50 | RemoveUnnecessaryVariables(field, defined, used);
51 | }
52 | }
53 |
54 | void Visit(AstTestTypeExpression* node)override
55 | {
56 | RemoveUnnecessaryVariables(node->target, defined, used);
57 | }
58 |
59 | void Visit(AstNewArrayExpression* node)override
60 | {
61 | RemoveUnnecessaryVariables(node->length, defined, used);
62 | }
63 |
64 | void Visit(AstNewArrayLiteralExpression* node)override
65 | {
66 | for (auto element : node->elements)
67 | {
68 | RemoveUnnecessaryVariables(element, defined, used);
69 | }
70 | }
71 |
72 | void Visit(AstArrayLengthExpression* node)override
73 | {
74 | RemoveUnnecessaryVariables(node->target, defined, used);
75 | }
76 |
77 | void Visit(AstArrayAccessExpression* node)override
78 | {
79 | RemoveUnnecessaryVariables(node->target, defined, used);
80 | RemoveUnnecessaryVariables(node->index, defined, used);
81 | }
82 |
83 | void Visit(AstFieldAccessExpression* node)override
84 | {
85 | RemoveUnnecessaryVariables(node->target, defined, used);
86 | }
87 |
88 | void Visit(AstInvokeExpression* node)override
89 | {
90 | RemoveUnnecessaryVariables(node->function, defined, used);
91 | for (auto argument : node->arguments)
92 | {
93 | RemoveUnnecessaryVariables(argument, defined, used);
94 | }
95 | }
96 |
97 | void Visit(AstLambdaExpression* node)override
98 | {
99 | RemoveUnnecessaryVariables(node->statement, defined, used, node->statement);
100 | }
101 | };
102 |
103 | /*************************************************************
104 | AstStatement::RemoveUnnecessaryVariables
105 | *************************************************************/
106 |
107 | class AstStatement_RemoveUnnecessaryVariables : public AstStatementVisitor
108 | {
109 | private:
110 | set>& defined;
111 | set>& used;
112 | AstStatement::Ptr& replacement;
113 | public:
114 | AstStatement_RemoveUnnecessaryVariables(set>& _defined, set>& _used, AstStatement::Ptr& _replacement)
115 | :defined(_defined), used(_used), replacement(_replacement)
116 | {
117 | }
118 |
119 | void Visit(AstBlockStatement* node)override
120 | {
121 | for (int i = node->statements.size() - 1; i >= 0; i--)
122 | {
123 | RemoveUnnecessaryVariables(node->statements[i], defined, used, node->statements[i]);
124 | }
125 | }
126 |
127 | void Visit(AstExpressionStatement* node)override
128 | {
129 | RemoveUnnecessaryVariables(node->expression, defined, used);
130 | }
131 |
132 | void Visit(AstDeclarationStatement* node)override
133 | {
134 | if (defined.find(node->declaration) != defined.end() && used.find(node->declaration) == used.end())
135 | {
136 | replacement = make_shared();
137 | }
138 | }
139 |
140 | void Visit(AstAssignmentStatement* node)override
141 | {
142 | auto leftValue = GetRootLeftValue(node->target);
143 | if (defined.find(leftValue) != defined.end() && used.find(leftValue) == used.end())
144 | {
145 | AstExpression::List exprs;
146 | CollectSideEffectExpressions(node->target, exprs);
147 | CollectSideEffectExpressions(node->value, exprs);
148 |
149 | auto block = make_shared();
150 | for (auto expr : exprs)
151 | {
152 | auto stat = make_shared();
153 | stat->expression = expr;
154 | block->statements.push_back(stat);
155 | }
156 | replacement = block;
157 | }
158 | }
159 |
160 | void Visit(AstIfStatement* node)override
161 | {
162 | RemoveUnnecessaryVariables(node->trueBranch, defined, used, node->trueBranch);
163 | if (node->falseBranch)
164 | {
165 | RemoveUnnecessaryVariables(node->falseBranch, defined, used, node->falseBranch);
166 | }
167 | }
168 | };
169 |
170 | /*************************************************************
171 | RemoveUnnecessaryVariables
172 | *************************************************************/
173 |
174 | void RemoveUnnecessaryVariables(AstExpression::Ptr node, set>& defined, set>& used)
175 | {
176 | AstExpression_RemoveUnnecessaryVariables visitor(defined, used);
177 | node->Accept(&visitor);
178 | }
179 |
180 | void RemoveUnnecessaryVariables(AstStatement::Ptr node, set>& defined, set>& used, AstStatement::Ptr& replacement)
181 | {
182 | AstStatement_RemoveUnnecessaryVariables visitor(defined, used, replacement);
183 | node->Accept(&visitor);
184 | }
185 | }
186 | }
--------------------------------------------------------------------------------
/Development/Source/Ast/TinymoeAst_RoughlyOptimize.cpp:
--------------------------------------------------------------------------------
1 | #include "TinymoeAst.h"
2 |
3 | namespace tinymoe
4 | {
5 | namespace ast
6 | {
7 | /*************************************************************
8 | AstDeclaration::RoughlyOptimize
9 | *************************************************************/
10 |
11 | class AstDeclaration_RoughlyOptimize : public AstDeclarationVisitor
12 | {
13 | public:
14 | void Visit(AstSymbolDeclaration* node)override
15 | {
16 | }
17 |
18 | void Visit(AstTypeDeclaration* node)override
19 | {
20 | }
21 |
22 | void Visit(AstFunctionDeclaration* node)override
23 | {
24 | RoughlyOptimize(node->statement, node->statement);
25 |
26 | set defined, used;
27 | CollectUsedVariables(node->statement, defined, used);
28 | RemoveUnnecessaryVariables(node->statement, defined, used, node->statement);
29 |
30 | RoughlyOptimize(node->statement, node->statement);
31 | }
32 | };
33 |
34 | /*************************************************************
35 | AstExpression::RoughlyOptimize
36 | *************************************************************/
37 |
38 | class AstExpression_RoughlyOptimize : public AstExpressionVisitor
39 | {
40 | private:
41 | AstExpression::Ptr& replacement;
42 |
43 | public:
44 | AstExpression_RoughlyOptimize(AstExpression::Ptr& _replacement)
45 | :replacement(_replacement)
46 | {
47 |
48 | }
49 |
50 | void Visit(AstLiteralExpression* node)override
51 | {
52 | }
53 |
54 | void Visit(AstIntegerExpression* node)override
55 | {
56 | }
57 |
58 | void Visit(AstFloatExpression* node)override
59 | {
60 | }
61 |
62 | void Visit(AstStringExpression* node)override
63 | {
64 | }
65 |
66 | void Visit(AstExternalSymbolExpression* node)override
67 | {
68 | }
69 |
70 | void Visit(AstReferenceExpression* node)override
71 | {
72 | }
73 |
74 | void Visit(AstNewTypeExpression* node)override
75 | {
76 | for (auto& field : node->fields)
77 | {
78 | RoughlyOptimize(field, field);
79 | }
80 | }
81 |
82 | void Visit(AstTestTypeExpression* node)override
83 | {
84 | RoughlyOptimize(node->target, node->target);
85 | }
86 |
87 | void Visit(AstNewArrayExpression* node)override
88 | {
89 | RoughlyOptimize(node->length, node->length);
90 | }
91 |
92 | void Visit(AstNewArrayLiteralExpression* node)override
93 | {
94 | for (auto& element : node->elements)
95 | {
96 | RoughlyOptimize(element, element);
97 | }
98 | }
99 |
100 | void Visit(AstArrayLengthExpression* node)override
101 | {
102 | RoughlyOptimize(node->target, node->target);
103 | }
104 |
105 | void Visit(AstArrayAccessExpression* node)override
106 | {
107 | RoughlyOptimize(node->target, node->target);
108 | RoughlyOptimize(node->index, node->index);
109 | }
110 |
111 | void Visit(AstFieldAccessExpression* node)override
112 | {
113 | RoughlyOptimize(node->target, node->target);
114 | }
115 |
116 | void Visit(AstInvokeExpression* node)override
117 | {
118 | RoughlyOptimize(node->function, node->function);
119 | for (auto& argument : node->arguments)
120 | {
121 | RoughlyOptimize(argument, argument);
122 | }
123 | }
124 |
125 | void Visit(AstLambdaExpression* node)override
126 | {
127 | shared_ptr stat;
128 | if (!(stat = dynamic_pointer_cast(node->statement)))
129 | {
130 | if (auto block = dynamic_pointer_cast(node->statement))
131 | {
132 | if (block->statements.size() == 1)
133 | {
134 | stat = dynamic_pointer_cast(block->statements[0]);
135 | }
136 | }
137 | }
138 |
139 | if (stat)
140 | {
141 | if (auto invoke = dynamic_pointer_cast(stat->expression))
142 | {
143 | if (node->arguments.size() != invoke->arguments.size())
144 | {
145 | goto FAIL_TO_OPTIMIZE;
146 | }
147 | if (auto ref = dynamic_pointer_cast(invoke->function))
148 | {
149 | auto decl = ref->reference.lock();
150 | for (auto argument : node->arguments)
151 | {
152 | if (decl == argument)
153 | {
154 | goto FAIL_TO_OPTIMIZE;
155 | }
156 | }
157 |
158 | for (int i = 0; (size_t)i < node->arguments.size(); i++)
159 | {
160 | if (auto arg = dynamic_pointer_cast(invoke->arguments[i]))
161 | {
162 | if (arg->reference.lock() != node->arguments[i])
163 | {
164 | goto FAIL_TO_OPTIMIZE;
165 | }
166 | }
167 | else
168 | {
169 | goto FAIL_TO_OPTIMIZE;
170 | }
171 | }
172 |
173 | replacement = invoke->function;
174 | return;
175 | }
176 | }
177 | }
178 |
179 | FAIL_TO_OPTIMIZE:
180 | RoughlyOptimize(node->statement, node->statement);
181 | }
182 | };
183 |
184 | /*************************************************************
185 | AstStatement::RoughlyOptimize
186 | *************************************************************/
187 |
188 | class AstStatement_RoughlyOptimize : public AstStatementVisitor
189 | {
190 | private:
191 | AstStatement::Ptr& replacement;
192 |
193 | public:
194 | AstStatement_RoughlyOptimize(AstStatement::Ptr& _replacement)
195 | :replacement(_replacement)
196 | {
197 |
198 | }
199 |
200 | void Visit(AstBlockStatement* node)override
201 | {
202 | for (auto& stat : node->statements)
203 | {
204 | RoughlyOptimize(stat, stat);
205 | }
206 |
207 | AstStatement::List stats;
208 | for (auto stat : node->statements)
209 | {
210 | ExpandBlock(stat, stats, stat == *(node->statements.end() - 1));
211 | }
212 | node->statements = std::move(stats);
213 | }
214 |
215 | void Visit(AstExpressionStatement* node)override
216 | {
217 | RoughlyOptimize(node->expression, node->expression);
218 | if (auto invoke = dynamic_pointer_cast(node->expression))
219 | {
220 | if (auto lambda = dynamic_pointer_cast(invoke->function))
221 | {
222 | auto block = make_shared();
223 | for (int i = 0; (size_t)i < lambda->arguments.size(); i++)
224 | {
225 | {
226 | auto stat = make_shared();
227 | stat->declaration = lambda->arguments[i];
228 | block->statements.push_back(stat);
229 | }
230 | {
231 | auto ref = make_shared();
232 | ref->reference = lambda->arguments[i];
233 |
234 | auto stat = make_shared();
235 | stat->target = ref;
236 | stat->value = invoke->arguments[i];
237 |
238 | block->statements.push_back(stat);
239 | }
240 | }
241 | block->statements.push_back(lambda->statement);
242 |
243 | replacement = block;
244 | goto END_OF_REPLACEMENT;
245 | }
246 | }
247 |
248 | {
249 | AstExpression::List exprs;
250 | CollectSideEffectExpressions(node->expression, exprs);
251 | if (exprs.size() == 0)
252 | {
253 | replacement = make_shared();
254 | }
255 | else if (exprs[0].get() != node->expression.get())
256 | {
257 | auto block = make_shared();
258 | for (auto expr : exprs)
259 | {
260 | auto stat = make_shared();
261 | stat->expression = expr;
262 | block->statements.push_back(stat);
263 | }
264 | replacement = block;
265 | }
266 | }
267 |
268 | END_OF_REPLACEMENT:
269 | if (replacement.get() != node)
270 | {
271 | RoughlyOptimize(replacement, replacement);
272 | }
273 | }
274 |
275 | void Visit(AstDeclarationStatement* node)override
276 | {
277 | }
278 |
279 | void Visit(AstAssignmentStatement* node)override
280 | {
281 | RoughlyOptimize(node->target, node->target);
282 | RoughlyOptimize(node->value, node->value);
283 | }
284 |
285 | void Visit(AstIfStatement* node)override
286 | {
287 | RoughlyOptimize(node->condition, node->condition);
288 | RoughlyOptimize(node->trueBranch, node->trueBranch);
289 | if (node->falseBranch)
290 | {
291 | RoughlyOptimize(node->falseBranch, node->falseBranch);
292 | }
293 | }
294 | };
295 |
296 | /*************************************************************
297 | RoughlyOptimize
298 | *************************************************************/
299 |
300 | void RoughlyOptimize(AstDeclaration::Ptr node)
301 | {
302 | AstDeclaration_RoughlyOptimize visitor;
303 | node->Accept(&visitor);
304 | }
305 |
306 | void RoughlyOptimize(AstExpression::Ptr node, AstExpression::Ptr& _replacement)
307 | {
308 | AstExpression_RoughlyOptimize visitor(_replacement);
309 | node->Accept(&visitor);
310 | }
311 |
312 | void RoughlyOptimize(AstStatement::Ptr node, AstStatement::Ptr& _replacement)
313 | {
314 | AstStatement_RoughlyOptimize visitor(_replacement);
315 | node->Accept(&visitor);
316 | }
317 |
318 | void RoughlyOptimize(AstAssembly::Ptr node)
319 | {
320 | for (auto decl : node->declarations)
321 | {
322 | RoughlyOptimize(decl);
323 | }
324 | }
325 | }
326 | }
--------------------------------------------------------------------------------
/Development/Source/Ast/TinymoeAst_SetParent.cpp:
--------------------------------------------------------------------------------
1 | #include "TinymoeAst.h"
2 |
3 | namespace tinymoe
4 | {
5 | namespace ast
6 | {
7 | /*************************************************************
8 | AstDeclaration::SetParent
9 | *************************************************************/
10 |
11 | class AstDeclaration_SetParent : public AstDeclarationVisitor
12 | {
13 | public:
14 |
15 | void Visit(AstSymbolDeclaration* node)override
16 | {
17 | }
18 |
19 | void Visit(AstTypeDeclaration* node)override
20 | {
21 | for (auto field : node->fields)
22 | {
23 | SetParent(field, node->shared_from_this());
24 | }
25 | }
26 |
27 | void Visit(AstFunctionDeclaration* node)override
28 | {
29 | if (node->ownerType)
30 | {
31 | SetParent(node->ownerType, node->shared_from_this());
32 | }
33 | for (auto argument : node->arguments)
34 | {
35 | SetParent(argument, node->shared_from_this());
36 | }
37 |
38 | SetParent(node->statement, node->shared_from_this());
39 | }
40 | };
41 |
42 | /*************************************************************
43 | AstExpression::SetParent
44 | *************************************************************/
45 |
46 | class AstExpression_SetParent : public AstExpressionVisitor
47 | {
48 | public:
49 |
50 | void Visit(AstLiteralExpression* node)override
51 | {
52 | }
53 |
54 | void Visit(AstIntegerExpression* node)override
55 | {
56 | }
57 |
58 | void Visit(AstFloatExpression* node)override
59 | {
60 | }
61 |
62 | void Visit(AstStringExpression* node)override
63 | {
64 | }
65 |
66 | void Visit(AstExternalSymbolExpression* node)override
67 | {
68 | }
69 |
70 | void Visit(AstReferenceExpression* node)override
71 | {
72 | }
73 |
74 | void Visit(AstNewTypeExpression* node)override
75 | {
76 | SetParent(node->type, node->shared_from_this());
77 | for (auto field : node->fields)
78 | {
79 | SetParent(field, node->shared_from_this());
80 | }
81 | }
82 |
83 | void Visit(AstTestTypeExpression* node)override
84 | {
85 | SetParent(node->target, node->shared_from_this());
86 | SetParent(node->type, node->shared_from_this());
87 | }
88 |
89 | void Visit(AstNewArrayExpression* node)override
90 | {
91 | SetParent(node->length, node->shared_from_this());
92 | }
93 |
94 | void Visit(AstNewArrayLiteralExpression* node)override
95 | {
96 | for (auto element : node->elements)
97 | {
98 | SetParent(element, node->shared_from_this());
99 | }
100 | }
101 |
102 | void Visit(AstArrayLengthExpression* node)override
103 | {
104 | SetParent(node->target, node->shared_from_this());
105 | }
106 |
107 | void Visit(AstArrayAccessExpression* node)override
108 | {
109 | SetParent(node->target, node->shared_from_this());
110 | SetParent(node->index, node->shared_from_this());
111 | }
112 |
113 | void Visit(AstFieldAccessExpression* node)override
114 | {
115 | SetParent(node->target, node->shared_from_this());
116 | }
117 |
118 | void Visit(AstInvokeExpression* node)override
119 | {
120 | SetParent(node->function, node->shared_from_this());
121 | for (auto argument : node->arguments)
122 | {
123 | SetParent(argument, node->shared_from_this());
124 | }
125 | }
126 |
127 | void Visit(AstLambdaExpression* node)override
128 | {
129 | for (auto argument : node->arguments)
130 | {
131 | SetParent(argument, node->shared_from_this());
132 | }
133 | SetParent(node->statement, node->shared_from_this());
134 | }
135 | };
136 |
137 | /*************************************************************
138 | AstStatement::SetParentInternal
139 | *************************************************************/
140 |
141 | class AstStatement_SetParent : public AstStatementVisitor
142 | {
143 | public:
144 |
145 | void Visit(AstBlockStatement* node)override
146 | {
147 | for (auto statement : node->statements)
148 | {
149 | SetParent(statement, node->shared_from_this());
150 | }
151 | }
152 |
153 | void Visit(AstExpressionStatement* node)override
154 | {
155 | SetParent(node->expression, node->shared_from_this());
156 | }
157 |
158 | void Visit(AstDeclarationStatement* node)override
159 | {
160 | SetParent(node->declaration, node->shared_from_this());
161 | }
162 |
163 | void Visit(AstAssignmentStatement* node)override
164 | {
165 | SetParent(node->target, node->shared_from_this());
166 | SetParent(node->value, node->shared_from_this());
167 | }
168 |
169 | void Visit(AstIfStatement* node)override
170 | {
171 | SetParent(node->condition, node->shared_from_this());
172 | SetParent(node->trueBranch, node->shared_from_this());
173 | if (node->falseBranch)
174 | {
175 | SetParent(node->falseBranch, node->shared_from_this());
176 | }
177 | }
178 | };
179 |
180 | /*************************************************************
181 | AstType::SetParent
182 | *************************************************************/
183 |
184 | class AstType_SetParent : public AstTypeVisitor
185 | {
186 | public:
187 |
188 | void Visit(AstPredefinedType* node)override
189 | {
190 | }
191 |
192 | void Visit(AstReferenceType* node)override
193 | {
194 | }
195 | };
196 |
197 | /*************************************************************
198 | AstAssembly::SetParent
199 | *************************************************************/
200 |
201 | class AstNode_SetParent : public AstVisitor
202 | {
203 | public:
204 |
205 | void Visit(AstType* node)override
206 | {
207 | AstType_SetParent visitor;
208 | node->Accept(&visitor);
209 | }
210 |
211 | void Visit(AstExpression* node)override
212 | {
213 | AstExpression_SetParent visitor;
214 | node->Accept(&visitor);
215 | }
216 |
217 | void Visit(AstStatement* node)override
218 | {
219 | AstStatement_SetParent visitor;
220 | node->Accept(&visitor);
221 | }
222 |
223 | void Visit(AstDeclaration* node)override
224 | {
225 | AstDeclaration_SetParent visitor;
226 | node->Accept(&visitor);
227 | }
228 |
229 | void Visit(AstAssembly* node)override
230 | {
231 | for (auto decl : node->declarations)
232 | {
233 | SetParent(decl, node->shared_from_this());
234 | }
235 | }
236 | };
237 |
238 | /*************************************************************
239 | SetParent
240 | *************************************************************/
241 |
242 | void SetParent(AstNode::Ptr node, AstNode::WeakPtr _parent)
243 | {
244 | ASSERT(node->parent.expired());
245 | node->parent = _parent;
246 | AstNode_SetParent visitor;
247 | node->Accept(&visitor);
248 | }
249 | }
250 | }
--------------------------------------------------------------------------------
/Development/Source/Compiler/TinymoeAstCodegen.h:
--------------------------------------------------------------------------------
1 | #ifndef VCZH_COMPILER_TINYMOEASTCODEGEN
2 | #define VCZH_COMPILER_TINYMOEASTCODEGEN
3 |
4 | #include "TinymoeStatementAnalyzer.h"
5 | #include "../Ast/TinymoeAst.h"
6 |
7 | namespace tinymoe
8 | {
9 | namespace compiler
10 | {
11 | class SymbolAstScope
12 | {
13 | public:
14 | typedef shared_ptr Ptr;
15 | typedef map SymbolAstDeclarationMap;
16 | typedef map SymbolAstFunctionDeclarationMap;
17 |
18 | SymbolAstDeclarationMap readAsts;
19 | SymbolAstDeclarationMap writeAsts;
20 | SymbolAstFunctionDeclarationMap functionPrototypes;
21 | ast::AstDeclaration::Ptr opPos, opNeg, opNot, opConcat, opAdd, opSub, opMul, opDiv, opIntDiv, opMod, opLT, opGT, opLE, opGE, opEQ, opNE, opAnd, opOr;
22 |
23 | ast::AstType::Ptr GetType(GrammarSymbol::Ptr symbol);
24 | };
25 |
26 | struct SymbolAstContext
27 | {
28 | int uniqueId = 0;
29 | ast::AstFunctionDeclaration::Ptr function;
30 | ast::AstSymbolDeclaration::Ptr continuation;
31 | GrammarSymbol::List createdVariables;
32 |
33 | string_t GetUniquePostfix();
34 | };
35 |
36 | struct SymbolAstResult
37 | {
38 | shared_ptr value;
39 | shared_ptr statement;
40 | shared_ptr continuation;
41 |
42 | SymbolAstResult();
43 | SymbolAstResult(shared_ptr _value);
44 | SymbolAstResult(shared_ptr _statement);
45 | SymbolAstResult(shared_ptr _value, shared_ptr _statement, shared_ptr _continuation);
46 |
47 | bool RequireCps()const;
48 | SymbolAstResult ReplaceValue(shared_ptr _value);
49 | SymbolAstResult ReplaceValue(shared_ptr _value, shared_ptr _continuation);
50 | void MergeForExpression(const SymbolAstResult& result, SymbolAstContext& context, vector& exprs, int& exprStart, ast::AstDeclaration::Ptr& state);
51 | static void AppendStatement(ast::AstStatement::Ptr& target, ast::AstStatement::Ptr statement);
52 | void AppendStatement(ast::AstStatement::Ptr _statement);
53 | void MergeForStatement(const SymbolAstResult& result, ast::AstDeclaration::Ptr& state);
54 | };
55 |
56 | extern ast::AstAssembly::Ptr GenerateAst(SymbolAssembly::Ptr symbolAssembly);
57 | }
58 | }
59 |
60 | #endif
--------------------------------------------------------------------------------
/Development/Source/Compiler/TinymoeAstCodegen_Declaration.cpp:
--------------------------------------------------------------------------------
1 | #include "TinymoeAstCodegen.h"
2 |
3 | using namespace tinymoe::ast;
4 |
5 | namespace tinymoe
6 | {
7 | namespace compiler
8 | {
9 |
10 | /*************************************************************
11 | Declaration::GenerateAst
12 | *************************************************************/
13 |
14 | shared_ptr SymbolDeclaration::GenerateAst(shared_ptr symbolModule)
15 | {
16 | auto ast = make_shared();
17 | ast->composedName = symbolModule->module->name->GetComposedName() + T("::") + name->GetComposedName();
18 | return ast;
19 | }
20 |
21 | shared_ptr TypeDeclaration::GenerateAst(shared_ptr symbolModule)
22 | {
23 | auto ast = make_shared();
24 | ast->composedName = symbolModule->module->name->GetComposedName() + T("::") + name->GetComposedName();
25 | for (auto field : fields)
26 | {
27 | auto astField = make_shared();
28 | astField->composedName = field->GetComposedName();
29 | ast->fields.push_back(astField);
30 | }
31 | return ast;
32 | }
33 |
34 | string_t FunctionDeclaration::GetComposedName()
35 | {
36 | string_t result;
37 | for (auto it = name.begin(); it != name.end(); it++)
38 | {
39 | result += (*it)->GetComposedName(type == FunctionDeclarationType::Phrase && (it == name.begin() || it + 1 == name.end()));
40 | if (it + 1 != name.end())
41 | {
42 | result += T("_");
43 | }
44 | }
45 | return result;
46 | }
47 |
48 | shared_ptr FunctionDeclaration::GenerateAst(shared_ptr symbolModule)
49 | {
50 | auto ast = make_shared();
51 | ast->composedName = symbolModule->module->name->GetComposedName() + T("::") + GetComposedName();
52 |
53 | {
54 | auto argument = make_shared();
55 | argument->composedName = T("$the_result");
56 | ast->resultVariable = argument;
57 | }
58 | {
59 | auto argument = make_shared();
60 | if (cps && cps->stateName)
61 | {
62 | argument->composedName = cps->stateName->GetComposedName();
63 | }
64 | else
65 | {
66 | argument->composedName = T("$state");
67 | }
68 | ast->arguments.push_back(argument);
69 | ast->stateArgument = argument;
70 | }
71 | if (category && category->signalName)
72 | {
73 | auto argument = make_shared();
74 | argument->composedName = category->signalName->GetComposedName();
75 | ast->arguments.push_back(argument);
76 | ast->signalArgument = argument;
77 | }
78 | if (bodyName)
79 | {
80 | auto argument = bodyName->CreateAst(ast).first;
81 | ast->arguments.push_back(argument);
82 | ast->blockBodyArgument = argument;
83 | }
84 |
85 | for (auto it = name.begin(); it != name.end(); it++)
86 | {
87 | auto pair = (*it)->CreateAst(ast);
88 | if (pair.first)
89 | {
90 | ast->readArgumentAstMap.insert(make_pair(it - name.begin(), ast->arguments.size()));
91 | ast->arguments.push_back(pair.first);
92 | }
93 | if (pair.second)
94 | {
95 | ast->writeArgumentAstMap.insert(make_pair(it - name.begin(), ast->arguments.size()));
96 | ast->arguments.push_back(pair.second);
97 | }
98 | }
99 |
100 | {
101 | auto argument = make_shared();
102 | if (cps && cps->continuationName)
103 | {
104 | argument->composedName = cps->continuationName->GetComposedName();
105 | }
106 | else
107 | {
108 | argument->composedName = T("$continuation");
109 | }
110 | ast->arguments.push_back(argument);
111 | ast->continuationArgument = argument;
112 | }
113 | return ast;
114 | }
115 | }
116 | }
--------------------------------------------------------------------------------
/Development/Source/Compiler/TinymoeDeclarationAnalyzer.h:
--------------------------------------------------------------------------------
1 | #ifndef VCZH_COMPILER_TINYMOEDECLARATIONANALYZER
2 | #define VCZH_COMPILER_TINYMOEDECLARATIONANALYZER
3 |
4 | #include "TinymoeLexicalAnalyzer.h"
5 |
6 | namespace tinymoe
7 | {
8 | namespace ast
9 | {
10 | class AstNode;
11 | class AstDeclaration;
12 | class AstSymbolDeclaration;
13 | }
14 |
15 | namespace compiler
16 | {
17 | class GrammarSymbol;
18 | class SymbolModule;
19 | class SymbolAstScope;
20 |
21 | /*************************************************************
22 | Function Components
23 | *************************************************************/
24 |
25 | enum class FunctionDeclarationType
26 | {
27 | Phrase, // expression, cannot be an statement
28 | Sentence, // statement
29 | Block, // block statement
30 | };
31 |
32 | enum class FunctionArgumentType
33 | {
34 | Normal, // a normal function argument
35 | List, // a tuple marshalled as array
36 | Argument, // for block only, represents an argument to the block body
37 | Expression, // for sentence and block only, represnets a re-evaluable expression
38 | Assignable, // for sentence and block only, represnets a assignable expression
39 | };
40 |
41 | class FunctionCps : public CodeFragment
42 | {
43 | public:
44 | typedef shared_ptr Ptr;
45 |
46 | SymbolName::Ptr stateName; // for accessing the CPS state object
47 | SymbolName::Ptr continuationName; // (optional) for accessing the CPS continuation function, statement only
48 |
49 | static FunctionCps::Ptr Parse(CodeFile::Ptr codeFile, CodeError::List& errors, int& lineIndex);
50 | };
51 |
52 | class FunctionCategory : public CodeFragment
53 | {
54 | public:
55 | typedef shared_ptr Ptr;
56 |
57 | SymbolName::Ptr signalName; // (optional) for non-first block (like else if, catch, etc) to access the result from the previous block
58 | SymbolName::Ptr categoryName; // (optional) category for this block
59 | SymbolName::List followCategories; // (optional) categories to follow
60 | SymbolName::List insideCategories; // (optional) categories to be contained
61 | bool closable = false; // (optional) true means this block can be the end of a block series
62 |
63 | static FunctionCategory::Ptr Parse(CodeFile::Ptr codeFile, CodeError::List& errors, int& lineIndex);
64 | };
65 |
66 | class FunctionFragment abstract : public CodeFragment
67 | {
68 | public:
69 | typedef shared_ptr Ptr;
70 | typedef vector List;
71 |
72 | CodeToken keywordToken;
73 |
74 | virtual shared_ptr CreateSymbol() = 0;
75 | virtual void AppendFunctionSymbol(shared_ptr symbol, bool primitive) = 0;
76 | virtual string_t GetComposedName(bool primitive) = 0;
77 |
78 | typedef pair, shared_ptr> AstPair;
79 | virtual AstPair CreateAst(weak_ptr parent) = 0;
80 | };
81 |
82 | /*************************************************************
83 | Declarations
84 | *************************************************************/
85 |
86 | class Declaration abstract : public CodeFragment, public enable_shared_from_this
87 | {
88 | public:
89 | typedef shared_ptr Ptr;
90 | typedef vector List;
91 |
92 | CodeToken keywordToken;
93 |
94 | virtual shared_ptr CreateSymbol(bool secondary) = 0;
95 | virtual shared_ptr GenerateAst(shared_ptr symbolModule) = 0;
96 | };
97 |
98 | class SymbolDeclaration : public Declaration
99 | {
100 | public:
101 | typedef shared_ptr Ptr;
102 |
103 | SymbolName::Ptr name;
104 |
105 | static SymbolDeclaration::Ptr Parse(CodeFile::Ptr codeFile, CodeError::List& errors, int& lineIndex);
106 |
107 | shared_ptr CreateSymbol(bool secondary)override;
108 | shared_ptr GenerateAst(shared_ptr symbolModule)override;
109 | };
110 |
111 | class TypeDeclaration : public Declaration
112 | {
113 | public:
114 | typedef shared_ptr Ptr;
115 |
116 | SymbolName::Ptr name;
117 | SymbolName::Ptr parent; // (optional)
118 | SymbolName::List fields;
119 |
120 | static TypeDeclaration::Ptr Parse(CodeFile::Ptr codeFile, CodeError::List& errors, int& lineIndex);
121 |
122 | shared_ptr CreateSymbol(bool secondary)override;
123 | shared_ptr GenerateAst(shared_ptr symbolModule)override;
124 | };
125 |
126 | class FunctionDeclaration : public Declaration
127 | {
128 | public:
129 | typedef shared_ptr Ptr;
130 |
131 | FunctionCps::Ptr cps; // (optional) for statement and block only
132 | FunctionCategory::Ptr category; // (optional) for block only
133 | FunctionDeclarationType type = FunctionDeclarationType::Phrase;
134 | FunctionFragment::Ptr bodyName; // (optional) argument for block body, block only
135 | FunctionFragment::List name; // function name and arguments
136 | SymbolName::Ptr alias; // (optional) a name that referencing this function
137 | int beginLineIndex = -1;
138 | int codeLineIndex = -1;
139 | int endLineIndex = -1;
140 |
141 | static FunctionDeclaration::Ptr Parse(CodeToken::List::iterator& it, CodeToken::List::iterator end, FunctionDeclaration::Ptr decl, CodeToken ownerToken, CodeError::List& errors);
142 | static FunctionDeclaration::Ptr Parse(CodeFile::Ptr codeFile, CodeError::List& errors, int& lineIndex);
143 |
144 | string_t GetComposedName();
145 | shared_ptr CreateSymbol(bool secondary)override;
146 | shared_ptr GenerateAst(shared_ptr symbolModule)override;
147 | };
148 |
149 | /*************************************************************
150 | Function Fragments
151 | *************************************************************/
152 |
153 | class ArgumentFragment abstract : public FunctionFragment
154 | {
155 | public:
156 | FunctionArgumentType type = FunctionArgumentType::Normal;
157 |
158 | static ArgumentFragment::Ptr Parse(CodeToken::List::iterator& it, CodeToken::List::iterator end, CodeToken ownerToken, CodeError::List& errors);
159 | };
160 |
161 | class NameFragment : public FunctionFragment
162 | {
163 | public:
164 | SymbolName::Ptr name; // part of the function name
165 |
166 | shared_ptr CreateSymbol()override;
167 | void AppendFunctionSymbol(shared_ptr symbol, bool primitive)override;
168 | string_t GetComposedName(bool primitive)override;
169 | AstPair CreateAst(weak_ptr parent)override;
170 | };
171 |
172 | class VariableArgumentFragment : public ArgumentFragment
173 | {
174 | public:
175 | FunctionArgumentType type; // type of the form
176 | SymbolName::Ptr name; // name of the argument
177 | SymbolName::Ptr receivingType; // (optional) receiving type for Normal argument only to do multiple dispatching
178 |
179 | shared_ptr CreateSymbol()override;
180 | void AppendFunctionSymbol(shared_ptr symbol, bool primitive)override;
181 | string_t GetComposedName(bool primitive)override;
182 | AstPair CreateAst(weak_ptr parent)override;
183 | };
184 |
185 | class FunctionArgumentFragment : public ArgumentFragment
186 | {
187 | public:
188 | FunctionDeclaration::Ptr declaration; // declaration for the argument representing a function
189 |
190 | shared_ptr CreateSymbol()override;
191 | void AppendFunctionSymbol(shared_ptr symbol, bool primitive)override;
192 | string_t GetComposedName(bool primitive)override;
193 | AstPair CreateAst(weak_ptr parent)override;
194 | };
195 |
196 | /*************************************************************
197 | Module
198 | *************************************************************/
199 |
200 | class Module : public CodeFragment
201 | {
202 | public:
203 | typedef shared_ptr Ptr;
204 | typedef vector List;
205 |
206 | SymbolName::Ptr name; // name of the module
207 | SymbolName::List usings; // other modules whose declarations can be referred in this module
208 | Declaration::List declarations; // declarations in this module
209 |
210 | static Module::Ptr Parse(CodeFile::Ptr codeFile, CodeError::List& errors);
211 | };
212 | }
213 | }
214 |
215 | #endif
--------------------------------------------------------------------------------
/Development/Source/Compiler/TinymoeExpressionAnalyzer.h:
--------------------------------------------------------------------------------
1 | #ifndef VCZH_COMPILER_TINYMOEEXPRESSIONANALYZER
2 | #define VCZH_COMPILER_TINYMOEEXPRESSIONANALYZER
3 |
4 | #include "TinymoeLexicalAnalyzer.h"
5 |
6 | namespace tinymoe
7 | {
8 | namespace ast
9 | {
10 | class AstNode;
11 | class AstExpression;
12 | class AstLambdaExpression;
13 | class AstDeclaration;
14 | }
15 |
16 | namespace compiler
17 | {
18 | class SymbolModule;
19 | class SymbolAstScope;
20 | struct SymbolAstContext;
21 | struct SymbolAstResult;
22 | class FunctionFragment;
23 |
24 | /*************************************************************
25 | Symbol
26 | *************************************************************/
27 |
28 | enum class GrammarFragmentType
29 | {
30 | Name, // for identifier list, e.g. [repeat with] the current number [from] 1 [to] 100
31 | Type, // for type name, e.g. set names to new [hash set]
32 | Primitive, // for primitive expression, e.g. sum from 1 to [10]
33 | Expression, // for all kinds of expressions, e.g. repeat with the current number from [1] to [100]
34 | List, // for tuple (marshalled as array), e.g. set names to collection of [("a", "b", "c")]
35 | Assignable, // for variable, or create a new symbolif the does not exist
36 | // e.g. [a variable]
37 | Argument, // always create a new symbol in the block body
38 | // e.g. repeat with [the current number] from 1 to sum from 1 to 10
39 | };
40 |
41 | class GrammarFragment
42 | {
43 | public:
44 | typedef shared_ptr Ptr;
45 | typedef vector List;
46 |
47 | GrammarFragmentType type;
48 | vector identifiers;
49 | shared_ptr functionFragment;
50 |
51 | GrammarFragment(GrammarFragmentType _type);
52 |
53 | string_t GetUniqueIdFragment();
54 | };
55 |
56 | enum class GrammarSymbolTarget
57 | {
58 | Custom, // user defined symbol
59 |
60 | Object, // (type) object
61 | Array, // (type) array
62 | Symbol, // (type) symbol
63 | Boolean, // (type) boolean
64 | Integer, // (type) integer
65 | Float, // (type) float
66 | String, // (type) string_t
67 | Function, // (type) function
68 |
69 | True, // (primitive) true
70 | False, // (primitive) false
71 | Null, // (primitive) null
72 | TheResult, // (primitive) the result
73 |
74 | Invoke, // (primitive) of
75 | InvokeContinuation, // (primitive) continuation of
76 | NewTypeOfFields, // (primitive) new of
77 | NewArray, // (primitive) new array of items
78 | GetArrayItem, // (primitive) item of array
79 | GetArrayLength, // (primitive) length of array
80 | IsType, // (primitive) is
81 | IsNotType, // (primitive) is not
82 | GetField, // (primitive) field of
83 |
84 | End, // (sentence) end
85 | Select, // (block) select
86 | Case, // (sentence) case
87 | CaseElse, // (sentence) case else
88 | RedirectTo, // (sentence) redirect to
89 | Assign, // (sentence) set to
90 | SetArrayItem, // (sentence) set item of array to
91 | SetField, // (sentence) set field of to
92 | };
93 |
94 | enum class GrammarSymbolType : int
95 | {
96 | Type = 1, //
97 | Symbol = 2, //
98 | Phrase = 4, //
99 | Sentence = 8, //
100 | Block = 16, //
101 | };
102 |
103 | class GrammarSymbol
104 | {
105 | public:
106 | typedef shared_ptr Ptr;
107 | typedef vector List;
108 | typedef multimap MultiMap;
109 |
110 | GrammarFragment::List fragments; // grammar fragments for this symbol
111 | // a statement cannot be an expression
112 | // the top invoke expression's function of a statement should reference to a statement symbol
113 | string_t uniqueId; // a string_t that identifies the grammar structure
114 | GrammarSymbolTarget target;
115 | GrammarSymbolType type;
116 |
117 | GrammarSymbol(GrammarSymbolType _type, GrammarSymbolTarget _target = GrammarSymbolTarget::Custom);
118 |
119 | void CalculateUniqueId();
120 | };
121 |
122 | GrammarSymbol::Ptr operator+(GrammarSymbol::Ptr symbol, const string_t& name);
123 | GrammarSymbol::Ptr operator+(GrammarSymbol::Ptr symbol, GrammarFragmentType type);
124 |
125 | /*************************************************************
126 | Expression
127 | *************************************************************/
128 |
129 | class Expression : public CodeFragment
130 | {
131 | public:
132 | typedef shared_ptr Ptr;
133 | typedef vector List;
134 |
135 | virtual string_t ToLog() = 0;
136 | virtual string_t ToCode() = 0;
137 | virtual void CollectNewAssignable(Expression::List& newAssignables, Expression::List& newArguments, Expression::List& modifiedAssignables) = 0;
138 | virtual SymbolAstResult GenerateAst(shared_ptr scope, SymbolAstContext& context, shared_ptr state) = 0;
139 | static shared_ptr GenerateContinuationLambdaAst(shared_ptr scope, SymbolAstContext& context, shared_ptr state);
140 | };
141 |
142 | // for numbers and strings
143 | class LiteralExpression : public Expression
144 | {
145 | public:
146 | CodeToken token;
147 |
148 | string_t ToLog()override;
149 | string_t ToCode()override;
150 | void CollectNewAssignable(Expression::List& newAssignables, Expression::List& newArguments, Expression::List& modifiedAssignables)override;
151 | SymbolAstResult GenerateAst(shared_ptr scope, SymbolAstContext& context, shared_ptr state)override;
152 | };
153 |
154 | // for new created symbols in and
155 | class ArgumentExpression : public Expression
156 | {
157 | public:
158 | SymbolName::Ptr name;
159 |
160 | string_t ToLog()override;
161 | string_t ToCode()override;
162 | void CollectNewAssignable(Expression::List& newAssignables, Expression::List& newArguments, Expression::List& modifiedAssignables)override;
163 | SymbolAstResult GenerateAst(shared_ptr scope, SymbolAstContext& context, shared_ptr state)override;
164 | };
165 |
166 | // for symbol referencing
167 | class ReferenceExpression : public Expression
168 | {
169 | public:
170 | GrammarSymbol::Ptr symbol;
171 |
172 | string_t ToLog()override;
173 | string_t ToCode()override;
174 | void CollectNewAssignable(Expression::List& newAssignables, Expression::List& newArguments, Expression::List& modifiedAssignables)override;
175 | SymbolAstResult GenerateAst(shared_ptr scope, SymbolAstContext& context, shared_ptr state)override;
176 | };
177 |
178 | // for function invoking
179 | class InvokeExpression : public Expression
180 | {
181 | public:
182 | typedef shared_ptr Ptr;
183 |
184 | Expression::Ptr function;
185 | Expression::List arguments;
186 |
187 | string_t ToLog()override;
188 | string_t ToCode()override;
189 | void CollectNewAssignable(Expression::List& newAssignables, Expression::List& newArguments, Expression::List& modifiedAssignables)override;
190 | SymbolAstResult GenerateAst(shared_ptr scope, SymbolAstContext& context, shared_ptr state)override;
191 | };
192 |
193 | // for
194 | class ListExpression : public Expression
195 | {
196 | public:
197 | Expression::List elements;
198 |
199 | string_t ToLog()override;
200 | string_t ToCode()override;
201 | void CollectNewAssignable(Expression::List& newAssignables, Expression::List& newArguments, Expression::List& modifiedAssignables)override;
202 | SymbolAstResult GenerateAst(shared_ptr scope, SymbolAstContext& context, shared_ptr state)override;
203 | };
204 |
205 | enum class UnaryOperator
206 | {
207 | Positive,
208 | Negative,
209 | Not,
210 | };
211 |
212 | // for unary operator invoking
213 | class UnaryExpression : public Expression
214 | {
215 | public:
216 | Expression::Ptr operand;
217 | UnaryOperator op;
218 |
219 | string_t ToLog()override;
220 | string_t ToCode()override;
221 | void CollectNewAssignable(Expression::List& newAssignables, Expression::List& newArguments, Expression::List& modifiedAssignables)override;
222 | SymbolAstResult GenerateAst(shared_ptr scope, SymbolAstContext& context, shared_ptr state)override;
223 | };
224 |
225 | enum class BinaryOperator
226 | {
227 | Concat,
228 | Add,
229 | Sub,
230 | Mul,
231 | Div,
232 | IntDiv,
233 | Mod,
234 | LT,
235 | GT,
236 | LE,
237 | GE,
238 | EQ,
239 | NE,
240 | And,
241 | Or,
242 | };
243 |
244 | // for binary operator invoking
245 | class BinaryExpression : public Expression
246 | {
247 | public:
248 | Expression::Ptr first;
249 | Expression::Ptr second;
250 | BinaryOperator op;
251 |
252 | string_t ToLog()override;
253 | string_t ToCode()override;
254 | void CollectNewAssignable(Expression::List& assignables, Expression::List& arguments, Expression::List& modifiedAssignables)override;
255 | SymbolAstResult GenerateAst(shared_ptr scope, SymbolAstContext& context, shared_ptr state)override;
256 | };
257 |
258 | /*************************************************************
259 | Symbol Stack
260 | *************************************************************/
261 |
262 | class GrammarStackItem
263 | {
264 | public:
265 | typedef shared_ptr Ptr;
266 | typedef vector List;
267 |
268 | GrammarSymbol::List symbols;
269 |
270 | void FillPredefinedSymbols();
271 | };
272 |
273 | class GrammarStack
274 | {
275 | public:
276 | typedef shared_ptr Ptr;
277 | typedef CodeToken::List::iterator Iterator;
278 | typedef pair ResultItem;
279 | typedef vector ResultList;
280 | typedef CodeError(GrammarStack::* ParseFunctionType)(Iterator, Iterator, ResultList&);
281 |
282 | GrammarStackItem::List stackItems; // available symbols organized in a scope based structure
283 | GrammarSymbol::MultiMap availableSymbols; // available symbols grouped by the unique identifier
284 | GrammarSymbol::Ptr resultSymbol;
285 | // the last symbol overrides all other symbols in the same group
286 |
287 | struct ExpressionLink
288 | {
289 | typedef shared_ptr Ptr;
290 |
291 | Expression::Ptr expression;
292 | Ptr previous;
293 | };
294 |
295 | void Push(GrammarStackItem::Ptr stackItem);
296 | GrammarStackItem::Ptr Pop();
297 |
298 | CodeError SuccessError();
299 | CodeError ParseToken(const string_t& token, Iterator input, Iterator end, vector& result);
300 | CodeError FoldError(CodeError error1, CodeError error2);
301 |
302 | CodeError ParseGrammarFragment(GrammarFragment::Ptr fragment, Iterator input, Iterator end, ResultList& result);
303 | CodeError ParseGrammarSymbolStep(GrammarSymbol::Ptr symbol, int fragmentIndex, ExpressionLink::Ptr previousExpression, Iterator input, Iterator end, vector>& result);
304 | CodeError ParseGrammarSymbol(GrammarSymbol::Ptr symbol, int beginFragment, ExpressionLink::Ptr previousExpression, Iterator input, Iterator end, ResultList& result);
305 | CodeError ParseGrammarSymbol(GrammarSymbol::Ptr symbol, Iterator input, Iterator end, ResultList& result);
306 |
307 | CodeError ParseType(Iterator input, Iterator end, ResultList& result); //
308 | CodeError ParseShortPrimitive(Iterator input, Iterator end, ResultList& result); // , op , (),
309 | CodeError ParsePrimitive(Iterator input, Iterator end, ResultList& result); // left recursive
310 | CodeError ParseList(Iterator input, Iterator end, ResultList& result); // (, ...)
311 | CodeError ParseAssignable(Iterator input, Iterator end, ResultList& result); // or
312 | CodeError ParseArgument(Iterator input, Iterator end, ResultList& result); //
313 |
314 | CodeError ParseBinary(Iterator input, Iterator end, ParseFunctionType parser, CodeTokenType* tokenTypes, BinaryOperator* binaryOperators, int count, ResultList& result);
315 | CodeError ParseExp1(Iterator input, Iterator end, ResultList& result); // * /
316 | CodeError ParseExp2(Iterator input, Iterator end, ResultList& result); // + -
317 | CodeError ParseExp3(Iterator input, Iterator end, ResultList& result); // &
318 | CodeError ParseExp4(Iterator input, Iterator end, ResultList& result); // < > <= >= = <>
319 | CodeError ParseExp5(Iterator input, Iterator end, ResultList& result); // and
320 | CodeError ParseExpression(Iterator input, Iterator end, ResultList& result); // or, aka.
321 |
322 | CodeError ParseStatement(Iterator input, Iterator end, ResultList& result);
323 | int CountStatementAssignables(Expression::List& assignables); // -1: illegal assignable (e.g. the assignable is a legal expression)
324 | int CountStatementAssignables(Expression::List& assignables, Expression::Ptr& illegalConvertedAssignable);
325 | };
326 | }
327 | }
328 |
329 | #endif
--------------------------------------------------------------------------------
/Development/Source/Compiler/TinymoeLexicalAnalyzer.h:
--------------------------------------------------------------------------------
1 | #ifndef VCZH_COMPILER_TINYMOELEXICALANALYZER
2 | #define VCZH_COMPILER_TINYMOELEXICALANALYZER
3 |
4 | #include "../TinymoeSTL.h"
5 |
6 | namespace tinymoe
7 | {
8 | namespace compiler
9 | {
10 | enum class CodeTokenType
11 | {
12 | Integer,
13 | Float,
14 | String,
15 | Identifier,
16 |
17 | Module, // module declaration
18 | Using, // import module declaration
19 | Phrase, // phrase declaration
20 | Sentence, // sentence declaration
21 | Block, // block declaration
22 | Symbol, // symbol declaration
23 | Type, // type declaration
24 |
25 | CPS, // continuation decoration
26 | Category, // block category definition
27 | Expression, // expression argument
28 | Argument, // argument argument
29 | Assignable, // assignable argument
30 | List, // list
31 |
32 | End, // end of an entity
33 |
34 | OpenBracket, // (
35 | CloseBracket, // )
36 | Comma, // ,
37 | Colon, // :
38 | Concat, // &
39 | Add, // +
40 | Sub, // -
41 | Mul, // *
42 | Div, // /
43 | IntDiv, // \ (can apply on floats)
44 | Mod, // %
45 | LT, // <
46 | GT, // >
47 | LE, // <=
48 | GE, // >=
49 | EQ, // =
50 | NE, // <>
51 | And, // and
52 | Or, // or
53 | Not, // not
54 |
55 | Comment, // -- xxxx
56 | Unknown,
57 | };
58 |
59 | struct CodeToken
60 | {
61 | typedef vector List;
62 |
63 | CodeTokenType type = CodeTokenType::Unknown;
64 | int row = -1;
65 | int column = -1;
66 | string_t value;
67 | int codeIndex = -1;
68 |
69 | bool IsNameFragmentToken();
70 |
71 | static string_t EscapeString(string_t value);
72 | static string_t UnescapeString(string_t str);
73 | };
74 |
75 | struct CodeError
76 | {
77 | typedef vector List;
78 |
79 | CodeToken position;
80 | string_t message;
81 | };
82 |
83 | struct CodeLine
84 | {
85 | typedef shared_ptr Ptr;
86 | typedef vector List;
87 |
88 | CodeToken::List tokens;
89 | };
90 |
91 | struct CodeFile
92 | {
93 | typedef shared_ptr Ptr;
94 | typedef vector List;
95 |
96 | CodeLine::List lines;
97 |
98 | static CodeFile::Ptr Parse(const string_t& code, int codeIndex, CodeError::List& errors);
99 | };
100 |
101 | class CodeFragment
102 | {
103 | public:
104 | CodeFragment();
105 | virtual ~CodeFragment();
106 | };
107 |
108 | class SymbolName : public CodeFragment
109 | {
110 | public:
111 | typedef shared_ptr Ptr;
112 | typedef vector List;
113 |
114 | vector identifiers;
115 |
116 | string_t GetName();
117 | string_t GetComposedName();
118 |
119 | static bool ConsumeToken(CodeToken::List::iterator& it, CodeToken::List::iterator end, CodeTokenType tokenType, const string_t& content, CodeToken ownerToken, CodeError::List& errors);
120 | static SymbolName::Ptr ParseToEnd(CodeToken::List::iterator it, CodeToken::List::iterator end, const string_t& ownerName, CodeToken ownerToken, CodeError::List& errors);
121 | static SymbolName::Ptr ParseToFarest(CodeToken::List::iterator& it, CodeToken::List::iterator end, const string_t& ownerName, CodeToken ownerToken, CodeError::List& errors);
122 | };
123 | }
124 | }
125 |
126 | #endif
127 |
--------------------------------------------------------------------------------
/Development/Source/Compiler/TinymoeStatementAnalyzer.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vczh/tinymoe/673e09e44c5dc6dedad5f802e41537c03fd044f0/Development/Source/Compiler/TinymoeStatementAnalyzer.cpp
--------------------------------------------------------------------------------
/Development/Source/Compiler/TinymoeStatementAnalyzer.h:
--------------------------------------------------------------------------------
1 | #ifndef VCZH_COMPILER_TINYMOESTATEMENTANALYZER
2 | #define VCZH_COMPILER_TINYMOESTATEMENTANALYZER
3 |
4 | #include "TinymoeDeclarationAnalyzer.h"
5 | #include "TinymoeExpressionAnalyzer.h"
6 |
7 | namespace tinymoe
8 | {
9 | namespace ast
10 | {
11 | class AstNode;
12 | class AstDeclaration;
13 | class AstSymbolDeclaration;
14 | class AstStatement;
15 | class AstExpression;
16 | }
17 |
18 | namespace compiler
19 | {
20 | class SymbolModule;
21 | class SymbolAstScope;
22 | struct SymbolAstContext;
23 | struct SymbolAstResult;
24 |
25 | /*************************************************************
26 | Statement
27 | *************************************************************/
28 |
29 | class Statement : public CodeFragment
30 | {
31 | public:
32 | typedef shared_ptr Ptr;
33 | typedef weak_ptr WeakPtr;
34 | typedef vector List;
35 | typedef map SymbolExpressionMap;
36 |
37 | CodeToken keywordToken;
38 | Statement::WeakPtr parentStatement;
39 | GrammarSymbol::Ptr statementSymbol;
40 | InvokeExpression::Ptr statementExpression;
41 | SymbolExpressionMap newVariables;
42 | SymbolExpressionMap blockArguments;
43 | Statement::List statements;
44 | bool connectToPreviousBlock = false;
45 |
46 | static SymbolAstResult GenerateExitAst(shared_ptr scope, SymbolAstContext& context, shared_ptr state);
47 | static void GenerateAssignableArgumentPairAst(shared_ptr scope, SymbolAstContext& context, shared_ptr state, shared_ptr signal, shared_ptr assignable, vector>::iterator& itvar, shared_ptr