diff --git a/Global.cs b/Global.cs index d66f85b..8795290 100644 --- a/Global.cs +++ b/Global.cs @@ -5,7 +5,9 @@ internal class Global public static List Namespaces = new List(); public static List allLoadedFiles = new(); //It is important, that allLoadedFiles and Namespaces corrospond public static List AllFunctions = new List(); - public static List CurrentlyAccessableVars = new(); + + public static List globalVars = new List(); + public static bool debugMode = false; public static int currentLine; public static List allFunctionCalls = new(); diff --git a/LangFuncHandle/InterpretMain.cs b/LangFuncHandle/InterpretMain.cs index b04fc1e..512a3ec 100644 --- a/LangFuncHandle/InterpretMain.cs +++ b/LangFuncHandle/InterpretMain.cs @@ -23,7 +23,7 @@ public static List InterpretVarDef(List commands) continue; } //Statenent is complete - if (commandLine.commands.Count != 2 && (commandLine.commands.Count != 3 && commandLine.commands[0].commandType == Command.CommandTypes.Statement && commandLine.commands[0].commandText == "link")) throw new CodeSyntaxException("Invalid VarConstruct statement.\nRight way of using it: ;"); + if (commandLine.commands.Count != 2 && commandLine.commands.Count != 3 && commandLine.commands[0].commandType == Command.CommandTypes.Statement && commandLine.commands[0].commandText == "link") throw new CodeSyntaxException("Invalid VarConstruct statement.\nRight way of using it: ;"); if (commandLine.commands.Count == 3) // Is link { if (commandLine.commands[1].commandType != Command.CommandTypes.Statement || commandLine.commands[2].commandType != Command.CommandTypes.Statement) throw new CodeSyntaxException("Invalid VarConstruct link statement.\nRight way of using it:link ;"); @@ -44,7 +44,7 @@ public static List InterpretVarDef(List commands) }); result.Add(new(varType, commandLine.commands[1].commandText.ToLower())); - + } statementMode = false; continue; @@ -182,9 +182,24 @@ public static List InterpretVarDef(List commands) thisNamespace.accessableNamespaces.Add(Global.Namespaces[Global.allLoadedFiles.FindIndex(a => ComparePaths(a, pathLocation))]); alreadyImportedNamespaces.Add(pathLocation); } + break; + case "makeglobalvar": + if ((commandLine.commands.Count != 3 && commandLine.commands.Count != 4) || commandLine.commands[1].commandType != Command.CommandTypes.Statement || commandLine.commands[2].commandType != Command.CommandTypes.Statement) throw new CodeSyntaxException("Invalid usage of makevar. Correct usage:\nmakevar ;"); + + if (!Enum.TryParse(commandLine.commands[1].commandText, true, out Value.ValueType varType) && commandLine.commands[1].commandText != "all") throw new CodeSyntaxException($"The vartype \"{commandLine.commands[1].commandText}\" doesn't exist."); + if (Statement.FindVar(commandLine.commands[2].commandText, new AccessableObjects(thisNamespace.publicNamespaceVars, new(NamespaceInfo.NamespaceIntend.@internal, "")), false) != null) throw new CodeSyntaxException($"A variable with the name \"{commandLine.commands[2].commandText}\" already exists in this context."); + Value? setToValue = null; + if (commandLine.commands.Count == 4) + { + setToValue = Statement.GetValueOfCommandLine(new CommandLine(new() { commandLine.commands[3] }, -1), new AccessableObjects(new(), new(NamespaceInfo.NamespaceIntend.nonedef, ""))); + } + if (commandLine.commands[1].commandText == "all") + thisNamespace.publicNamespaceVars.Add(new(new(VarConstruct.VarType.all, commandLine.commands[2].commandText), setToValue ?? new(varType))); + else + thisNamespace.publicNamespaceVars.Add(new(new(Value.ConvertValueTypeToVarType(varType), commandLine.commands[2].commandText), setToValue ?? new(varType))); break; default: throw new CodeSyntaxException($"\"{commandLine.commands[0].commandText}\" isn't a recognized statement in header interpret mode."); @@ -233,6 +248,15 @@ private static bool ComparePaths(string path1, string path2) public static Value? InterpretNormalMode(List commands, AccessableObjects accessableObjects) { + foreach (NamespaceInfo namespaceInfo in accessableObjects.currentNamespace.accessableNamespaces) + { + foreach (Var var in namespaceInfo.publicNamespaceVars) + { + if (accessableObjects.accessableVars.Contains(var)) continue; + if (accessableObjects.accessableVars.Any(x => x.varConstruct.name == var.varConstruct.name)) throw new CodeSyntaxException($"A global variable with the name \"{var.varConstruct.name}\" already exists. So you can't use this name again."); + accessableObjects.accessableVars.Add(var); + } + } //More or less the core of the language. It uses a Command-List and loops over every command, it then checks the command type and calls the corrosponding internal functions to the code. bool statementMode = false; Value? returnValue; diff --git a/LangFuncHandle/Statement.cs b/LangFuncHandle/Statement.cs index 6e63608..c552385 100644 --- a/LangFuncHandle/Statement.cs +++ b/LangFuncHandle/Statement.cs @@ -111,6 +111,23 @@ internal class Statement Var foundVar = FindVar(commandLine.commands[1].commandText, accessableObjects, true); foundVar.varValueHolder = new(new(foundVar.varValueHolder.value.valueType, foundVar.varValueHolder.value.ObjectValue)); return null; + case "makevar": + + if (commandLine.commands.Count != 3 || commandLine.commands[1].commandType != Command.CommandTypes.Statement || commandLine.commands[2].commandType != Command.CommandTypes.Statement) throw new CodeSyntaxException("Invalid usage of makevar. Correct usage:\nmakevar ;"); + + + + if (!Enum.TryParse(commandLine.commands[1].commandText, true, out Value.ValueType varType) && commandLine.commands[1].commandText != "all") throw new CodeSyntaxException($"The vartype \"{commandLine.commands[1].commandText}\" doesn't exist."); + if (FindVar(commandLine.commands[2].commandText, accessableObjects, false) != null) throw new CodeSyntaxException($"A variable with the name \"{commandLine.commands[2].commandText}\" already exists in this context."); + if (commandLine.commands[1].commandText == "all") + { + accessableObjects.accessableVars.Add(new(new(VarConstruct.VarType.all, commandLine.commands[2].commandText), new(varType))); + return null; + } + accessableObjects.accessableVars.Add(new(new(Value.ConvertValueTypeToVarType(varType), commandLine.commands[2].commandText), new(varType))); + return null; + + @@ -127,7 +144,7 @@ public static Value GetValueOfCommandLine(CommandLine commandLine, Value.ValueTy FunctionCall functionCall = commandLine.commands[0].functionCall ?? throw new InternalInterpreterException("Internal: function call was not converted to a function call."); if (commandLine.commands.Count != 1) //There shouldnt be anything after a function call throw new CodeSyntaxException($"Unexpected {commandLine.commands[1].commandType} after functioncall."); - if ( functionCall.callFunction.returnType != Value.ConvertValueTypeToVarType(expectedType)) //Find out if function returns desired type + if (functionCall.callFunction.returnType != Value.ConvertValueTypeToVarType(expectedType)) //Find out if function returns desired type throw new CodeSyntaxException($"The function {functionCall.callFunction.functionLocation} does not return the expected {expectedType} type."); return functionCall.DoFunctionCall(accessableObjects); @@ -206,7 +223,7 @@ private static void StaticStatementSet(CommandLine commandLine, AccessableObject if (correctVar == null) throw new CodeSyntaxException($"The variable {commandLine.commands[1].commandText} cant be found."); correctVar.VarValue = GetValueOfCommandLine(new CommandLine(commandLine.commands.GetRange(2, commandLine.commands.Count - 2), commandLine.lineIDX), accessableObjects); } - public static Var? FindVar(string name, AccessableObjects accessableObjects, bool failAtNotFind = false) + public static Var? FindVar(string name, AccessableObjects accessableObjects, bool failAtNotFind = false) { name = name.ToLower(); foreach (Var var in accessableObjects.accessableVars) //Search for variable @@ -233,7 +250,7 @@ public static Value ReturnStatement(List commands, AccessableObjects ac case "true": if (commands.Count != 1) throw new CodeSyntaxException($"Unexpected {commands[1].commandType}"); - + return new(Value.ValueType.@bool, true); case "false": if (commands.Count != 1) throw new CodeSyntaxException($"Unexpected {commands[1].commandType}"); @@ -247,7 +264,7 @@ public static Value ReturnStatement(List commands, AccessableObjects ac return new(); case "nl": - return new (Value.ValueType.@string, "\n"); + return new(Value.ValueType.@string, "\n"); case "lineChar": return new(Value.ValueType.@string, "Ⅼ"); @@ -277,7 +294,8 @@ public static Value ReturnStatement(List commands, AccessableObjects ac returnValueFromVar = new(foundLinkableVar.VarValue); returnValueFromVar.comesFromVarValue = foundLinkableVar; return returnValueFromVar; - + + @@ -286,7 +304,7 @@ public static Value ReturnStatement(List commands, AccessableObjects ac default: // Is probably var - + if (commands.Count != 1) throw new CodeSyntaxException($"Unexpected syntax after varname \"{commands[0].commandText}\"."); commands[0].commandText = commands[0].commandText.ToLower(); foreach (Var var in accessableObjects.accessableVars) @@ -295,7 +313,7 @@ public static Value ReturnStatement(List commands, AccessableObjects ac return new(var.VarValue); } - + //Var not found diff --git a/Objects/VarClasses/Var.cs b/Objects/VarClasses/Var.cs index 13c34b8..e864d65 100644 --- a/Objects/VarClasses/Var.cs +++ b/Objects/VarClasses/Var.cs @@ -12,8 +12,13 @@ public class Var public Var(VarConstruct varConstruct, Value varValue) { this.varConstruct = varConstruct; + + + this.varValueHolder = new(varValue); + if (Value.ConvertValueTypeToVarType(VarValue.valueType) != varConstruct.type && varConstruct.type != VarConstruct.VarType.all) throw new CodeSyntaxException($"The variable \"{varConstruct.name}\" can't be initialized with a {varValue.valueType}-type value, because it's a {varConstruct.type}-type variable."); + } public Value VarValue diff --git a/README.md b/README.md index e212a91..d634a6d 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,9 @@ set stringValue2 "Hello World!"; #Set both variables to "Hello World!" - unlink The unlink statement can unlink two previusly linked variables. Both will keep their previusly shared value, but it will be uncoppled. Here's the usage: - ```unlink ;``` +- makevar + The makevar statement can create a variable. It's used like this: + - ```makeVar ;``` ### Return statements: @@ -302,6 +305,10 @@ set seed [HeaderExampleLibrary.ReturnRandomValue:seed]; }; }; ``` +- makeglobalvar: + This statement will create a global variable, that can be used everywehere in your project (So you don't need to inport a namespace, to access its global variable (I still gotta implement that)). + Here is how you build the statement: ```makeGlobalVar ;``` or ```makeGlobalVar ;``` + ## var def interpreter mode This is just another interpreter mode just like header mode, just with some different rules. Its only purpose is to define a list of variables and it only has one statement type. The statement is built up like this: