Evaluate char arrays and 'disp'
This commit is contained in:
		
							parent
							
								
									886b897a4c
								
							
						
					
					
						commit
						0529e87d43
					
				
							
								
								
									
										10
									
								
								Parser/EvaluationScope.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Parser/EvaluationScope.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| using Parser.Objects; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| namespace Parser | ||||
| { | ||||
|     internal class EvaluationScope | ||||
|     { | ||||
|         public Dictionary<string, MObject> Variables { get; } = new Dictionary<string, MObject>(); | ||||
|     } | ||||
| } | ||||
| @ -4,14 +4,10 @@ using Parser.Objects; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.Immutable; | ||||
| using System.Linq; | ||||
| 
 | ||||
| namespace Parser | ||||
| { | ||||
|     internal class EvaluationScope | ||||
|     { | ||||
|         public Dictionary<string, MObject> Variables { get; } = new Dictionary<string, MObject>(); | ||||
|     } | ||||
| 
 | ||||
|     internal class Evaluator | ||||
|     { | ||||
|         private readonly SyntaxTree _syntaxTree; | ||||
| @ -218,7 +214,59 @@ namespace Parser | ||||
| 
 | ||||
|         private MObject? EvaluateFunctionCall(FunctionCallExpressionSyntaxNode expression) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|             var arguments = new List<MObject>(); | ||||
|             var nodes = expression.Nodes.Where(n => n.IsNode).Select(n => (ExpressionSyntaxNode)n.AsNode()!); | ||||
|             var allGood = true; | ||||
|             foreach (var node in nodes) | ||||
|             { | ||||
|                 var argument = EvaluateExpression(node); | ||||
|                 if (argument is null) | ||||
|                 { | ||||
|                     _diagnostics.ReportCannotEvaluateExpression( | ||||
|                         new TextSpan(node.Position, node.FullWidth)); | ||||
|                     allGood = false; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     arguments.Add(argument); | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
|             if (!allGood) | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
| 
 | ||||
|             var function = GetFunctionSymbol(expression.FunctionName); | ||||
|             if (function.Name == "disp") | ||||
|             { | ||||
|                 return EvaluateDisp(arguments); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 throw new NotImplementedException("Functions are not supported."); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private MObject? EvaluateDisp(List<MObject> arguments) | ||||
|         { | ||||
|             if (arguments.Count != 1) | ||||
|             { | ||||
|                 throw new NotImplementedException($"Cannot evaluate disp() with {arguments.Count} arguments."); | ||||
|             } | ||||
| 
 | ||||
|             Console.WriteLine(arguments[0]); | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         private FunctionSymbol GetFunctionSymbol(ExpressionSyntaxNode functionName) | ||||
|         { | ||||
|             if (functionName.Kind == TokenKind.IdentifierNameExpression) | ||||
|             { | ||||
|                 return new FunctionSymbol(((IdentifierNameExpressionSyntaxNode)functionName).Text); | ||||
|             } | ||||
| 
 | ||||
|             throw new NotImplementedException($"Unknown function symbol '{functionName.Text}'."); | ||||
|         } | ||||
| 
 | ||||
|         private MObject? EvaluateCellArrayElementAccess(CellArrayElementAccessExpressionSyntaxNode expression) | ||||
| @ -248,7 +296,11 @@ namespace Parser | ||||
| 
 | ||||
|         private MObject? EvaluateStringLiteralExpression(StringLiteralSyntaxNode expression) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|             return expression.StringToken.Value switch | ||||
|             { | ||||
|                 string s => MObject.CreateCharArray(s.ToCharArray()), | ||||
|                 _ => null, | ||||
|             }; | ||||
|         } | ||||
| 
 | ||||
|         private MObject? EvaluateNumberLiteralExpression(NumberLiteralSyntaxNode expression) | ||||
|  | ||||
							
								
								
									
										12
									
								
								Parser/FunctionSymbol.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								Parser/FunctionSymbol.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| namespace Parser | ||||
| { | ||||
|     internal class FunctionSymbol | ||||
|     { | ||||
|         public string Name { get; } | ||||
| 
 | ||||
|         public FunctionSymbol(string name) | ||||
|         { | ||||
|             Name = name; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										22
									
								
								Parser/Objects/MCharArray.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Parser/Objects/MCharArray.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| namespace Parser.Objects | ||||
| { | ||||
|     public class MCharArray : MObject | ||||
|     { | ||||
|         private MCharArray(char[] chars) | ||||
|         { | ||||
|             Chars = chars; | ||||
|         } | ||||
| 
 | ||||
|         public char[] Chars { get; } | ||||
| 
 | ||||
|         public static MCharArray Create(char[] chars) | ||||
|         { | ||||
|             return new MCharArray(chars); | ||||
|         } | ||||
| 
 | ||||
|         public override string ToString() | ||||
|         { | ||||
|             return new string(Chars); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -6,5 +6,10 @@ | ||||
|         { | ||||
|             return MDoubleNumber.Create(value); | ||||
|         } | ||||
| 
 | ||||
|         public static MCharArray CreateCharArray(char[] chars) | ||||
|         { | ||||
|             return MCharArray.Create(chars); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -21,7 +21,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Repl", "Repl\Repl.csproj", "{8FEDFE5D-3320-418F-88A6-09C1B51C4441}" | ||||
| EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MApplication", "MApplication\MApplication.csproj", "{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}" | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MApplication", "MApplication\MApplication.csproj", "{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}" | ||||
| EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cmi", "cmi\cmi.csproj", "{C2447F0B-733D-4755-A104-5B82E24D3F47}" | ||||
| EndProject | ||||
| Global | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| @ -57,6 +59,10 @@ Global | ||||
| 		{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 		{C2447F0B-733D-4755-A104-5B82E24D3F47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||
| 		{C2447F0B-733D-4755-A104-5B82E24D3F47}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{C2447F0B-733D-4755-A104-5B82E24D3F47}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{C2447F0B-733D-4755-A104-5B82E24D3F47}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(SolutionProperties) = preSolution | ||||
| 		HideSolutionNode = FALSE | ||||
|  | ||||
							
								
								
									
										47
									
								
								cmi/Program.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								cmi/Program.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
| using Parser; | ||||
| using System; | ||||
| using System.IO; | ||||
| 
 | ||||
| namespace cmi | ||||
| { | ||||
|     class Program | ||||
|     { | ||||
|         static void Main(string[] args) | ||||
|         { | ||||
|             if (args.Length != 1) | ||||
|             { | ||||
|                 Console.Error.WriteLine("Usage: cmi <file.m>"); | ||||
|             } | ||||
| 
 | ||||
|             var fileName = args[0]; | ||||
|             var text = File.ReadAllText(fileName); | ||||
|             var tree = SyntaxTree.Parse(text); | ||||
|             var compilation = Compilation.Create(tree); | ||||
|             if (tree.Diagnostics.Diagnostics.Count > 0) | ||||
|             { | ||||
|                 foreach (var diagnostic in tree.Diagnostics.Diagnostics) | ||||
|                 { | ||||
|                     Console.ForegroundColor = ConsoleColor.DarkRed; | ||||
|                     Console.WriteLine($"{diagnostic.Span}: {diagnostic.Message}"); | ||||
|                     Console.ResetColor(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             var context = new CompilationContext(); | ||||
|             var evaluationResult = compilation.Evaluate(context); | ||||
| 
 | ||||
|             foreach (var diagnostic in evaluationResult.Diagnostics) | ||||
|             { | ||||
|                 Console.ForegroundColor = ConsoleColor.DarkRed; | ||||
|                 Console.WriteLine($"{diagnostic.Span}: {diagnostic.Message}"); | ||||
|                 Console.ResetColor(); | ||||
|             } | ||||
| 
 | ||||
|             var result = evaluationResult.Value?.ToString(); | ||||
|             if (result is not null) | ||||
|             { | ||||
|                 Console.WriteLine(result); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										14
									
								
								cmi/cmi.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								cmi/cmi.csproj
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
| 
 | ||||
|   <PropertyGroup> | ||||
|     <OutputType>Exe</OutputType> | ||||
|     <TargetFramework>net5.0</TargetFramework> | ||||
|     <Nullable>enable</Nullable> | ||||
|     <LangVersion>preview</LangVersion> | ||||
|   </PropertyGroup> | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\Parser\Parser.csproj" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
| </Project> | ||||
							
								
								
									
										3
									
								
								examples/helloworld/hello.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								examples/helloworld/hello.m
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| x = 1; | ||||
| disp(x + 2); | ||||
| disp('Hello world!'); | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user