diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9e4b172
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+
+.vs
diff --git a/Compiler.sln b/Compiler.sln
new file mode 100644
index 0000000..06860a7
--- /dev/null
+++ b/Compiler.sln
@@ -0,0 +1,17 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Compiler", "LineParser\Compiler.csproj", "{C58A9D4D-2F9B-405D-BE58-27163A50CF5F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C58A9D4D-2F9B-405D-BE58-27163A50CF5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C58A9D4D-2F9B-405D-BE58-27163A50CF5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C58A9D4D-2F9B-405D-BE58-27163A50CF5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C58A9D4D-2F9B-405D-BE58-27163A50CF5F}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/LineParser/Compiler.csproj b/LineParser/Compiler.csproj
new file mode 100644
index 0000000..9a4fa03
--- /dev/null
+++ b/LineParser/Compiler.csproj
@@ -0,0 +1,185 @@
+
+
+
+ Debug
+ AnyCPU
+ {C58A9D4D-2F9B-405D-BE58-27163A50CF5F}
+ Library
+ LineParser
+ LineParser
+ v3.5
+ 8.0.30703
+ 2.0
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+
+
+ full
+ true
+ bin\Release
+ prompt
+ 4
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LineParser/Compiler.csproj.user b/LineParser/Compiler.csproj.user
new file mode 100644
index 0000000..6cbe588
--- /dev/null
+++ b/LineParser/Compiler.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ ProjectFiles
+
+
\ No newline at end of file
diff --git a/LineParser/Compiler.sln b/LineParser/Compiler.sln
new file mode 100644
index 0000000..11e1040
--- /dev/null
+++ b/LineParser/Compiler.sln
@@ -0,0 +1,17 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Compiler", "Compiler.csproj", "{C58A9D4D-2F9B-405D-BE58-27163A50CF5F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C58A9D4D-2F9B-405D-BE58-27163A50CF5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C58A9D4D-2F9B-405D-BE58-27163A50CF5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C58A9D4D-2F9B-405D-BE58-27163A50CF5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C58A9D4D-2F9B-405D-BE58-27163A50CF5F}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/LineParser/Compiler.userprefs b/LineParser/Compiler.userprefs
new file mode 100644
index 0000000..b1d3b7a
--- /dev/null
+++ b/LineParser/Compiler.userprefs
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LineParser/ErrorHandler/ErrorMessage.cs b/LineParser/ErrorHandler/ErrorMessage.cs
new file mode 100644
index 0000000..a7bcec2
--- /dev/null
+++ b/LineParser/ErrorHandler/ErrorMessage.cs
@@ -0,0 +1,58 @@
+using System;
+using Runtime;
+
+namespace ErrorHandler
+{
+
+ public class ErrorMessage
+ {
+ public static Action errorMessageMethod;
+ internal static Language currentLanguage;
+
+ internal static void sendErrorMessage(int lineNumber, string message){
+ errorMessageMethod.Invoke (lineNumber, message);
+ }
+
+ [System.Obsolete("Use new sendErrorMessage() instead.", true)]
+ internal static void sendErrorMessage(int lineNumber, ErrorType theErrorType, int index, string[] args){
+ //string message = currentLanguage.getErrorMessage (theErrorType, index, args);
+ string message = "Message sent via old system...";
+ sendErrorMessage (lineNumber, message);
+ }
+
+ #region test
+ internal static void sendErrorMessage(int lineNumber, ErrorType errorType, string specificError, string[] args){
+ string message = currentLanguage.getErrorMessage (errorType, specificError, args);
+ sendErrorMessage (lineNumber, message);
+ }
+ #endregion
+
+ public static void setLanguage(){
+ currentLanguage = new SwedishLanguage ();
+ IErrorSender theSender = (currentLanguage as IErrorSender);
+
+ IfStatementErrors ifError = theSender.ifStatementErrors;
+ ElseStatementErrors elseError = theSender.elseStatementErrors;
+ ForLoopErrors forError = theSender.forLoopErrors;
+ IndentationErrors indentError = theSender.indentErrors;
+ TextErrors txtError = theSender.textErrors;
+ VariableErrors varError = theSender.variableErrors;
+
+ WhileLoopErrors whileError = theSender.whileLoopErrors;
+ NumberErrors numError = theSender.numberErrors;
+ KeywordErrors keywordError = theSender.keywordErrors;
+ FunctionErrors funcError = theSender.functionErrors;
+ OtherErrors otherError = theSender.otherErrors;
+ SystemFailureErrors systemErrors = theSender.systemErrors;
+
+ currentLanguage.initLanguageErrors1 (ifError, elseError, forError, indentError, txtError, varError);
+ currentLanguage.initLanguageErrors2 (whileError, numError, keywordError, funcError, otherError, systemErrors);
+ }
+
+ public static void setErrorMethod(Action errorMethod){
+ errorMessageMethod = errorMethod;
+ }
+
+ }
+}
+
diff --git a/LineParser/ErrorHandler/ErrorType.cs b/LineParser/ErrorHandler/ErrorType.cs
new file mode 100644
index 0000000..27e2f45
--- /dev/null
+++ b/LineParser/ErrorHandler/ErrorType.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum ErrorType
+ {
+ ForLoop,
+ WhileLoop,
+ Variable,
+ Function,
+ IfStatements,
+ ElseStatements,
+ Expression,
+ Indentation,
+ Text,
+ Number,
+ Keyword,
+ Other,
+ System
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/ElseError/ElseErrorType.cs b/LineParser/ErrorHandler/Errors/ElseError/ElseErrorType.cs
new file mode 100644
index 0000000..34735cc
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/ElseError/ElseErrorType.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum ElseErrorType
+ {
+ missingIndentOperator,
+ unknownFormat,
+ missingIfBeforeElse,
+ elseCantLinkToElse
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/ElseError/ElseStatementErrors.cs b/LineParser/ErrorHandler/Errors/ElseError/ElseStatementErrors.cs
new file mode 100644
index 0000000..1c8b381
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/ElseError/ElseStatementErrors.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+ public interface ElseStatementErrors
+ {
+ string missingIndentOperator (string[] arg);
+ string unknownFormat (string[] arg);
+ string missingIfBeforeElse (string[] arg);
+ string elseCantLinkToElse (string[] arg);
+ }
+
+
+ public class ElseErrorsOrder
+ {
+ public static Dictionary> getMessages(ElseStatementErrors theLogicOrder){
+ Dictionary> messages = new Dictionary> ();
+
+ messages.Add (ElseErrorType.missingIndentOperator.ToString(), theLogicOrder.missingIndentOperator);
+ messages.Add (ElseErrorType.unknownFormat.ToString(), theLogicOrder.unknownFormat);
+ messages.Add (ElseErrorType.missingIfBeforeElse.ToString(), theLogicOrder.missingIfBeforeElse);
+ messages.Add (ElseErrorType.elseCantLinkToElse.ToString(), theLogicOrder.elseCantLinkToElse);
+
+ return messages;
+ }
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/Error.cs b/LineParser/ErrorHandler/Errors/Error.cs
new file mode 100644
index 0000000..553f13a
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/Error.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+ public class Error
+ {
+ private ForLoopErrorType forType;
+ private TextErrorType textType;
+
+ public Error (TextErrorType eType)
+ {
+ textType = eType;
+ }
+
+ public Error (ForLoopErrorType eType)
+ {
+ forType = eType;
+ }
+
+ /*public Error (TextErrorType eType)
+ {
+ errorType = eType;
+ }*/
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/ForLoopError/ForLoopErrorType.cs b/LineParser/ErrorHandler/Errors/ForLoopError/ForLoopErrorType.cs
new file mode 100644
index 0000000..19c5840
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/ForLoopError/ForLoopErrorType.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum ForLoopErrorType {
+ missingIndentOperator,
+ unknownFormat,
+ expectVariableAt2,
+ expectInAt3,
+ expectRangeAt4,
+ rangeArgumentEmpty,
+ rangeArgumentNotNumber,
+ rangeMissingParenthesis,
+ counterVariableIsNotNumber
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/ForLoopError/ForLoopErrors.cs b/LineParser/ErrorHandler/Errors/ForLoopError/ForLoopErrors.cs
new file mode 100644
index 0000000..39c4d37
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/ForLoopError/ForLoopErrors.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+ public interface ForLoopErrors
+ {
+ string missingIndentOperator (string[] arg);
+ string unknownFormat (string[] arg);
+ string expectVariableAt2 (string[] arg);
+ string expectInAt3 (string[] arg);
+ string expectRangeAt4 (string[] arg);
+ string rangeArgumentEmpty (string[] arg);
+ string rangeArgumentNotNumber (string[] arg);
+ string rangeMissingParenthesis (string[] arg);
+ string counterVariableIsNotNumber (string[] arg);
+ }
+
+
+
+ public class ForErrorsOrder
+ {
+ [System.Obsolete("Use getMessages() instead", true)]
+ public static Func[] getStatements(ForLoopErrors theLogicOrder){
+ List> statements = new List> ();
+
+ statements.Add (theLogicOrder.missingIndentOperator);
+ statements.Add (theLogicOrder.unknownFormat);
+ statements.Add (theLogicOrder.expectVariableAt2);
+ statements.Add (theLogicOrder.expectInAt3);
+ statements.Add (theLogicOrder.expectRangeAt4);
+ statements.Add (theLogicOrder.rangeArgumentEmpty);
+ statements.Add (theLogicOrder.rangeArgumentNotNumber);
+ statements.Add (theLogicOrder.rangeMissingParenthesis);
+ statements.Add (theLogicOrder.counterVariableIsNotNumber);
+
+ return statements.ToArray ();
+ }
+
+ #region test
+
+ public static Dictionary> getMessages(ForLoopErrors theLogicOrder){
+ Dictionary> messages = new Dictionary> ();
+
+ messages.Add (ForLoopErrorType.missingIndentOperator.ToString(), theLogicOrder.missingIndentOperator);
+ messages.Add (ForLoopErrorType.unknownFormat.ToString(), theLogicOrder.unknownFormat);
+ messages.Add (ForLoopErrorType.expectVariableAt2.ToString(), theLogicOrder.expectVariableAt2);
+ messages.Add (ForLoopErrorType.expectInAt3.ToString(), theLogicOrder.expectInAt3);
+ messages.Add (ForLoopErrorType.expectRangeAt4.ToString(), theLogicOrder.expectRangeAt4);
+ messages.Add (ForLoopErrorType.rangeArgumentEmpty.ToString(), theLogicOrder.rangeArgumentEmpty);
+ messages.Add (ForLoopErrorType.rangeArgumentNotNumber.ToString(), theLogicOrder.rangeArgumentNotNumber);
+ messages.Add (ForLoopErrorType.rangeMissingParenthesis.ToString(), theLogicOrder.rangeMissingParenthesis);
+ messages.Add (ForLoopErrorType.counterVariableIsNotNumber.ToString(), theLogicOrder.counterVariableIsNotNumber);
+
+ return messages;
+ }
+
+ #endregion
+
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/FunctionError/FunctionErrorType.cs b/LineParser/ErrorHandler/Errors/FunctionError/FunctionErrorType.cs
new file mode 100644
index 0000000..f44e7ae
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/FunctionError/FunctionErrorType.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum FunctionErrorType
+ {
+ cantReturnFromMainScope
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/FunctionError/FunctionErrors.cs b/LineParser/ErrorHandler/Errors/FunctionError/FunctionErrors.cs
new file mode 100644
index 0000000..0530278
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/FunctionError/FunctionErrors.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+ public interface FunctionErrors
+ {
+ string cantReturnFromMainScope (string[] arg);
+ }
+
+
+ public class FunctionErrorsOrder
+ {
+
+ public static Dictionary> getMessages(FunctionErrors theLogicOrder){
+ Dictionary> messages = new Dictionary> ();
+
+ messages.Add (FunctionErrorType.cantReturnFromMainScope.ToString(), theLogicOrder.cantReturnFromMainScope);
+
+ return messages;
+ }
+ }
+}
\ No newline at end of file
diff --git a/LineParser/ErrorHandler/Errors/IfAndElifError/IfErrorType.cs b/LineParser/ErrorHandler/Errors/IfAndElifError/IfErrorType.cs
new file mode 100644
index 0000000..ae51bd4
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/IfAndElifError/IfErrorType.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum IfErrorType
+ {
+ missingIndentOperator,
+ unknownFormat,
+ expressionNotCorrectType
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/IfAndElifError/IfStatementErrors.cs b/LineParser/ErrorHandler/Errors/IfAndElifError/IfStatementErrors.cs
new file mode 100644
index 0000000..a91adc4
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/IfAndElifError/IfStatementErrors.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+
+ public interface IfStatementErrors
+ {
+ string missingIndentOperator (string[] arg);
+ string unknownFormat (string[] arg);
+ string expressionNotCorrectType (string[] arg);
+ }
+
+
+ public class IfErrorsOrder
+ {
+ public static Dictionary> getMessages(IfStatementErrors theLogicOrder){
+ Dictionary> messages = new Dictionary> ();
+
+ messages.Add (IfErrorType.missingIndentOperator.ToString(), theLogicOrder.missingIndentOperator);
+ messages.Add (IfErrorType.unknownFormat.ToString(), theLogicOrder.unknownFormat);
+ messages.Add (IfErrorType.expressionNotCorrectType.ToString(), theLogicOrder.expressionNotCorrectType);
+
+ return messages;
+ }
+ }
+
+
+}
+
diff --git a/LineParser/ErrorHandler/Errors/IndentationError/IndentationErrorType.cs b/LineParser/ErrorHandler/Errors/IndentationError/IndentationErrorType.cs
new file mode 100644
index 0000000..056361a
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/IndentationError/IndentationErrorType.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum IndentationErrorType
+ {
+ unknownIndentStarter,
+ firstLineIndentError,
+ indentationError,
+ expectingBodyAfterScopeStarter
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/IndentationError/IndentationErrors.cs b/LineParser/ErrorHandler/Errors/IndentationError/IndentationErrors.cs
new file mode 100644
index 0000000..990a36a
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/IndentationError/IndentationErrors.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+ public interface IndentationErrors
+ {
+ string unknownIndentStarter (string[] arg);
+ string firstLineIndentError (string[] arg);
+ string indentationError (string[] arg);
+ string expectingBodyAfterScopeStarter (string[] arg);
+
+ }
+
+
+ public class IndentationErrorsOrder
+ {
+ public static Dictionary> getMessages(IndentationErrors theLogicOrder)
+ {
+ Dictionary> messages = new Dictionary> ();
+
+ messages.Add (IndentationErrorType.unknownIndentStarter.ToString(), theLogicOrder.unknownIndentStarter);
+ messages.Add (IndentationErrorType.firstLineIndentError.ToString(), theLogicOrder.firstLineIndentError);
+ messages.Add (IndentationErrorType.indentationError.ToString(), theLogicOrder.indentationError);
+ messages.Add (IndentationErrorType.expectingBodyAfterScopeStarter.ToString(), theLogicOrder.expectingBodyAfterScopeStarter);
+
+ return messages;
+ }
+ }
+}
+
+
diff --git a/LineParser/ErrorHandler/Errors/KeywordError/KeywordErrorType.cs b/LineParser/ErrorHandler/Errors/KeywordError/KeywordErrorType.cs
new file mode 100644
index 0000000..fdf63f6
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/KeywordError/KeywordErrorType.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum KeywordErrorType
+ {
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/KeywordError/KeywordErrors.cs b/LineParser/ErrorHandler/Errors/KeywordError/KeywordErrors.cs
new file mode 100644
index 0000000..f413568
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/KeywordError/KeywordErrors.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+ public interface KeywordErrors
+ {
+ //string speciallDeclerationNeedsDeclaredVariable (string[] arg);
+ }
+
+
+ public class KeywordErrorsOrder
+ {
+
+ public static Dictionary> getMessages(KeywordErrors theLogicOrder){
+ Dictionary> messages = new Dictionary> ();
+
+ //messages.Add (KeywordErrorType.speciallDeclerationNeedsDeclaredVariable.ToString(), theLogicOrder.speciallDeclerationNeedsDeclaredVariable);
+
+ return messages;
+ }
+ }
+}
\ No newline at end of file
diff --git a/LineParser/ErrorHandler/Errors/NumberError/NumberErrorType.cs b/LineParser/ErrorHandler/Errors/NumberError/NumberErrorType.cs
new file mode 100644
index 0000000..15b0922
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/NumberError/NumberErrorType.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum NumberErrorType
+ {
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/NumberError/NumberErrors.cs b/LineParser/ErrorHandler/Errors/NumberError/NumberErrors.cs
new file mode 100644
index 0000000..36282e5
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/NumberError/NumberErrors.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+ public interface NumberErrors
+ {
+ //string speciallDeclerationNeedsDeclaredVariable (string[] arg);
+ }
+
+
+ public class NumberErrorsOrder
+ {
+
+ public static Dictionary> getMessages(NumberErrors theLogicOrder){
+ Dictionary> messages = new Dictionary> ();
+
+ //messages.Add (NumberErrorType.speciallDeclerationNeedsDeclaredVariable.ToString(), theLogicOrder.speciallDeclerationNeedsDeclaredVariable);
+
+ return messages;
+ }
+ }
+}
\ No newline at end of file
diff --git a/LineParser/ErrorHandler/Errors/OtherError/OtherErrorType.cs b/LineParser/ErrorHandler/Errors/OtherError/OtherErrorType.cs
new file mode 100644
index 0000000..9f3216f
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/OtherError/OtherErrorType.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum OtherErrorType
+ {
+ //corruptAndOrStatement
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/OtherError/OtherErrors.cs b/LineParser/ErrorHandler/Errors/OtherError/OtherErrors.cs
new file mode 100644
index 0000000..74893e7
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/OtherError/OtherErrors.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+ public interface OtherErrors
+ {
+ //string corruptAndOrStatement (string[] arg);
+ }
+
+
+ public class OtherErrorsOrder
+ {
+
+ public static Dictionary> getMessages(OtherErrors theLogicOrder){
+ Dictionary> messages = new Dictionary> ();
+
+ //messages.Add (OtherErrorType.corruptAndOrStatement.ToString(), theLogicOrder.corruptAndOrStatement);
+
+ return messages;
+ }
+ }
+}
\ No newline at end of file
diff --git a/LineParser/ErrorHandler/Errors/SystemFailureError/SystemFailureErrorType.cs b/LineParser/ErrorHandler/Errors/SystemFailureError/SystemFailureErrorType.cs
new file mode 100644
index 0000000..dd0bbb1
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/SystemFailureError/SystemFailureErrorType.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum SystemFailureErrorType
+ {
+ corruptAndOrStatement,
+ textParsingMalfunction,
+ possibleComparissonStatements,
+ unknownLogic,
+ scopeParsingMalfunction,
+ addOrChangeUnsupportedVariableType
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/SystemFailureError/SystemFailureErrors.cs b/LineParser/ErrorHandler/Errors/SystemFailureError/SystemFailureErrors.cs
new file mode 100644
index 0000000..3667d8a
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/SystemFailureError/SystemFailureErrors.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+ public interface SystemFailureErrors
+ {
+ string corruptAndOrStatement (string[] arg);
+ string textParsingMalfunction (string[] arg);
+ string possibleComparissonStatements (string[] arg);
+ string unknownLogic (string[] arg);
+ string scopeParsingMalfunction (string[] arg);
+ string addOrChangeUnsupportedVariableType (string[] arg);
+ }
+
+ public class SystemFailureErrorsOrder
+ {
+ public static Dictionary> getMessages(SystemFailureErrors theLogicOrder){
+ Dictionary> messages = new Dictionary> ();
+
+ messages.Add (SystemFailureErrorType.corruptAndOrStatement.ToString(), theLogicOrder.corruptAndOrStatement);
+ messages.Add (SystemFailureErrorType.textParsingMalfunction.ToString(), theLogicOrder.textParsingMalfunction);
+ messages.Add (SystemFailureErrorType.possibleComparissonStatements.ToString(), theLogicOrder.possibleComparissonStatements);
+ messages.Add (SystemFailureErrorType.unknownLogic.ToString(), theLogicOrder.unknownLogic);
+ messages.Add (SystemFailureErrorType.scopeParsingMalfunction.ToString(), theLogicOrder.scopeParsingMalfunction);
+ messages.Add (SystemFailureErrorType.addOrChangeUnsupportedVariableType.ToString(), theLogicOrder.addOrChangeUnsupportedVariableType);
+
+ return messages;
+ }
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/TextError/TextErrorType.cs b/LineParser/ErrorHandler/Errors/TextError/TextErrorType.cs
new file mode 100644
index 0000000..4e0efed
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/TextError/TextErrorType.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum TextErrorType
+ {
+ expectedPlusSignBetweenStrings,
+ expectedATextValue,
+ expressionNeedsToEndWithAString
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/TextError/TextErrors.cs b/LineParser/ErrorHandler/Errors/TextError/TextErrors.cs
new file mode 100644
index 0000000..a199b3d
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/TextError/TextErrors.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+ public interface TextErrors
+ {
+ string expectedPlusSignBetweenStrings(string[] arg);
+ string expectedATextValue(string[] arg);
+ string expressionNeedsToEndWithAString(string[] arg);
+ }
+
+
+ public class TextErrorsOrder
+ {
+ public static Dictionary> getMessages(TextErrors theLogicOrder){
+ Dictionary> messages = new Dictionary> ();
+
+ messages.Add (TextErrorType.expectedPlusSignBetweenStrings.ToString(), theLogicOrder.expectedPlusSignBetweenStrings);
+ messages.Add (TextErrorType.expectedATextValue.ToString(), theLogicOrder.expectedATextValue);
+ messages.Add (TextErrorType.expressionNeedsToEndWithAString.ToString(), theLogicOrder.expressionNeedsToEndWithAString);
+
+ return messages;
+ }
+ }
+}
+
+
diff --git a/LineParser/ErrorHandler/Errors/VariableError/VariableErrorType.cs b/LineParser/ErrorHandler/Errors/VariableError/VariableErrorType.cs
new file mode 100644
index 0000000..52cc041
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/VariableError/VariableErrorType.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum VariableErrorType
+ {
+ speciallDeclerationNeedsDeclaredVariable
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/VariableError/VariableErrors.cs b/LineParser/ErrorHandler/Errors/VariableError/VariableErrors.cs
new file mode 100644
index 0000000..3572ca2
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/VariableError/VariableErrors.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+ public interface VariableErrors
+ {
+ string speciallDeclerationNeedsDeclaredVariable (string[] arg);
+ }
+
+
+ public class VariableErrorsOrder
+ {
+ [System.Obsolete("Use getMessages() instead", true)]
+ public static Func[] getStatements(VariableErrors theLogicOrder){
+ List> statements = new List> ();
+
+ statements.Add (theLogicOrder.speciallDeclerationNeedsDeclaredVariable);
+
+
+ return statements.ToArray ();
+ }
+
+ public static Dictionary> getMessages(VariableErrors theLogicOrder){
+ Dictionary> messages = new Dictionary> ();
+
+ messages.Add (VariableErrorType.speciallDeclerationNeedsDeclaredVariable.ToString(), theLogicOrder.speciallDeclerationNeedsDeclaredVariable);
+
+ return messages;
+ }
+ }
+}
\ No newline at end of file
diff --git a/LineParser/ErrorHandler/Errors/WhileLoopError/WhileErrorType.cs b/LineParser/ErrorHandler/Errors/WhileLoopError/WhileErrorType.cs
new file mode 100644
index 0000000..286ac20
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/WhileLoopError/WhileErrorType.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace ErrorHandler
+{
+ public enum WhileErrorType
+ {
+ missingIndentOperator,
+ unknownFormat
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Errors/WhileLoopError/WhileLoopErrors.cs b/LineParser/ErrorHandler/Errors/WhileLoopError/WhileLoopErrors.cs
new file mode 100644
index 0000000..86fb22b
--- /dev/null
+++ b/LineParser/ErrorHandler/Errors/WhileLoopError/WhileLoopErrors.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+
+namespace ErrorHandler
+{
+ public interface WhileLoopErrors
+ {
+ string missingIndentOperator (string[] arg);
+ string unknownFormat (string[] arg);
+
+ }
+
+
+ public class WhileErrorsOrder
+ {
+ [System.Obsolete("Use getMessages() instead", true)]
+ public static Func[] getStatements(WhileLoopErrors theLogicOrder){
+ List> statements = new List> ();
+
+ statements.Add (theLogicOrder.missingIndentOperator);
+ statements.Add (theLogicOrder.unknownFormat);
+
+
+ return statements.ToArray ();
+ }
+
+ public static Dictionary> getMessages(WhileLoopErrors theLogicOrder){
+ Dictionary> messages = new Dictionary> ();
+
+ messages.Add (WhileErrorType.missingIndentOperator.ToString(), theLogicOrder.missingIndentOperator);
+ messages.Add (WhileErrorType.unknownFormat.ToString(), theLogicOrder.unknownFormat);
+
+ return messages;
+ }
+ }
+}
+
diff --git a/LineParser/ErrorHandler/IErrorSender.cs b/LineParser/ErrorHandler/IErrorSender.cs
new file mode 100644
index 0000000..cc740d5
--- /dev/null
+++ b/LineParser/ErrorHandler/IErrorSender.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace ErrorHandler
+{
+ public interface IErrorSender {
+
+ string getErrorMessage(ErrorType theErrorType, string theSpecificError, string[] args);
+ void initLanguageErrors1(IfStatementErrors If, ElseStatementErrors Else, ForLoopErrors For, IndentationErrors Indent, TextErrors Text, VariableErrors Variable);
+ void initLanguageErrors2(WhileLoopErrors While, NumberErrors Number, KeywordErrors Keyword, FunctionErrors Function, OtherErrors Other, SystemFailureErrors System);
+
+ IfStatementErrors ifStatementErrors{ get; }
+ ElseStatementErrors elseStatementErrors{ get; }
+ ForLoopErrors forLoopErrors { get; }
+ IndentationErrors indentErrors{ get; }
+ TextErrors textErrors { get; }
+ VariableErrors variableErrors { get; }
+
+ WhileLoopErrors whileLoopErrors{ get; }
+ NumberErrors numberErrors { get; }
+ KeywordErrors keywordErrors { get; }
+ FunctionErrors functionErrors { get; }
+ OtherErrors otherErrors { get; }
+ SystemFailureErrors systemErrors { get; }
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/LanguagePrefab/Language.cs b/LineParser/ErrorHandler/Languages/LanguagePrefab/Language.cs
new file mode 100644
index 0000000..4944a48
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/LanguagePrefab/Language.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Runtime;
+
+namespace ErrorHandler
+{
+
+ public abstract class Language{
+
+
+ public string notFoundStatement = "Unknown Error Statement!";
+
+ private Dictionary>> errorMessages = new Dictionary>> ();
+
+
+ /// Inits first part of the language errors. Stores error messages in dictionary.
+ public void initLanguageErrors1(IfStatementErrors If, ElseStatementErrors Else, ForLoopErrors For, IndentationErrors Indent, TextErrors Text, VariableErrors Variable){
+ errorMessages.Add (ErrorType.IfStatements, IfErrorsOrder.getMessages (If));
+ errorMessages.Add (ErrorType.ElseStatements, ElseErrorsOrder.getMessages (Else));
+ errorMessages.Add (ErrorType.ForLoop, ForErrorsOrder.getMessages (For));
+ errorMessages.Add (ErrorType.Indentation, IndentationErrorsOrder.getMessages (Indent));
+ errorMessages.Add (ErrorType.Text, TextErrorsOrder.getMessages (Text));
+ errorMessages.Add (ErrorType.Variable, VariableErrorsOrder.getMessages (Variable));
+ }
+
+ /// Inits second part of the language errors. Stores error messages in dictionary.
+ public void initLanguageErrors2(WhileLoopErrors While, NumberErrors Number, KeywordErrors Keyword, FunctionErrors Function, OtherErrors Other, SystemFailureErrors system) {
+ errorMessages.Add (ErrorType.WhileLoop, WhileErrorsOrder.getMessages (While));
+ errorMessages.Add (ErrorType.Number, NumberErrorsOrder.getMessages (Number));
+ errorMessages.Add (ErrorType.Keyword, KeywordErrorsOrder.getMessages (Keyword));
+ errorMessages.Add (ErrorType.Function, FunctionErrorsOrder.getMessages (Function));
+ errorMessages.Add (ErrorType.Other, OtherErrorsOrder.getMessages (Other));
+ errorMessages.Add (ErrorType.System, SystemFailureErrorsOrder.getMessages (system));
+ }
+
+
+ /// Returns a specific error message. Second parameter must be of specific error type (e.g. ForLoopErrorType) and converted to string.
+ public string getErrorMessage(ErrorType theErrorType, string theSpecificError, string[] args){
+
+ if (errorMessages.ContainsKey (theErrorType)){
+ if (errorMessages [theErrorType].ContainsKey (theSpecificError))
+ return errorMessages [theErrorType] [theSpecificError].Invoke (args);
+ }
+
+ return notFoundStatement;
+
+ }
+
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishErrorTexts/AndraFel.cs b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/AndraFel.cs
new file mode 100644
index 0000000..d4f0fcc
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/AndraFel.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace ErrorHandler
+{
+ public class AndraFel : OtherErrors
+ {
+ #region Errors from SyntaxCheck
+
+ /*public string missingIndentOperator (string[] arg)
+ {
+ return "Det saknas ett \":\" i slutet av din Else sats";
+ }*/
+
+ #endregion
+
+
+
+ #region Errors from Runtime
+
+ #endregion
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishErrorTexts/ElseSatserFel.cs b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/ElseSatserFel.cs
new file mode 100644
index 0000000..ae0a13d
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/ElseSatserFel.cs
@@ -0,0 +1,44 @@
+using System;
+
+namespace ErrorHandler
+{
+ public class ElseSatserFel : ElseStatementErrors
+ {
+ #region Errors from SyntaxCheck
+
+ public string missingIndentOperator (string[] arg)
+ {
+ return "Det saknas ett \":\" i slutet av din Else sats";
+ }
+
+ /// Called if the else statement is not composed of only 2 parts.
+ /// An else statement should only look like "else:"
+ public string unknownFormat (string[] arg)
+ {
+ return "Okänt format i din Else sats. Kom ihåg att else ser ut såhär: \"else:\"";
+ }
+
+
+ /// Missing if before else so link can not be setup
+ public string missingIfBeforeElse (string[] arg)
+ {
+ return "Else måste vara länkat till en If-sats";
+ }
+
+ /// Called if there is two else after each other
+ public string elseCantLinkToElse (string[] arg)
+ {
+ return "Else måste komma direkt efter en If-sats. Kan inte kopplas till en annan else";
+ }
+
+ #endregion
+
+
+
+ #region Errors from Runtime
+
+ #endregion
+
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishErrorTexts/ForLoopFel.cs b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/ForLoopFel.cs
new file mode 100644
index 0000000..ba71ced
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/ForLoopFel.cs
@@ -0,0 +1,70 @@
+using System;
+
+namespace ErrorHandler
+{
+ public class ForLoopFel : ForLoopErrors
+ {
+
+ #region Errors from SyntaxCheck
+ /// Missings the indent operator ":".
+ public string missingIndentOperator (string[] args)
+ {
+ return "Det saknas ett \":\" i slutet av din for-slinga";
+ }
+
+ /// Weird format on for loop. E.g. more than 5 or less than 4 words.
+ public string unknownFormat (string[] args)
+ {
+ return "Okänt format på for-slingan. Kom ihåg att den ska likna: \"for i in range(5):\"";
+ }
+
+ /// Expects a index variable (e.g. i) as word number 2.
+ public string expectVariableAt2 (string[] args)
+ {
+ return "I en for-slinga förväntas det andra ordet att vara en variabel (till exempel: i)";
+ }
+
+ /// Expects the keyword "in" as word number 3.
+ public string expectInAt3 (string[] args)
+ {
+ return "I en for-slinga förväntas det tredje ordet att vara \"in\"";
+ }
+
+ /// Expects the keyword "range" as word number 4. This must be redefined if lists are introduced
+ public string expectRangeAt4 (string[] args)
+ {
+ return "I en for-slinga förväntas det fjärde ordet att vara \"range\"";
+ }
+
+ #endregion
+
+
+
+ #region Errors from Runtime
+ /// Expects atleast on number between parenthesis to range().
+ public string rangeArgumentEmpty (string[] args)
+ {
+ return "Det måste finnas minst en siffra mellan parenteserna till \"range()\"";
+ }
+
+ /// Expects the argsuments to range() to be numbers.
+ public string rangeArgumentNotNumber (string[] args)
+ {
+ return "Det får bara vara siffor mellan parenteserna till \"range()\"";
+ }
+
+ /// Expects the keyword "range" to be followed by parenthesis.
+ public string rangeMissingParenthesis (string[] args)
+ {
+ return "Det saknas parenteser till \"range()\"";
+ }
+
+ public string counterVariableIsNotNumber (string[] args)
+ {
+ return "Din räknevariabel " + args[0] + " måste vara en siffra";
+ }
+
+ #endregion
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishErrorTexts/FunktionFel.cs b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/FunktionFel.cs
new file mode 100644
index 0000000..ecb1a3e
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/FunktionFel.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace ErrorHandler
+{
+ public class FunktionFel : FunctionErrors
+ {
+ #region Errors from SyntaxCheck
+
+
+ #endregion
+
+
+
+ #region Errors from Runtime
+
+ /// Called if there is a return statement in the main scope
+ public string cantReturnFromMainScope (string[] arg)
+ {
+ return "Du kan inte använda return utanför en funktion";
+ }
+
+ #endregion
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishErrorTexts/IfSatserFel.cs b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/IfSatserFel.cs
new file mode 100644
index 0000000..b0c9d2f
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/IfSatserFel.cs
@@ -0,0 +1,35 @@
+using System;
+namespace ErrorHandler
+{
+ public class IfSatserFel : IfStatementErrors
+ {
+
+ #region Errors from SyntaxCheck
+
+ public string missingIndentOperator (string[] arg)
+ {
+ return "Det saknas ett \":\" i slutet av din if-sats";
+ }
+
+ public string unknownFormat (string[] arg)
+ {
+ return "Okänt format i din if-sats. Kom ihåg att en if-sats ska likna: \"if jämförelse:\"";
+ }
+
+
+ #endregion
+
+
+
+ #region Errors from Runtime
+ /// Called when expression type is not bool, number, string nor None.
+ /// The expression in if-statement needs to evaluate to True or False.
+ public string expressionNotCorrectType (string[] arg)
+ {
+ return "Uttrycket i en if-sats måste vara True (Sant) eller False (Falskt)";
+ }
+
+ #endregion
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishErrorTexts/IndenteringsFel.cs b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/IndenteringsFel.cs
new file mode 100644
index 0000000..e75a743
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/IndenteringsFel.cs
@@ -0,0 +1,42 @@
+using System;
+
+namespace ErrorHandler
+{
+ public class IndenteringsFel : IndentationErrors
+ {
+ #region Errors from SyntaxCheck
+
+ /// Called if there is an indentation without a scope starter (eg if, while) before
+ public string unknownIndentStarter (string[] arg)
+ {
+ return "Okänd start på indentering";
+ }
+
+ /// Called if first line is not at indentation level 0
+ public string firstLineIndentError (string[] arg)
+ {
+ return "Första raden i programmet måste alltid vara längst till vänster.";
+ }
+
+ /// Called if there is a indentation error like missing to indent after if declaration or indenting too much
+ public string indentationError (string[] arg)
+ {
+ return "Tabb-fel, koden måste vara rätt antal steg (tabb) in från kanten.";
+ }
+
+ /// Called if there is no more lines of code after a scope starter (e.g. if, while)
+ public string expectingBodyAfterScopeStarter (string[] arg)
+ {
+ return "Förväntar sig indenterad kod efter den här raden";
+ }
+
+ #endregion
+
+
+
+ #region Errors from Runtime
+
+ #endregion
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishErrorTexts/KeywordFel.cs b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/KeywordFel.cs
new file mode 100644
index 0000000..051eb4b
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/KeywordFel.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace ErrorHandler
+{
+ public class KeywordFel : KeywordErrors
+ {
+ #region Errors from SyntaxCheck
+
+ /*public string missingIndentOperator (string[] arg)
+ {
+ return "Det saknas ett \":\" i slutet av din Else sats";
+ }*/
+
+ #endregion
+
+
+
+ #region Errors from Runtime
+
+ #endregion
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishErrorTexts/NummerFel.cs b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/NummerFel.cs
new file mode 100644
index 0000000..850bc5b
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/NummerFel.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace ErrorHandler
+{
+ public class NummerFel : NumberErrors
+ {
+ #region Errors from SyntaxCheck
+
+ /*public string missingIndentOperator (string[] arg)
+ {
+ return "Det saknas ett \":\" i slutet av din Else sats";
+ }*/
+
+ #endregion
+
+
+
+ #region Errors from Runtime
+
+ #endregion
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishErrorTexts/SystemFel.cs b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/SystemFel.cs
new file mode 100644
index 0000000..e6d8150
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/SystemFel.cs
@@ -0,0 +1,51 @@
+using System;
+
+namespace ErrorHandler
+{
+ public class SystemFel : SystemFailureErrors
+ {
+ #region Errors from SyntaxCheck
+
+ /// Called if something goes wrong in the logic when parsing. A unique error code is added to know where it got triggered
+ public string unknownLogic (string[] arg)
+ {
+ return "Förstår inte koden. Försök igen! (" + arg[0] + ")";
+ }
+
+ /// Called if something goes wrong with the parsing of scopes
+ public string scopeParsingMalfunction (string[] arg)
+ {
+ return "Något gick fel vid parsing av scopes";
+ }
+
+ #endregion
+
+
+
+ #region Errors from Runtime
+ /// Called if (startIndex < logicOrder.Length && endIndex < logicOrder.Length) == true
+ /// Error could be caused by corrupt And/Or statement
+ public string corruptAndOrStatement (string[] arg)
+ {
+ return "Något är fel vid And/Or";
+ }
+
+ public string textParsingMalfunction (string[] arg)
+ {
+ return "Något gick galet med text-parsingen";
+ }
+
+ /// Called if parsing of a comparion in if statement fails and does not return other error
+ public string possibleComparissonStatements (string[] arg)
+ {
+ return "Okänt format av jämförelsen i if-satsen";
+ }
+
+ // Called if the variableType is not supported (eg unknown, unsigned)
+ public string addOrChangeUnsupportedVariableType(string[] arg){
+ return "Typen av data du försöker lägga in i variabeln stöds inte i detta moment";
+ }
+ #endregion
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishErrorTexts/TextFel.cs b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/TextFel.cs
new file mode 100644
index 0000000..ff17a95
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/TextFel.cs
@@ -0,0 +1,34 @@
+using System;
+
+namespace ErrorHandler
+{
+ public class TextFel : TextErrors
+ {
+ #region Errors from SyntaxCheck
+
+ /// Should this error really exist? You can add strings to eachother without + in Python
+ public string expectedPlusSignBetweenStrings (string[] arg)
+ {
+ return "Det förväntas vara ett \"+\" mellan textsträngarna";
+ }
+
+
+
+ #endregion
+
+
+
+ #region Errors from Runtime
+ public string expectedATextValue (string[] arg)
+ {
+ return "Det förväntades ett text värde";
+ }
+
+ public string expressionNeedsToEndWithAString (string[] arg)
+ {
+ return "Utrycket måste avslutas med en text";
+ }
+ #endregion
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishErrorTexts/VariabelFel.cs b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/VariabelFel.cs
new file mode 100644
index 0000000..32e7ba4
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/VariabelFel.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace ErrorHandler
+{
+ public class VariabelFel : VariableErrors
+ {
+ #region Errors from SyntaxCheck
+
+ #endregion
+
+
+
+ #region Errors from Runtime
+ public string speciallDeclerationNeedsDeclaredVariable (string[] arg)
+ {
+ return "För att använda specialtilldelning, så måste variabeln först vara deklarerad";
+ }
+
+ #endregion
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishErrorTexts/WhileLoopFel.cs b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/WhileLoopFel.cs
new file mode 100644
index 0000000..4acbda4
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishErrorTexts/WhileLoopFel.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace ErrorHandler
+{
+ public class WhileLoopFel : WhileLoopErrors
+ {
+ #region Errors from SyntaxCheck
+
+ public string missingIndentOperator (string[] arg)
+ {
+ return "Det saknas ett \":\" i slutet av din While loop";
+ }
+
+ public string unknownFormat (string[] arg)
+ {
+ return "Okänt format i din While loop";
+ }
+
+ #endregion
+
+
+
+ #region Errors from Runtime
+
+ #endregion
+ }
+}
+
diff --git a/LineParser/ErrorHandler/Languages/SwedishLanguage.cs b/LineParser/ErrorHandler/Languages/SwedishLanguage.cs
new file mode 100644
index 0000000..84f555d
--- /dev/null
+++ b/LineParser/ErrorHandler/Languages/SwedishLanguage.cs
@@ -0,0 +1,59 @@
+using System;
+
+namespace ErrorHandler
+{
+ public class SwedishLanguage : Language, IErrorSender
+ {
+
+ public IfStatementErrors ifStatementErrors {
+ get {return new IfSatserFel ();}
+ }
+
+ public ElseStatementErrors elseStatementErrors {
+ get {return new ElseSatserFel ();}
+ }
+
+ public ForLoopErrors forLoopErrors {
+ get {return new ForLoopFel (); }
+ }
+
+ public IndentationErrors indentErrors {
+ get {return new IndenteringsFel ();}
+ }
+
+ public TextErrors textErrors {
+ get {return new TextFel();}
+ }
+
+ public VariableErrors variableErrors {
+ get {return new VariabelFel ();}
+ }
+
+
+
+ public WhileLoopErrors whileLoopErrors {
+ get {return new WhileLoopFel ();}
+ }
+
+ public NumberErrors numberErrors {
+ get {return new NummerFel ();}
+ }
+
+ public KeywordErrors keywordErrors {
+ get {return new KeywordFel ();}
+ }
+
+ public FunctionErrors functionErrors {
+ get {return new FunktionFel ();}
+ }
+
+ public OtherErrors otherErrors {
+ get {return new AndraFel ();}
+ }
+
+ public SystemFailureErrors systemErrors {
+ get {return new SystemFel ();}
+ }
+ }
+}
+
diff --git a/LineParser/ErrorHandler/LevenshteinDist.cs b/LineParser/ErrorHandler/LevenshteinDist.cs
new file mode 100644
index 0000000..f1fc92e
--- /dev/null
+++ b/LineParser/ErrorHandler/LevenshteinDist.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Runtime;
+
+namespace Compiler
+{
+ public class LevenshteinDist
+ {
+ private static int variableMaxDist = 2;
+
+ public static void checkForClosesVariable(string notFoundName, int lineNumber, Scope currentScope){
+ List results = new List ();
+
+ foreach (Variable v in currentScope.scopeVariables.variableList)
+ if (v.name != notFoundName)
+ results.Add (new LeveshteinResult(CalcEditDist (notFoundName, v.name), v.name));
+
+ results = results.OrderBy (x => x.dist).ToList ();
+
+
+ if (results.Count > 0 && results [0].dist <= variableMaxDist)
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, string.Format("Hittar inte variabeln \"{0}\" i minnet.\nMenade du \"{1}\"?", notFoundName, results[0].word));
+ }
+
+ public static void checkForClosesFunctions(string notFoundName, List savedFunctions, int lineNumber) {
+ List results = new List();
+
+ foreach (Function function in savedFunctions)
+ if (function.name != notFoundName)
+ results.Add(new LeveshteinResult(CalcEditDist(notFoundName, function.name), function.name));
+
+ results = results.OrderBy(x => x.dist).ToList();
+
+
+ if (results.Count > 0 && results[0].dist <= variableMaxDist)
+ ErrorHandler.ErrorMessage.sendErrorMessage(lineNumber, string.Format("Hittar ingen funktion med namn \"{0}\".\nMenade du \"{1}\"?", notFoundName, results[0].word));
+ }
+
+ private class LeveshteinResult{
+ public int dist;
+ public string word;
+
+ public LeveshteinResult(int dist, string word){
+ this.dist = dist;
+ this.word = word;
+ }
+ }
+
+
+ /// Compute the distance between two strings.
+ public static int CalcEditDist(string s, string t)
+ {
+ int n = s.Length;
+ int m = t.Length;
+ int[,] d = new int[n + 1, m + 1];
+
+ // Step 1
+ if (n == 0)
+ return m;
+
+ if (m == 0)
+ return n;
+
+ // Step 2
+ for (int i = 0; i <= n; d[i, 0] = i++)
+ {
+ }
+
+ for (int j = 0; j <= m; d[0, j] = j++)
+ {
+ }
+
+ // Step 3
+ for (int i = 1; i <= n; i++)
+ {
+ //Step 4
+ for (int j = 1; j <= m; j++)
+ {
+ // Step 5
+ int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
+
+ // Step 6
+ d[i, j] = Math.Min(
+ Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
+ d[i - 1, j - 1] + cost);
+ }
+ }
+ // Step 7
+ return d[n, m];
+ }
+ }
+}
+
diff --git a/LineParser/Functions/BuiltInFunctions/FunctionRange.cs b/LineParser/Functions/BuiltInFunctions/FunctionRange.cs
new file mode 100644
index 0000000..4df3792
--- /dev/null
+++ b/LineParser/Functions/BuiltInFunctions/FunctionRange.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using Compiler;
+
+namespace Compiler
+{
+ internal class FunctionRange : Function {
+
+ public FunctionRange(){
+ base.name = "range";
+ base.hasReturnVariable = false;
+ base.inputParameterAmount.Add (1);
+ base.inputParameterAmount.Add (2);
+ base.inputParameterAmount.Add (3);
+ base.pauseWalker = false;
+ }
+
+
+
+
+ #region implemented abstract members of Function
+ public override Variable runFunction (Scope currentScope, Variable[] inputParas, int lineNumber)
+ {
+ throw new System.NotImplementedException ();
+ }
+ #endregion
+ }
+
+}
+
diff --git a/LineParser/Functions/BuiltInFunctions/GameFunctions.cs b/LineParser/Functions/BuiltInFunctions/GameFunctions.cs
new file mode 100644
index 0000000..99298c2
--- /dev/null
+++ b/LineParser/Functions/BuiltInFunctions/GameFunctions.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+
+namespace Compiler
+{
+ public class GameFunctions
+ {
+ internal static List gameFunctions;
+
+ public static void setGameFunctions(List inputList){
+ gameFunctions = inputList;
+ }
+ }
+}
+
diff --git a/LineParser/Functions/BuiltInFunctions/PreBuiltFunctionList.cs b/LineParser/Functions/BuiltInFunctions/PreBuiltFunctionList.cs
new file mode 100644
index 0000000..d85ddd5
--- /dev/null
+++ b/LineParser/Functions/BuiltInFunctions/PreBuiltFunctionList.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Compiler
+{
+ internal class PreBuiltFunctionList
+ {
+ internal static Function[] pythonFunctions = {new FunctionRange()};
+ }
+}
+
diff --git a/LineParser/Functions/CurrentFunctions.cs b/LineParser/Functions/CurrentFunctions.cs
new file mode 100644
index 0000000..e7a1184
--- /dev/null
+++ b/LineParser/Functions/CurrentFunctions.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+
+namespace Compiler
+{
+
+ public class CurrentFunctions
+ {
+ public List savedFunctions = new List();
+
+ public CurrentFunctions(){
+ foreach (Function f in PreBuiltFunctionList.pythonFunctions)
+ addFunction (f);
+ foreach (Function f in GameFunctions.gameFunctions)
+ addFunction (f);
+ }
+
+
+ public Function getSavedFunction(string searchedFunction, int lineNumber){
+ for (int i = 0; i < savedFunctions.Count; i++)
+ if (savedFunctions [i].name == searchedFunction)
+ return savedFunctions [i];
+
+ LevenshteinDist.checkForClosesFunctions(searchedFunction, savedFunctions, lineNumber);
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, "Hittar ingen funktion med namn \"" + searchedFunction + "\".");
+ return null;
+ }
+
+ public bool doesFunctionExist(string searchedFunction){
+ foreach(Function f in savedFunctions)
+ if (f.name == searchedFunction)
+ return true;
+
+ return false;
+ }
+
+
+ public void addFunction(Function newFunc){
+ for (int i = savedFunctions.Count-1; i >= 0; i--)
+ if (savedFunctions [i].name == newFunc.name)
+ savedFunctions.RemoveAt (i);
+
+ savedFunctions.Add (newFunc);
+ }
+
+
+ public List getShallowCopy(){
+ Function[] tempArray = savedFunctions.ToArray ();
+ Function[] shallow = (Function[])tempArray.Clone ();
+ List returnList = new List ();
+ returnList.AddRange (shallow);
+ return returnList;
+ }
+ }
+}
+
diff --git a/LineParser/Functions/Function.cs b/LineParser/Functions/Function.cs
new file mode 100644
index 0000000..c97f705
--- /dev/null
+++ b/LineParser/Functions/Function.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+
+namespace Compiler
+{
+ public abstract class Function{
+
+ public string name;
+ public string buttonText;
+ public bool hasReturnVariable;
+ public bool pauseWalker;
+ public List inputParameterAmount = new List();
+ public string[] inputParameterNames = new string[10];
+ public Scope functionScope;
+ public bool isUserFunction = false;
+
+
+ public abstract Variable runFunction (Scope currentScope, Variable[] inputParas, int lineNumber);
+ }
+
+}
+
diff --git a/LineParser/Functions/FunctionParser.cs b/LineParser/Functions/FunctionParser.cs
new file mode 100644
index 0000000..74f9cda
--- /dev/null
+++ b/LineParser/Functions/FunctionParser.cs
@@ -0,0 +1,176 @@
+using System;
+using ErrorHandler;
+using System.Collections.Generic;
+using Runtime;
+
+namespace Compiler
+{
+ public class FunctionParser{
+
+ public static Logic parseIntoFunctionCall(string word, int lineNumber, Scope currentScope){
+ string funcName = getFunctionName (word, lineNumber);
+ string funcPara = getFunctionInParameter (word, lineNumber);
+
+ return new FunctionCall (word, funcName, PackageUnWrapper.removeSurrondingParanteser(funcPara), null);
+ }
+
+
+ public static void linkFunctionCall(FunctionCall theFuncCall, int lineNumber, Scope currentScope){
+
+ Function searchedFunc = currentScope.scopeFunctions.getSavedFunction (theFuncCall.name, lineNumber);
+ if (searchedFunc != null){
+ validParameters (theFuncCall.parameter, searchedFunc, lineNumber, currentScope);
+
+ if (theFuncCall.returnCalculations != null)
+ theFuncCall.inputVariables = parseInputVariables (theFuncCall.returnCalculations, lineNumber, theFuncCall.targetFunc, currentScope);
+ else
+ theFuncCall.inputVariables = getValueOfParameters (theFuncCall.parameter, theFuncCall.targetFunc, lineNumber, currentScope, theFuncCall);
+
+ //for (int i = 0; i < theFuncCall.inputVariables.Length; i++) {
+ // Print.print (theFuncCall.inputVariables [i].name + " : " + theFuncCall.inputVariables [i].getNumber ().ToString ());
+ //}
+
+
+ theFuncCall.lineNumber = lineNumber;
+ theFuncCall.targetFunc = searchedFunc;
+ theFuncCall.name = searchedFunc.name;
+ }
+
+ }
+
+
+ public static string getFunctionName(string functionWord, int lineNumber){
+ for (int i = 0; i < functionWord.Length; i++)
+ if (functionWord [i] == '(')
+ return functionWord.Substring (0, i);
+
+ ErrorMessage.sendErrorMessage (lineNumber, "Funktions anrop saknar en \"(\"");
+ return null;
+ }
+
+
+ public static string getFunctionInParameter(string functionWord, int lineNumber){
+ for (int i = 0; i < functionWord.Length; i++)
+
+ if (functionWord [i] == '(')
+ return functionWord.Substring(i, (functionWord.Length)-i);
+
+ ErrorMessage.sendErrorMessage (lineNumber, "Funktions anrop saknar en \"(\"");
+ return null;
+ }
+
+
+ public static bool validParameters(string trimmedPara, Function calledFunction, int lineNumber, Scope currentScope){
+ int paraAmount = getParameterAmount (trimmedPara, lineNumber, currentScope);
+
+ if (calledFunction.inputParameterAmount.Contains (paraAmount) == false)
+ ErrorMessage.sendErrorMessage (lineNumber, "Antal parametrar matchar inte funktions definition");
+
+ return true;
+ }
+
+
+ public static Variable[] getValueOfParameters(string trimmedPara, Function calledFunction, int lineNumber, Scope currentScope, FunctionCall theFuncCall){
+ string[] words = WordParser.parseWords (trimmedPara);
+
+ if (words.Length != 0) {
+ Logic[] logicOrder = WordsToLogicParser.determineLogicFromWords (words, lineNumber, currentScope);
+ List packedLogics = convertIntoParameterLogic (words, logicOrder, lineNumber);
+ theFuncCall.setReturnCalculations (packedLogics);
+
+ if (packedLogics != null)
+ return parseInputVariables(packedLogics, lineNumber, calledFunction, currentScope);
+ }
+
+ return new Variable[0];
+ }
+
+
+ private static Variable[] parseInputVariables(List packedLogics, int lineNumber, Function calledFunction, Scope currentScope){
+ Variable[] inputVariables = new Variable[packedLogics.Count];
+
+ for (int i = 0; i < packedLogics.Count; i++)
+ inputVariables [i] = SumParser.parseIntoSum (packedLogics [i], lineNumber, currentScope);
+
+ foreach (Variable v in inputVariables)
+ if (v.variableType == VariableTypes.unknown)
+ ErrorMessage.sendErrorMessage (lineNumber, "En eller flera av inparametrarna till: " + calledFunction.name + " är korrupta");
+
+ return inputVariables;
+ }
+
+
+ public static int getParameterAmount(string trimmedPara, int lineNumber, Scope currentScope){
+ string[] words = WordParser.parseWords (trimmedPara);
+ if (words.Length == 0)
+ return 0;
+
+ Logic[] logicOrder = WordsToLogicParser.determineLogicFromWords (words, lineNumber, currentScope);
+ List packedLogics = convertIntoParameterLogic (words, logicOrder, lineNumber);
+
+ return packedLogics.Count;
+ }
+
+ public static string[] getParameterNames(string trimmedPara, int lineNumber, Scope currentScope){
+ string[] words = WordParser.parseWords (trimmedPara);
+ if (words.Length == 0)
+ return new string[0];
+
+ Logic[] logicOrder = WordsToLogicParser.determineLogicFromWords (words, lineNumber, currentScope);
+ List packedLogics = convertIntoParameterLogic (words, logicOrder, lineNumber);
+
+
+ List returnWords = new List();
+ foreach (Logic[] l in packedLogics) {
+ if (l.Length != 1)
+ ErrorMessage.sendErrorMessage (lineNumber, "Du tycks ha glömt ett \",\"");
+
+ returnWords.Add (l [0].word);
+ }
+
+
+ return returnWords.ToArray();
+ }
+
+
+ static List convertIntoParameterLogic(string[] words, Logic[] logicOrder, int lineNumber){
+ List packedLogic = new List ();
+
+ if (logicOrder [0].currentType == WordTypes.commaSign || logicOrder [logicOrder.Length-1].currentType == WordTypes.commaSign)
+ ErrorMessage.sendErrorMessage (lineNumber, "Dinna komma tecke matchar inte");
+
+
+ int lastComma = -1;
+ for (int i = 0; i < logicOrder.Length; i++) {
+ if (logicOrder [i].currentType == WordTypes.commaSign) {
+
+ if (i == lastComma + 1) {
+ ErrorMessage.sendErrorMessage (lineNumber, "Två komma tecken kan inte komma direkt efter varandra");
+ return null;
+ } else {
+
+ List tempList = new List ();
+ for (int j = lastComma + 1; j < i; j++)
+ tempList.Add (logicOrder [j]);
+
+ packedLogic.Add (tempList.ToArray());
+ lastComma = i;
+ }
+
+ }
+ }
+
+ // Fix the last package should be written as a function for beautiful code later
+ List tempList2 = new List ();
+ for (int j = lastComma+1; j < logicOrder.Length; j++)
+ tempList2.Add (logicOrder [j]);
+
+ packedLogic.Add (tempList2.ToArray());
+
+
+ return packedLogic;
+ }
+ }
+
+}
+
\ No newline at end of file
diff --git a/LineParser/Functions/UserFunction.cs b/LineParser/Functions/UserFunction.cs
new file mode 100644
index 0000000..75f772f
--- /dev/null
+++ b/LineParser/Functions/UserFunction.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using Runtime;
+
+namespace Compiler
+{
+ public class UserFunction : Function {
+
+ public Scope targetScope;
+
+ public UserFunction(string name, Scope targetScope, int inputParaAmount){
+ base.name = name;
+ this.targetScope = targetScope;
+ base.inputParameterAmount.Add (inputParaAmount);
+ base.isUserFunction = true;
+ }
+
+ #region implemented abstract members of Function
+
+ public override Variable runFunction (Scope currentScope, Variable[] inputParas, int lineNumber)
+ {
+ Scope targetClone = targetScope.createDeepCopy ();
+ ScopeReturnParser.parseScopeReturns (targetClone, targetClone);
+ targetClone.linkChildScopes (targetClone);
+
+ for (int i = 0; i < base.inputParameterNames.Length && i < inputParas.Length; i++) {
+ inputParas [i].name = base.inputParameterNames [i];
+ Print.print ("Adding: " + inputParas [i].name + " : " + inputParas [i].getNumber ());
+ targetClone.scopeVariables.addVariable (inputParas [i], targetClone.scopeParser, lineNumber);
+ }
+
+ foreach (Function f in currentScope.scopeFunctions.getShallowCopy())
+ targetClone.scopeFunctions.addFunction (f);
+
+
+
+ Runtime.CodeWalker.switchToUserFunc (currentScope, targetClone);
+ return new Variable("Return Variable");
+ }
+
+ #endregion
+
+ }
+
+}
+
diff --git a/LineParser/Logics/ComparisonType.cs b/LineParser/Logics/ComparisonType.cs
new file mode 100644
index 0000000..acf3cbf
--- /dev/null
+++ b/LineParser/Logics/ComparisonType.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace Compiler
+{
+ public enum ComparisonType{
+ equalsTo,
+ notEqualsTo,
+ lessThen,
+ lessThenOrEqualsTo,
+ greaterThen,
+ greaterThenOrEqaulsTo,
+ unknown
+ };
+
+}
+
diff --git a/LineParser/Logics/Lines/CodeLine.cs b/LineParser/Logics/Lines/CodeLine.cs
new file mode 100644
index 0000000..4c309a4
--- /dev/null
+++ b/LineParser/Logics/Lines/CodeLine.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using Runtime;
+
+namespace Compiler
+{
+
+ public class CodeLine
+ {
+ public int lineNumber = 0;
+ public int indentLevel = 0;
+ public string[] words;
+ public Logic[] logicOrder;
+ public Logic theCommandType;
+ public Logic[] returnCalculations;
+ public bool doParseLine = true;
+
+ public CodeLine(int lineNumber, int indentNumber, string[] words){
+ this.indentLevel = indentNumber;
+ this.lineNumber = lineNumber;
+ this.words = words;
+ }
+
+
+ public string getFullLine(){
+ string temp = "";
+ for (int i = 0; i < words.Length; i++)
+ temp += words [i];
+
+ return temp;
+ }
+
+ public CodeLine cloneLine(){
+ CodeLine tempLine = new CodeLine (lineNumber, indentLevel, words);
+
+ Logic[] tempOrder = (Logic[])logicOrder.Clone ();
+ for (int i = 0; i < tempOrder.Length; i++) {
+ if (tempOrder [i].currentType == WordTypes.returnStatement)
+ tempOrder [i] = new ReturnStatement ();
+
+ }
+ tempLine.logicOrder = tempOrder;
+
+ tempLine.resetCalculations ();
+ return tempLine;
+ }
+
+
+ #region return calculations
+ public Logic[] getLatestOrder(){
+ if (returnCalculations == null)
+ return logicOrder;
+
+ return returnCalculations;
+ }
+
+ public void resetCalculations(){
+ returnCalculations = null;
+ }
+
+ public void insertReturnExpect(Logic l){
+ Logic[] tempLogic = (Logic[])getLatestOrder ().Clone ();
+ returnCalculations = tempLogic;
+
+ ReturnMemoryControll.insertReturnExpectation (this, lineNumber, l);
+ }
+
+
+
+ #endregion
+ }
+}
+
diff --git a/LineParser/Logics/Lines/ComparisonOperatorParser.cs b/LineParser/Logics/Lines/ComparisonOperatorParser.cs
new file mode 100644
index 0000000..90ea8ed
--- /dev/null
+++ b/LineParser/Logics/Lines/ComparisonOperatorParser.cs
@@ -0,0 +1,166 @@
+using System;
+using ErrorHandler;
+
+namespace Compiler
+{
+ public class ComparisonOperatorParser{
+
+ public static ComparisonType parseOperators(Logic[] logicOrder){
+
+ if (logicOrder.Length > 2 || logicOrder.Length == 0)
+ return ComparisonType.unknown;
+
+
+ if (logicOrder.Length == 1)
+ return parseSingleOperator (logicOrder [0]);
+
+ if (logicOrder.Length == 2)
+ return parseSDoubleOperator (logicOrder);
+
+ return ComparisonType.unknown;
+ }
+
+ static ComparisonType parseSDoubleOperator(Logic[] theOperators){
+ if (theOperators[1].currentType != WordTypes.equalSign)
+ return ComparisonType.unknown;
+
+
+ if (theOperators[0].currentType == WordTypes.equalSign)
+ return ComparisonType.equalsTo;
+
+ if (theOperators[0].currentType == WordTypes.lessThenSign)
+ return ComparisonType.lessThenOrEqualsTo;
+
+ if (theOperators[0].currentType == WordTypes.greaterThenSign)
+ return ComparisonType.greaterThenOrEqaulsTo;
+
+ if (theOperators[0].currentType == WordTypes.xorOperator)
+ return ComparisonType.notEqualsTo;
+
+
+ return ComparisonType.unknown;
+ }
+
+
+ static ComparisonType parseSingleOperator(Logic theOperator){
+ if (theOperator.currentType == WordTypes.lessThenSign)
+ return ComparisonType.lessThen;
+
+ if (theOperator.currentType == WordTypes.greaterThenSign)
+ return ComparisonType.greaterThen;
+
+ return ComparisonType.unknown;
+ }
+
+
+
+
+ public static bool checkSumsToOperator(VariableTypes theSum, ComparisonType theOperator, int lineNumber){
+ if (theSum == VariableTypes.number)
+ return true;
+
+ if (theSum == VariableTypes.boolean) {
+ if (theOperator == ComparisonType.equalsTo || theOperator == ComparisonType.notEqualsTo)
+ return true;
+ }
+
+ if (theSum == VariableTypes.textString) {
+ if (theOperator == ComparisonType.equalsTo || theOperator == ComparisonType.notEqualsTo)
+ return true;
+ }
+
+
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, "Okänd operator kombination av " + theSum);
+ return false;
+ }
+
+ public static bool makeComparison(Variable var1, Variable var2, ComparisonType theOperator, int lineNumber){
+
+ if (var1.variableType == VariableTypes.unknown || var1.variableType == VariableTypes.unsigned || var2.variableType == VariableTypes.unknown || var2.variableType == VariableTypes.unsigned)
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, "En eller flera av operatorerna går inte att tyda");
+
+
+ if (var1.variableType != var2.variableType)
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, "Kan inte utföra jämförelse mellan " + var1.variableType + " och " + var2.variableType);
+
+
+ if (theOperator == ComparisonType.equalsTo) {
+ if (var1.variableType == VariableTypes.boolean) {
+ if (var1.getBool () == var2.getBool ())
+ return true;
+ else
+ return false;
+ }
+
+ if (var1.variableType == VariableTypes.number) {
+ if (var1.getNumber () == var2.getNumber ())
+ return true;
+ else
+ return false;
+ }
+
+ if (var1.variableType == VariableTypes.textString) {
+ if (var1.getString () == var2.getString ())
+ return true;
+ else
+ return false;
+ }
+ }
+
+ if (theOperator == ComparisonType.notEqualsTo) {
+ if (var1.variableType == VariableTypes.boolean) {
+ if (var1.getBool () != var2.getBool ())
+ return true;
+ else
+ return false;
+ }
+
+ if (var1.variableType == VariableTypes.number) {
+ if (var1.getNumber () != var2.getNumber ())
+ return true;
+ else
+ return false;
+ }
+
+ if (var1.variableType == VariableTypes.textString) {
+ if (var1.getString () != var2.getString ())
+ return true;
+ else
+ return false;
+ }
+ }
+
+ if (theOperator == ComparisonType.greaterThenOrEqaulsTo && var1.variableType == VariableTypes.number){
+ if (var1.getNumber () >= var2.getNumber ())
+ return true;
+ else
+ return false;
+ }
+
+ if (theOperator == ComparisonType.lessThenOrEqualsTo && var1.variableType == VariableTypes.number){
+ if (var1.getNumber () <= var2.getNumber ())
+ return true;
+ else
+ return false;
+ }
+ if (theOperator == ComparisonType.lessThen && var1.variableType == VariableTypes.number){
+ if (var1.getNumber () < var2.getNumber ())
+ return true;
+ else
+ return false;
+ }
+ if (theOperator == ComparisonType.greaterThen && var1.variableType == VariableTypes.number){
+ if (var1.getNumber () > var2.getNumber ())
+ return true;
+ else
+ return false;
+ }
+
+
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.System, SystemFailureErrorType.unknownLogic.ToString(), new string[]{"4"});
+ return false;
+ }
+ }
+
+}
+
diff --git a/LineParser/Logics/Lines/ReturnValue.cs b/LineParser/Logics/Lines/ReturnValue.cs
new file mode 100644
index 0000000..7748f1d
--- /dev/null
+++ b/LineParser/Logics/Lines/ReturnValue.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace Compiler
+{
+ public class ReturnValue : Logic
+ {
+ public ReturnValue(){
+ base.currentType = WordTypes.returnValue;
+ base.word = "returnValue";
+ }
+ }
+}
+
diff --git a/LineParser/Logics/Logic.cs b/LineParser/Logics/Logic.cs
new file mode 100644
index 0000000..72225c0
--- /dev/null
+++ b/LineParser/Logics/Logic.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Compiler
+{
+ public abstract class Logic{
+
+ public string word;
+ public WordTypes currentType;
+
+ }
+}
+
diff --git a/LineParser/Logics/Loops/ForLoop.cs b/LineParser/Logics/Loops/ForLoop.cs
new file mode 100644
index 0000000..c6b9148
--- /dev/null
+++ b/LineParser/Logics/Loops/ForLoop.cs
@@ -0,0 +1,76 @@
+using System.Collections;
+using System.Collections.Generic;
+using Runtime;
+using ErrorHandler;
+
+namespace Compiler{
+
+ public class ForLoop : ScopeLoop, Loop{
+
+ public int indentLevel;
+ public double startValue = 0;
+ public double endValue;
+ public double incrementValue = 1;
+ public Variable counterVariable;
+
+ public ForLoop(){
+ base.currentType = WordTypes.forLoop;
+ base.word = "for";
+ base.theComparisonType = ComparisonType.lessThen;
+ }
+
+ public void setLoopVariables(string counterName, double startValue, double endValue, double incrementValue){
+ this.startValue = startValue;
+ this.endValue = endValue;
+
+ if (incrementValue < 0) {
+ base.theComparisonType = ComparisonType.greaterThen;
+ Print.print ("Changing type");
+ }
+
+ Variable leftVariable = new Variable (counterName, startValue);
+ Variable checkVariable = new Variable ("ForLoopCheckValue", endValue);
+
+ this.counterVariable = leftVariable;
+
+ counterVariable.setValue (startValue);
+ counterVariable.isForLoopVariable = true;
+
+ base.leftValue = counterVariable;
+ base.rightValue = checkVariable;
+ this.incrementValue = incrementValue;
+ }
+
+
+ #region Loop implementation
+ public void addCounterVariableToScope(int lineNumber){
+ getTargetScope().scopeVariables.addVariable (counterVariable, getTargetScope().scopeParser, lineNumber);
+ }
+
+ public bool makeComparison (int lineNumber, bool doChangeValue = true)
+ {
+ if (counterVariable.variableType != VariableTypes.number)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ForLoop, ForLoopErrorType.counterVariableIsNotNumber.ToString(), new string[1] {counterVariable.name});
+
+ if(doChangeValue)
+ counterVariable.setValue (counterVariable.getNumber () + incrementValue);
+ bool doLoop = ComparisonOperatorParser.makeComparison (counterVariable, base.rightValue, base.theComparisonType, lineNumber);
+
+
+ getTargetScope().scopeVariables.addVariable (counterVariable, getTargetScope().scopeParser, lineNumber);
+ if (doLoop == false && doChangeValue)
+ counterVariable.setValue (endValue - incrementValue);
+
+ return doLoop;
+ }
+
+
+ public void resetCounterVariable ()
+ {
+ counterVariable.setValue (startValue);
+ }
+ #endregion
+
+ }
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Loops/Loop.cs b/LineParser/Logics/Loops/Loop.cs
new file mode 100644
index 0000000..ecec993
--- /dev/null
+++ b/LineParser/Logics/Loops/Loop.cs
@@ -0,0 +1,11 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public interface Loop{
+ bool makeComparison (int lineNumber, bool changeValue = true);
+ void addCounterVariableToScope (int lineNumber);
+ void resetCounterVariable();
+ }
+
+}
diff --git a/LineParser/Logics/Loops/WhileLoop.cs b/LineParser/Logics/Loops/WhileLoop.cs
new file mode 100644
index 0000000..4b1647c
--- /dev/null
+++ b/LineParser/Logics/Loops/WhileLoop.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace Compiler
+{
+ public class WhileLoop : ScopeLoop, Loop {
+
+ public int indentLevel;
+ public Logic[] theStatement;
+
+ public WhileLoop(){
+ base.currentType = WordTypes.whileLoop;
+ base.word = "while";
+ }
+
+ #region Loop implementation
+ public bool makeComparison (int lineNumber, bool changeValue = true)
+ {
+ return StatementParser.parseStatement (theStatement, lineNumber, getTargetScope());
+ }
+
+ public void addCounterVariableToScope (int lineNumber)
+ {
+
+ }
+ public void resetCounterVariable ()
+ {
+
+ }
+ #endregion
+ }
+
+}
+
diff --git a/LineParser/Logics/Operators/AndOperator.cs b/LineParser/Logics/Operators/AndOperator.cs
new file mode 100644
index 0000000..4aea4bd
--- /dev/null
+++ b/LineParser/Logics/Operators/AndOperator.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class AndOperator : Logic, AndOrOperator {
+
+ public AndOperator(string word){
+ base.currentType = WordTypes.andOperator;
+ base.word = word;
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Operators/CommaSign.cs b/LineParser/Logics/Operators/CommaSign.cs
new file mode 100644
index 0000000..86966ff
--- /dev/null
+++ b/LineParser/Logics/Operators/CommaSign.cs
@@ -0,0 +1,13 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class CommaSign : Logic{
+
+ public CommaSign(){
+ base.currentType = WordTypes.commaSign;
+ base.word = ",";
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Operators/EqualSign.cs b/LineParser/Logics/Operators/EqualSign.cs
new file mode 100644
index 0000000..7785bba
--- /dev/null
+++ b/LineParser/Logics/Operators/EqualSign.cs
@@ -0,0 +1,14 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class EqualSign : Logic, ComparisonOperator{
+
+ public EqualSign(){
+ base.currentType = WordTypes.equalSign;
+ base.word = "=";
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Operators/GreaterThenSign.cs b/LineParser/Logics/Operators/GreaterThenSign.cs
new file mode 100644
index 0000000..34fc504
--- /dev/null
+++ b/LineParser/Logics/Operators/GreaterThenSign.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class GreaterThenSign : Logic, ComparisonOperator{
+
+ public GreaterThenSign(){
+ base.currentType = WordTypes.greaterThenSign;
+ base.word = ">";
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Operators/IndentOperator.cs b/LineParser/Logics/Operators/IndentOperator.cs
new file mode 100644
index 0000000..77a2552
--- /dev/null
+++ b/LineParser/Logics/Operators/IndentOperator.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class IndentOperator : Logic{
+
+ public IndentOperator(){
+ base.currentType = WordTypes.indentOperator;
+ base.word = ":";
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Operators/LessThenSign.cs b/LineParser/Logics/Operators/LessThenSign.cs
new file mode 100644
index 0000000..e6beaf0
--- /dev/null
+++ b/LineParser/Logics/Operators/LessThenSign.cs
@@ -0,0 +1,14 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class LessThenSign : Logic, ComparisonOperator{
+
+ public LessThenSign(){
+ base.currentType = WordTypes.lessThenSign;
+ base.word = "<";
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Operators/MathOperator.cs b/LineParser/Logics/Operators/MathOperator.cs
new file mode 100644
index 0000000..e7ac8d6
--- /dev/null
+++ b/LineParser/Logics/Operators/MathOperator.cs
@@ -0,0 +1,16 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class MathOperator : Logic {
+
+ public MathOperator(string word){
+ base.currentType = WordTypes.mathOperator;
+
+ base.word = word;
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Operators/NotOperator.cs b/LineParser/Logics/Operators/NotOperator.cs
new file mode 100644
index 0000000..2b0978a
--- /dev/null
+++ b/LineParser/Logics/Operators/NotOperator.cs
@@ -0,0 +1,16 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class NotOperator : Logic {
+
+ public NotOperator(string word){
+ base.currentType = WordTypes.notOperator;
+
+ base.word = word;
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Operators/OrOperator.cs b/LineParser/Logics/Operators/OrOperator.cs
new file mode 100644
index 0000000..569308c
--- /dev/null
+++ b/LineParser/Logics/Operators/OrOperator.cs
@@ -0,0 +1,15 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class OrOperator : Logic, AndOrOperator {
+
+ public OrOperator(string word){
+ base.currentType = WordTypes.orOperator;
+ base.word = word;
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Operators/XorOperator.cs b/LineParser/Logics/Operators/XorOperator.cs
new file mode 100644
index 0000000..c8ba2f6
--- /dev/null
+++ b/LineParser/Logics/Operators/XorOperator.cs
@@ -0,0 +1,16 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class XorOperator : Logic, ComparisonOperator {
+
+ public XorOperator(string word){
+ base.currentType = WordTypes.xorOperator;
+
+ base.word = word;
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Speciall/BreakStatement.cs b/LineParser/Logics/Speciall/BreakStatement.cs
new file mode 100644
index 0000000..960ec15
--- /dev/null
+++ b/LineParser/Logics/Speciall/BreakStatement.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace Compiler
+{
+ public class BreakStatement : Logic{
+
+ public BreakStatement(){
+ base.currentType = WordTypes.breakStatement;
+ base.word = "break";
+ }
+
+
+ }
+}
+
diff --git a/LineParser/Logics/Speciall/ContinueStatment.cs b/LineParser/Logics/Speciall/ContinueStatment.cs
new file mode 100644
index 0000000..471f014
--- /dev/null
+++ b/LineParser/Logics/Speciall/ContinueStatment.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Compiler
+{
+ public class ContinueStatment : Logic
+ {
+ public ContinueStatment(){
+ base.currentType = WordTypes.continueStatement;
+ base.word = "continue";
+ }
+
+ }
+}
+
diff --git a/LineParser/Logics/Speciall/DefStatement.cs b/LineParser/Logics/Speciall/DefStatement.cs
new file mode 100644
index 0000000..b86bd0e
--- /dev/null
+++ b/LineParser/Logics/Speciall/DefStatement.cs
@@ -0,0 +1,20 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class DefStatement : ScopeStarter {
+
+
+ public int indentLevel;
+ public ElseStatement linkedElse;
+
+ public DefStatement(){
+ base.currentType = WordTypes.defStatement;
+ base.word = "def";
+ }
+
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Speciall/ElifStatement.cs b/LineParser/Logics/Speciall/ElifStatement.cs
new file mode 100644
index 0000000..1dbd366
--- /dev/null
+++ b/LineParser/Logics/Speciall/ElifStatement.cs
@@ -0,0 +1,45 @@
+using System;
+
+namespace Compiler
+{
+ public class ElifStatement : ScopeStarter, ComparisonScope{
+
+ public int indentLevel;
+ public ComparisonScope nextStatement;
+
+ public ElifStatement(){
+ base.currentType = WordTypes.elifOperator;
+ base.word = "elif";
+ base.doEnterScope = false;
+ }
+
+
+ public void initNextstatement(){
+ if (nextStatement != null) {
+ nextStatement.setParseLine (!doEnterScope);
+
+ if (nextStatement is ElseStatement)
+ nextStatement.setEnterScope (!doEnterScope);
+ }
+ }
+
+ #region ComparisonScope implementation
+
+ public void linkNextStatement (ComparisonScope nextScope){
+ nextStatement = nextScope;
+ }
+ public void setEnterScope (bool value)
+ {
+ base.doEnterScope = value;
+ }
+
+ public void setParseLine (bool value)
+ {
+ if (value == false && nextStatement != null)
+ nextStatement.setParseLine (false);
+ base.doParseLine = value;
+ }
+ #endregion
+ }
+}
+
diff --git a/LineParser/Logics/Speciall/ElseStatement.cs b/LineParser/Logics/Speciall/ElseStatement.cs
new file mode 100644
index 0000000..fb8b3ed
--- /dev/null
+++ b/LineParser/Logics/Speciall/ElseStatement.cs
@@ -0,0 +1,30 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class ElseStatement : ScopeStarter, ComparisonScope{
+
+ public int indentLevel;
+ public ElseStatement(){
+ base.currentType = WordTypes.elseOperator;
+ base.word = "else";
+ }
+
+ #region ComparisonScope implementation
+ public void linkNextStatement (ComparisonScope nextScope){}
+ public void initNextstatement (){}
+
+ public void setEnterScope (bool value)
+ {
+ base.doEnterScope = value;
+ }
+
+ public void setParseLine (bool value)
+ {
+ base.doParseLine = value;
+ }
+ #endregion
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Speciall/FunctionCall.cs b/LineParser/Logics/Speciall/FunctionCall.cs
new file mode 100644
index 0000000..6124312
--- /dev/null
+++ b/LineParser/Logics/Speciall/FunctionCall.cs
@@ -0,0 +1,59 @@
+using System.Collections;
+using System.Collections.Generic;
+using Runtime;
+
+namespace Compiler{
+
+ public class FunctionCall : Logic {
+
+ public string fullWord;
+ public string name;
+ public string parameter;
+ public bool hasReturnVariable;
+ public Function targetFunc;
+ public Variable[] inputVariables;
+
+ public List returnCalculations;
+
+ public int lineNumber;
+
+ public FunctionCall(string fullWord, string name, string parameter, Function targetFunc){
+ setLogic (word, WordTypes.functionCall);
+ this.fullWord = word;
+ this.targetFunc = targetFunc;
+ this.name = name;
+ this.parameter = parameter;
+ base.currentType = WordTypes.functionCall;
+ }
+
+
+ public Variable runFunction (Scope currentScope){
+ if (CodeWalker.isWaitingForUserInput)
+ return new Variable();
+
+ return targetFunc.runFunction (currentScope, inputVariables, lineNumber);
+ }
+
+ public void setLogic(string word, WordTypes currentType){
+ base.currentType = currentType;
+ base.word = word;
+ }
+
+
+ #region Return Calculations
+ public void setReturnCalculations(List inputList){
+ returnCalculations = new List ();
+ foreach (Logic[] l in inputList)
+ returnCalculations.Add (l);
+ }
+
+ public void resetCalculations(){
+ returnCalculations.Clear ();
+ returnCalculations = null;
+ }
+
+ #endregion
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Speciall/IfStatement.cs b/LineParser/Logics/Speciall/IfStatement.cs
new file mode 100644
index 0000000..577a34b
--- /dev/null
+++ b/LineParser/Logics/Speciall/IfStatement.cs
@@ -0,0 +1,43 @@
+using System.Collections;
+
+namespace Compiler{
+
+ public class IfStatement : ScopeStarter, ComparisonScope {
+
+ public int indentLevel;
+ public ComparisonScope nextStatement;
+
+ public IfStatement(){
+ base.currentType = WordTypes.ifOperator;
+ base.word = "if";
+ }
+
+
+ public void initNextstatement(){
+ if (nextStatement != null) {
+ nextStatement.setParseLine (!doEnterScope);
+
+ if (nextStatement is ElseStatement)
+ nextStatement.setEnterScope (!doEnterScope);
+ }
+ }
+
+ #region ComparisonScope implementation
+ public void linkNextStatement (ComparisonScope nextScope){
+ nextStatement = nextScope;
+ }
+ public void setEnterScope (bool value)
+ {
+ base.doEnterScope = value;
+ }
+
+ public void setParseLine (bool value)
+ {
+ base.doParseLine = value;
+ }
+
+ #endregion
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/Logics/Speciall/Package.cs b/LineParser/Logics/Speciall/Package.cs
new file mode 100644
index 0000000..769d05b
--- /dev/null
+++ b/LineParser/Logics/Speciall/Package.cs
@@ -0,0 +1,59 @@
+using System;
+
+namespace Compiler
+{
+ public class Package : Logic{
+
+ public int lineNumber = 0;
+ public Logic[] logicOrder;
+ public Logic[] returnCalculations;
+
+
+ public Package(string word, int lineNumber){
+ this.lineNumber = lineNumber;
+ base.word = word;
+ base.currentType = WordTypes.package;
+ }
+
+ public Package(Logic[] logicOrder, int lineNumber){
+ this.lineNumber = lineNumber;
+ base.word = "Internal Package";
+ base.currentType = WordTypes.package;
+ this.logicOrder = logicOrder;
+ }
+
+
+
+ public void setLogicOrder(Logic[] logicOrder){
+ this.logicOrder = logicOrder;
+ }
+
+
+ #region return calculations
+ public Logic[] getLatestOrder(){
+ if (returnCalculations == null)
+ return logicOrder;
+
+ return returnCalculations;
+ }
+
+ public void resetCalculations(){
+ returnCalculations = null;
+ }
+
+ public void insertAwaitReturn(Logic l){
+ Logic[] tempLogic = (Logic[])getLatestOrder ().Clone ();
+
+ for (int i = 0; i < tempLogic.Length; i++)
+ if (tempLogic [i] == l) {
+ tempLogic [i] = new ReturnValue ();
+ returnCalculations = tempLogic;
+ return;
+ }
+ else if (tempLogic [i].currentType == WordTypes.package)
+ (tempLogic [i] as Package).insertAwaitReturn (l);
+ }
+ #endregion
+ }
+}
+
diff --git a/LineParser/Logics/Speciall/ReturnStatement.cs b/LineParser/Logics/Speciall/ReturnStatement.cs
new file mode 100644
index 0000000..72e0aae
--- /dev/null
+++ b/LineParser/Logics/Speciall/ReturnStatement.cs
@@ -0,0 +1,42 @@
+using System;
+using ErrorHandler;
+using Runtime;
+
+namespace Compiler
+{
+ public class ReturnStatement : Logic
+ {
+ public Logic[] followOrder;
+ public Scope FunctionParent;
+
+
+ public ReturnStatement ()
+ {
+ base.currentType = WordTypes.returnStatement;
+ base.word = "return";
+ }
+
+
+ public void findFunctionParent(Scope currentScope, int lineNumber){
+ if (currentScope.theScopeType == ScopeType.function) {
+ return;
+ }
+ else if(currentScope.theScopeType == ScopeType.main)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.Function, FunctionErrorType.cantReturnFromMainScope.ToString(), null);
+
+
+ if(currentScope.parentScope == null)
+ ErrorMessage.sendErrorMessage (lineNumber, "Scope saknar anropare \n" + currentScope.theScopeType);
+
+
+ Scope parentScope = currentScope.parentScope;
+ while (parentScope.theScopeType != ScopeType.function) {
+ parentScope = parentScope.parentScope;
+ }
+ FunctionParent = parentScope;
+ }
+
+
+ }
+}
+
diff --git a/LineParser/Logics/WordTypes.cs b/LineParser/Logics/WordTypes.cs
new file mode 100644
index 0000000..d0d920b
--- /dev/null
+++ b/LineParser/Logics/WordTypes.cs
@@ -0,0 +1,37 @@
+namespace Compiler{
+
+ public enum WordTypes{
+ variable,
+ functionCall,
+ mathOperator,
+ number,
+ textString,
+ booleanValue,
+ booleanExpression,
+ ifOperator,
+ elseOperator,
+ elifOperator,
+ forLoop,
+ whileLoop,
+ defStatement,
+ breakStatement,
+ continueStatement,
+ returnStatement,
+ returnValue,
+ equalSign,
+ xorOperator,
+ lessThenSign,
+ greaterThenSign,
+ notOperator,
+ andOperator,
+ orOperator,
+ speciallWord,
+ inWord,
+ indentOperator,
+ commaSign,
+ package, // A package is a compressed parameter example: (x + 23 - 3)
+ nill,
+ unknown,
+ };
+
+}
\ No newline at end of file
diff --git a/LineParser/PackageUnWrapper.cs b/LineParser/PackageUnWrapper.cs
new file mode 100644
index 0000000..e3c3b14
--- /dev/null
+++ b/LineParser/PackageUnWrapper.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace Compiler
+{
+ public class PackageUnWrapper{
+
+ public static void unpackPackage(string word, int lineNumber, Scope currentScope, Package currentPackage){
+
+ if (word.Length <= 2)
+ return;
+
+ string trimedString = removeSurrondingParanteser(word);
+
+ string[] words = WordParser.parseWords (trimedString);
+ Logic[] logicOrder = WordsToLogicParser.determineLogicFromWords (words, lineNumber, currentScope);
+
+ currentPackage.logicOrder = logicOrder;
+ }
+
+
+
+ public static string removeSurrondingParanteser(string word){
+ return word.Substring (1, word.Length - 2);
+ }
+
+ }
+}
+
diff --git a/LineParser/Parsers/AndOperatorParser.cs b/LineParser/Parsers/AndOperatorParser.cs
new file mode 100644
index 0000000..cf24187
--- /dev/null
+++ b/LineParser/Parsers/AndOperatorParser.cs
@@ -0,0 +1,12 @@
+using System;
+
+
+namespace Compiler
+{
+ public class AndOperatorParser
+ {
+
+
+ }
+}
+
diff --git a/LineParser/Parsers/BooleanAlgebra/FindBoolExpressions.cs b/LineParser/Parsers/BooleanAlgebra/FindBoolExpressions.cs
new file mode 100644
index 0000000..5ff4662
--- /dev/null
+++ b/LineParser/Parsers/BooleanAlgebra/FindBoolExpressions.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace LineParser
+{
+ public class FindBoolExpressions
+ {
+ public FindBoolExpressions ()
+ {
+ }
+ }
+}
+
diff --git a/LineParser/Parsers/FunctionParser.cs b/LineParser/Parsers/FunctionParser.cs
new file mode 100644
index 0000000..807d570
--- /dev/null
+++ b/LineParser/Parsers/FunctionParser.cs
@@ -0,0 +1,177 @@
+using System;
+using System.Collections.Generic;
+
+namespace Compiler
+{
+ public class FunctionParser{
+
+ public static Compiler.Logic parseIntoFunctionCall(string word, int lineNumber, Compiler.Scope currentScope){
+
+ string funcName = getFunctionName (word, lineNumber);
+ string funcPara = getFunctionInParameter (word, lineNumber);
+
+ return new FunctionCall (word, funcName, funcPara, null);
+ }
+
+ public static void linkFunctionCall(FunctionCall theFunc, int lineNumber, Compiler.Scope currentScope){
+ Compiler.Function searchedFunc = currentScope.scopeFunctions.getSavedFunction (theFunc.name, lineNumber);
+ if (searchedFunc != null){
+
+ Compiler.Variable[] inputVariables = validParameters (PackageUnWrapper.removeSurrondingParanteser (theFunc.parameter), searchedFunc, lineNumber, currentScope);
+ theFunc.targetFunc = searchedFunc;
+ }
+
+ }
+
+
+ public static string getFunctionName(string functionWord, int lineNumber){
+
+ for (int i = 0; i < functionWord.Length; i++)
+ if (functionWord [i] == '(')
+ return functionWord.Substring (0, i);
+
+ ErrorMessage.sendErrorMessage (lineNumber, "Compiler.Function Call is missing a (");
+ return null;
+ }
+
+
+ public static string getFunctionInParameter(string functionWord, int lineNumber){
+
+ for (int i = 0; i < functionWord.Length; i++)
+
+ if (functionWord [i] == '(')
+ return functionWord.Substring(i, (functionWord.Length)-i);
+
+ ErrorMessage.sendErrorMessage (lineNumber, "Compiler.Function Call is missing a (");
+ return null;
+ }
+
+
+ public static bool hasReturnValue(string word, int lineNumber){
+ Compiler.Function searchedFunc = Camera.main.GetComponent().funcs.getSavedFunction (FunctionParser.getFunctionName (word, lineNumber), lineNumber);
+ if (searchedFunc != null)
+ return searchedFunc.hasReturnVariable;
+
+
+ return false;
+ }
+
+
+
+ static Compiler.Variable[] validParameters(string trimmedPara, Compiler.Function calledFunction, int lineNumber, Compiler.Scope currentScope){
+
+
+ string[] words = Compiler.WordParser.parseWords (trimmedPara);
+
+ if (words.Length != 0) {
+ Compiler.Logic[] logicOrder = WordLogic.determineLogicFromWords (words, lineNumber, currentScope);
+
+ List> packedLogics = convertIntoParameterLogic (words, logicOrder, lineNumber);
+
+ if (packedLogics != null) {
+ Compiler.Variable[] inputVariables = new Compiler.Variable[packedLogics.Count];
+
+ for (int i = 0; i < packedLogics.Count; i++)
+ inputVariables [i] = ValidSumCheck.checkIfValidSum (packedLogics [i].ToArray (), lineNumber);
+
+
+ foreach (Compiler.Variable v in inputVariables)
+ if (v.variableType == Compiler.VariableTypes.unkown)
+ ErrorMessage.sendErrorMessage (lineNumber, "one or several of the input parameters to function: " + calledFunction.name + " are corrupt!");
+
+
+ if (calledFunction.inputParameters.Contains (inputVariables.Length))
+ return inputVariables;
+ }
+
+ }
+
+ if (calledFunction.inputParameters.Contains (0))
+ return new Compiler.Variable[0];
+
+ ErrorMessage.sendErrorMessage (lineNumber, "Amount of parameters does not match Expected!");
+ return new Compiler.Variable[0];
+ }
+
+
+ public static Compiler.Variable[] getValueOfParameters(string trimmedPara, Compiler.Function calledFunction, int lineNumber,Compiler.Scope currentScope){
+
+
+ string[] words = Compiler.WordParser.parseWords (trimmedPara);
+
+ if (words.Length != 0) {
+ Compiler.Logic[] logicOrder = WordLogic.determineLogicFromWords (words, lineNumber, currentScope);
+
+ List> packedLogics = convertIntoParameterLogic (words, logicOrder, lineNumber);
+
+ if (packedLogics != null) {
+ Compiler.Variable[] inputVariables = new Compiler.Variable[packedLogics.Count];
+
+ for (int i = 0; i < packedLogics.Count; i++)
+ inputVariables [i] = SumParser.parseIntoSum (packedLogics [i].ToArray (), lineNumber, currentScope);
+
+
+ foreach (Compiler.Variable v in inputVariables)
+ if (v.variableType == Compiler.VariableTypes.unkown)
+ ErrorMessage.sendErrorMessage (lineNumber, "one or several of the input parameters to function: " + calledFunction.name + " are corrupt!");
+
+
+ if (calledFunction.inputParameters.Contains (inputVariables.Length))
+ return inputVariables;
+ }
+
+ }
+
+ return new Compiler.Variable[0];
+ }
+
+
+
+ static List> convertIntoParameterLogic(string[] words, Compiler.Logic[] logicOrder, int lineNumber){
+
+ List> packedLogic = new List> ();
+
+
+
+ if (logicOrder [0].currentType == Compiler.WordTypes.commaSign || logicOrder [logicOrder.Length-1].currentType == Compiler.WordTypes.commaSign)
+ ErrorMessage.sendErrorMessage (lineNumber, "Commas does not match in the parameter");
+
+
+ int lastComma = -1;
+ for (int i = 0; i < logicOrder.Length; i++) {
+ if (logicOrder [i].currentType == Compiler.WordTypes.commaSign) {
+
+ if (i == lastComma + 1) {
+ ErrorMessage.sendErrorMessage (lineNumber, "Stacked commas in parameter");
+ return null;
+ } else {
+
+ List tempList = new List ();
+ for (int j = lastComma + 1; j < i; j++)
+ tempList.Add (logicOrder [j]);
+
+ packedLogic.Add (tempList);
+ lastComma = i;
+ }
+
+ }
+ }
+
+ // Fixes the last package should be written as a function for beautiful code later
+ List tempList2 = new List ();
+ for (int j = lastComma+1; j < logicOrder.Length; j++)
+ tempList2.Add (logicOrder [j]);
+
+ packedLogic.Add (tempList2);
+
+
+ return packedLogic;
+ }
+
+
+
+
+ }
+
+}
+
diff --git a/LineParser/Parsers/InternalParseFunctions.cs b/LineParser/Parsers/InternalParseFunctions.cs
new file mode 100644
index 0000000..625c6c5
--- /dev/null
+++ b/LineParser/Parsers/InternalParseFunctions.cs
@@ -0,0 +1,24 @@
+using System;
+using ErrorHandler;
+
+namespace Compiler
+{
+ public class InternalParseFunctions
+ {
+
+ public static Logic[] getSubArray(Logic[] logicOrder, int startIndex, int endIndex, int lineNumber){
+ if (startIndex < logicOrder.Length && endIndex < logicOrder.Length) {
+ Logic[] subArray = new Logic[endIndex - startIndex + 1];
+ for (int i = startIndex; i <= endIndex; i++)
+ subArray [i - startIndex] = logicOrder [i];
+
+ return subArray;
+ } else
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.System, SystemFailureErrorType.corruptAndOrStatement.ToString(), null);
+
+ return null;
+ }
+
+ }
+}
+
diff --git a/LineParser/Parsers/Lines/LineParser.cs b/LineParser/Parsers/Lines/LineParser.cs
new file mode 100644
index 0000000..41c8756
--- /dev/null
+++ b/LineParser/Parsers/Lines/LineParser.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+
+namespace Compiler
+{
+ public class LineParser
+ {
+ public static List parseLines(List lineList){
+ List tempList = new List ();
+
+ for (int i = 0; i < lineList.Count; i++) {
+ if (lineList [i].theString != "" && containsChar(lineList[i].theString) && !isComment(lineList[i].theString)) {
+ int indentLevel = getIndentLevel (lineList [i].theString);
+ string trimmedString = lineList [i].theString.Substring (indentLevel, lineList [i].theString.Length - indentLevel);
+ string[] words = WordParser.parseWords (trimmedString);
+ addLine (tempList, lineList[i].lineNumber, indentLevel, words);
+ }
+ }
+
+ return tempList;
+ }
+
+ private static bool containsChar(string line){
+ if (string.IsNullOrEmpty(line.Trim()))
+ return false;
+ return true;
+ }
+
+ private static bool isComment(string line){
+ for (int i = 0; i < line.Length; i++)
+ if (char.IsWhiteSpace (line [i]) == false) {
+ if (line [i] == '#')
+ return true;
+
+ return false;
+ }
+
+ return false;
+ }
+
+ private static int getIndentLevel(string line){
+ int indentCounter = 0;
+ for (int i = 0; i < line.Length; i++) {
+ if (line [i] == '\t')
+ indentCounter++;
+ else
+ break;
+ }
+
+ return indentCounter;
+ }
+
+ private static void addLine(List programCodeLines ,int lineNumber, int indentLevel, string[] words){
+ CodeLine temp = new CodeLine (lineNumber, indentLevel, words);
+ programCodeLines.Add (temp);
+ }
+ }
+}
+
diff --git a/LineParser/Parsers/Lines/LineSplitter.cs b/LineParser/Parsers/Lines/LineSplitter.cs
new file mode 100644
index 0000000..8e1784d
--- /dev/null
+++ b/LineParser/Parsers/Lines/LineSplitter.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+
+namespace Compiler
+{
+ internal class LineSplitter
+ {
+ public static List splitTextIntoLines(string currentText){
+ List tempList = new List ();
+
+ string tempLine = "";
+ int currentLineNumber = 1;
+ int lastLinePos = -1;
+
+ for (int i = 0; i < currentText.Length; i++) {
+ if (currentText [i] == '\n') {
+ tempLine = currentText.Substring (lastLinePos + 1, i - (lastLinePos + 1));
+ tempList.Add (new ParsedLine(tempLine, currentLineNumber));
+ lastLinePos = i;
+ currentLineNumber++;
+ }
+ }
+
+ if (lastLinePos != currentText.Length) {
+ tempLine = currentText.Substring (lastLinePos + 1, currentText.Length - (lastLinePos + 1));
+ tempList.Add (new ParsedLine(tempLine, currentLineNumber));
+ }
+
+ return tempList;
+ }
+ }
+}
+
diff --git a/LineParser/Parsers/Lines/ParsedLine.cs b/LineParser/Parsers/Lines/ParsedLine.cs
new file mode 100644
index 0000000..47bba2a
--- /dev/null
+++ b/LineParser/Parsers/Lines/ParsedLine.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace Compiler
+{
+ public class ParsedLine{
+ public string theString;
+ public int lineNumber;
+
+ public ParsedLine(string text, int lineNumber){
+ this.theString = text;
+ this.lineNumber = lineNumber;
+ }
+
+ }
+}
+
diff --git a/LineParser/Parsers/Logics/PostLogicParsing.cs b/LineParser/Parsers/Logics/PostLogicParsing.cs
new file mode 100644
index 0000000..60fe62e
--- /dev/null
+++ b/LineParser/Parsers/Logics/PostLogicParsing.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using Runtime;
+
+namespace Compiler
+{
+ public class PostLogicParsing
+ {
+
+ ///
+ /// Split Packages and Statements. Combine Variables and Packages into FunctionCalls.
+ ///
+ public static Logic[] parsePostLogics(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ logicOrder = splitPackagesAndStatements(logicOrder, lineNumber, currentScope);
+ return parseVariablesAndPackagesIntoFunctionCalls (logicOrder, lineNumber, currentScope);
+ }
+
+
+ private static Logic[] splitPackagesAndStatements(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ List newOrder = new List ();
+
+ for (int i = 0; i < logicOrder.Length; i++) {
+ if (logicOrder [i].currentType == WordTypes.functionCall && SpecialWordParser.isKeyWord ((logicOrder [i] as FunctionCall).name)) {
+
+ Package temp = new Package ("(" + (logicOrder [i] as FunctionCall).parameter + ")", lineNumber);
+ temp.logicOrder = WordsToLogicParser.determineLogicFromWords (new string[]{ temp.word}, lineNumber, currentScope);
+
+ if ((logicOrder [i] as FunctionCall).name == "if") {
+ newOrder.Add (new IfStatement ());
+ newOrder.Add(temp);
+ }
+ else if ((logicOrder [i] as FunctionCall).name == "while") {
+ newOrder.Add (new WhileLoop ());
+ newOrder.Add(temp);
+ }
+
+ } else
+ newOrder.Add (logicOrder [i]);
+ }
+ return newOrder.ToArray();
+ }
+
+
+ private static Logic[] parseVariablesAndPackagesIntoFunctionCalls(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ List tempOrder = new List ();
+
+ for (int i = 0; i < logicOrder.Length; i++)
+ if (logicOrder [i].currentType == WordTypes.variable && (i+1 < logicOrder.Length && logicOrder[i+1].currentType == WordTypes.package)) {
+ Logic theFuncCall = FunctionParser.parseIntoFunctionCall (logicOrder [i].word + logicOrder [i + 1].word, lineNumber, currentScope);
+ tempOrder.Add (theFuncCall);
+ i += 1;
+ }
+ else
+ tempOrder.Add (logicOrder [i]);
+
+ return tempOrder.ToArray ();
+ }
+
+ }
+}
+
diff --git a/LineParser/Parsers/Logics/WordsToLogicParser.cs b/LineParser/Parsers/Logics/WordsToLogicParser.cs
new file mode 100644
index 0000000..2ff6916
--- /dev/null
+++ b/LineParser/Parsers/Logics/WordsToLogicParser.cs
@@ -0,0 +1,214 @@
+using System;
+using System.Collections.Generic;
+
+namespace Compiler
+{
+ public class WordsToLogicParser{
+
+
+ public static Logic[] determineLogicFromWords(string[] words, int lineNumber, Scope currentScope){
+ Logic[] logicOrder = new Logic[words.Length];
+
+ for (int i = 0; i < words.Length; i++) {
+ logicOrder [i] = getCurrentLogic (words [i], lineNumber, currentScope);
+ if (logicOrder [i].currentType == WordTypes.package) {
+ PackageUnWrapper.unpackPackage (words [i], lineNumber, currentScope, logicOrder [i] as Package);
+ }
+ }
+
+ logicOrder = PostLogicParsing.parsePostLogics (logicOrder, lineNumber, currentScope);
+
+ return logicOrder;
+ }
+
+
+
+ private static Logic getCurrentLogic(string word, int lineNumber, Scope currentScope){
+
+ if (word == ",")
+ return new CommaSign();
+
+ if (word == ">")
+ return new GreaterThenSign();
+
+ if (word == "<")
+ return new LessThenSign();
+
+ if (word == ":")
+ return new IndentOperator();
+
+ if (word == "!")
+ return new XorOperator (word);
+
+ if (word == "not")
+ return new NotOperator (word);
+
+ if (word == "or")
+ return new OrOperator (word);
+
+ if (word == "and")
+ return new AndOperator (word);
+
+
+ if (isBooleanValue (word) == 1)
+ return new BooleanValue (true);
+ if (isBooleanValue (word) == 0)
+ return new BooleanValue (false);
+
+
+ if (isNumber (word))
+ return new NumberValue(word);
+
+ if (isString (word))
+ return new TextValue (word);
+
+
+ if (SpecialWordParser.isKeyWord (word)) {
+ SpecialWordParser.checkIfUnsupportedKeyword (word, lineNumber);
+ WordTypes specialType = SpecialWordParser.getSpecialType (word, lineNumber);
+
+ if (specialType == WordTypes.forLoop)
+ return new ForLoop ();
+
+ if (specialType == WordTypes.whileLoop)
+ return new WhileLoop ();
+
+ if (specialType == WordTypes.ifOperator)
+ return new IfStatement ();
+
+ if (specialType == WordTypes.elifOperator)
+ return new ElifStatement ();
+
+ if (specialType == WordTypes.elseOperator)
+ return new ElseStatement ();
+
+ if (specialType == WordTypes.defStatement)
+ return new DefStatement ();
+
+ if (specialType == WordTypes.returnStatement)
+ return new ReturnStatement ();
+
+ if (specialType == WordTypes.breakStatement)
+ return new BreakStatement ();
+
+ if (specialType == WordTypes.continueStatement)
+ return new ContinueStatment ();
+ }
+
+
+
+ if (startsWithDigitOrWeirdChar(word) == false) {
+
+ if (endsWithParantes (word)) {
+ Logic temp = FunctionParser.parseIntoFunctionCall (word, lineNumber, currentScope);
+ if (temp != null)
+ return temp;
+ }
+ else {
+ if(containsButNotStartWithDigitWeirdChar(word) == false)
+ return checkVariable(word, currentScope.scopeVariables);
+ }
+
+
+ }
+
+ if (word.Length == 1) {
+ if (word [0] == '=')
+ return new EqualSign ();
+ if(isMathOperator(word[0]))
+ return new MathOperator(word);
+ }
+
+ if (isPackage (word)) {
+
+ return new Package(word, lineNumber);
+ }
+
+ return new UnknownLogic (lineNumber);
+ }
+
+
+ private static Logic checkVariable(string word, Variables scopeVariables){
+
+ int variablePos = scopeVariables.containsVariable (word);
+ if (variablePos >= 0) {
+ return scopeVariables.variableList [variablePos];
+ }
+
+ return new Variable (word);
+ }
+
+
+
+ private static int isBooleanValue(string word){
+ if (word == "True")
+ return 1;
+ if (word == "False")
+ return 0;
+
+ return -1;
+ }
+
+
+ private static bool isNumber(string word){
+ double testNumber = 0;
+
+ return double.TryParse (word, out testNumber);
+ }
+
+ private static bool isMathOperator(char c){
+ for(int i = 0; i < MathParser.mathOperators.Length; i++)
+ if(c == MathParser.mathOperators[i])
+ return true;
+
+ return false;
+ }
+
+
+ private static bool startsWithDigitOrWeirdChar(string word){
+ if(char.IsLetter(word[0]))
+ return false;
+
+ if (word [0] == '_')
+ return false;
+
+ return true;
+ }
+
+ private static bool containsButNotStartWithDigitWeirdChar(string word){
+ if (word.Length == 1)
+ return false;
+
+ for (int i = 1; i < word.Length; i++)
+ if (!char.IsLetter (word [i]) && !char.IsDigit (word [i]) && word [i] != '_')
+ return true;
+
+ return false;
+ }
+
+ private static bool endsWithParantes(string word){
+ if(word[word.Length-1] == ')')
+ return true;
+
+ return false;
+ }
+
+
+ private static bool isPackage(string word){
+ if (word [0] == '(' && word [word.Length - 1] == ')')
+ return true;
+
+ return false;
+ }
+
+ private static bool isString(string word){
+ if (word [0] == '"' && word [word.Length - 1] == '"')
+ return true;
+
+ return false;
+ }
+
+ }
+
+}
+
diff --git a/LineParser/Parsers/SpecialWordParser.cs b/LineParser/Parsers/SpecialWordParser.cs
new file mode 100644
index 0000000..ba00a21
--- /dev/null
+++ b/LineParser/Parsers/SpecialWordParser.cs
@@ -0,0 +1,121 @@
+using System;
+using Runtime;
+using ErrorHandler;
+
+namespace Compiler
+{
+
+ public class SpecialWordParser{
+
+ public static readonly string[] keywords = {"while", "for", "in", "if", "else", "elif", "def", "return", "break", "continue"};
+ public static readonly string[] scopeStarters = {"while", "for", "if", "else", "elif", "def"};
+
+ public static readonly string[] unSupportedKeywords = {"as", "assert", "class", "del", "except",
+ "exec", "finally", "from", "global", "import", "is", "lambda", "pass", "raise", "try", "with", "yield", "None"};
+
+
+ public static Logic parseSpecialLine(Logic[] logicOrder, int lineNumber, Scope currentScope){
+
+ switch (logicOrder[0].currentType) {
+
+ case WordTypes.elifOperator:
+ case WordTypes.ifOperator:
+ return IfAndElifStatementParser.parseStatement (logicOrder, lineNumber, currentScope);
+
+ case WordTypes.elseOperator:
+ return ElseStatementParser.parseElseStatement (logicOrder, lineNumber, currentScope);
+
+ case WordTypes.forLoop:
+ return ForLoopParser.parseForLoop(logicOrder, lineNumber, currentScope);
+
+ case WordTypes.whileLoop:
+ return WhileLoopParser.parseWhileLoop(logicOrder, lineNumber, currentScope);
+
+ case WordTypes.defStatement:
+ return DefStatementParser.parseDefStatement(logicOrder, lineNumber, currentScope);
+
+ case WordTypes.returnStatement:
+ return ReturnStatementParser.parseReturnStatement (logicOrder, lineNumber, currentScope);
+
+ case WordTypes.breakStatement:
+ return BreakAndContinueStatementParser.parseBreakStatement (logicOrder, lineNumber, currentScope);
+
+ case WordTypes.continueStatement:
+ return BreakAndContinueStatementParser.parseContinueStatement (logicOrder, lineNumber, currentScope);
+
+
+ default:
+ return new UnknownLogic(lineNumber);
+ }
+ }
+
+
+ public static bool isKeyWord(string word){
+ foreach (string s in keywords)
+ if (s == word)
+ return true;
+
+ foreach (string s in unSupportedKeywords)
+ if (s == word)
+ return true;
+
+ return false;
+ }
+
+ public static void checkIfUnsupportedKeyword(string word,int lineNumber){
+ foreach (string s in unSupportedKeywords)
+ if (s == word)
+ ErrorMessage.sendErrorMessage (lineNumber, s + " stöds inte i detta spel");
+ }
+
+ public static WordTypes getSpecialType(string word, int lineNumber){
+
+ if (word == "while")
+ return WordTypes.whileLoop;
+
+ if (word == "for")
+ return WordTypes.forLoop;
+
+ if (word == "if")
+ return WordTypes.ifOperator;
+
+ if (word == "else")
+ return WordTypes.elseOperator;
+
+ if (word == "elif")
+ return WordTypes.elifOperator;
+
+ if (word == "in")
+ return WordTypes.inWord;
+
+ if (word == "def")
+ return WordTypes.defStatement;
+
+ if (word == "return")
+ return WordTypes.returnStatement;
+
+ if (word == "break")
+ return WordTypes.breakStatement;
+
+ if (word == "continue")
+ return WordTypes.continueStatement;
+
+ ErrorMessage.sendErrorMessage (lineNumber, word + " antogs vara ett keyword, men något gick fel");
+ return WordTypes.unknown;
+ }
+
+
+ public static bool isValidScopeStarter(Logic[] logicOrder, int lineNumber){
+
+ if (logicOrder[0] is ScopeStarter){
+ return true;
+ }
+
+
+ return false;
+ }
+
+ }
+
+}
+
diff --git a/LineParser/Parsers/Statements/DefStatementParser.cs b/LineParser/Parsers/Statements/DefStatementParser.cs
new file mode 100644
index 0000000..e8b86b8
--- /dev/null
+++ b/LineParser/Parsers/Statements/DefStatementParser.cs
@@ -0,0 +1,32 @@
+using ErrorHandler;
+using System.Collections;
+using System.Collections.Generic;
+using Runtime;
+
+namespace Compiler {
+
+ public class DefStatementParser{
+
+
+ // Could be optimized so that we save left, right and operators for next comparision so we do not need to parse every loop instance!
+
+
+ public static Logic parseDefStatement(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ FunctionCall theFuncCall = logicOrder [1] as FunctionCall;
+
+ if(SpecialWordParser.isKeyWord(theFuncCall.name))
+ ErrorMessage.sendErrorMessage (lineNumber,string.Format( "\"{0}\" är ett Python keyword, du kan därför inte döpa en funktion till det", theFuncCall.name));
+
+ int paraAmount = (FunctionParser.getParameterAmount (theFuncCall.parameter, lineNumber, currentScope));
+ UserFunction theFunc = new UserFunction (theFuncCall.name, (logicOrder [0] as ScopeStarter).getTargetScope(), paraAmount);
+ currentScope.scopeFunctions.addFunction(theFunc);
+
+ theFunc.inputParameterNames = FunctionParser.getParameterNames (theFuncCall.parameter, lineNumber, currentScope);
+
+ return new DefStatement ();
+ }
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/LineParser/Parsers/Statements/ElseStatementParser.cs b/LineParser/Parsers/Statements/ElseStatementParser.cs
new file mode 100644
index 0000000..64ead8f
--- /dev/null
+++ b/LineParser/Parsers/Statements/ElseStatementParser.cs
@@ -0,0 +1,22 @@
+using ErrorHandler;
+using System.Collections;
+
+namespace Compiler {
+
+ public class ElseStatementParser{
+
+
+ public static Logic parseElseStatement(Logic[] logicOrder, int lineNumber, Scope currentScope){
+
+ if (logicOrder [logicOrder.Length - 1].currentType != WordTypes.indentOperator)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ElseStatements, ElseErrorType.missingIndentOperator.ToString(), null);
+
+ if (logicOrder.Length != 2)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ElseStatements, ElseErrorType.unknownFormat.ToString(), null);
+
+
+ return (logicOrder[0] as ElseStatement);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/LineParser/Parsers/Statements/ForLoopParser.cs b/LineParser/Parsers/Statements/ForLoopParser.cs
new file mode 100644
index 0000000..5cf380c
--- /dev/null
+++ b/LineParser/Parsers/Statements/ForLoopParser.cs
@@ -0,0 +1,86 @@
+using ErrorHandler;
+using System.Collections;
+using Runtime;
+
+namespace Compiler {
+
+ public class ForLoopParser{
+
+ public static Logic parseForLoop(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ syntaxCheckForLoop (logicOrder, lineNumber);
+
+
+ #region get & check variables
+ FunctionCall rangeCall = (logicOrder [3] as FunctionCall);
+ Variable[] inputVariables = FunctionParser.getValueOfParameters (rangeCall.parameter, rangeCall.targetFunc, lineNumber, currentScope, rangeCall);
+
+ // Checks if inputVariables is empty and else if only numbers
+ if (inputVariables.Length == 0) {
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ForLoop, ForLoopErrorType.rangeArgumentEmpty.ToString(), null);
+ }
+ else {
+ foreach (Variable v in inputVariables)
+ if(v.variableType != VariableTypes.number)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ForLoop, ForLoopErrorType.rangeArgumentNotNumber.ToString(), null);
+ }
+ #endregion
+
+
+ ForLoop returnLoop = new ForLoop ();
+ returnLoop.setTargetScope((logicOrder [0] as ScopeStarter).getTargetScope());
+ returnLoop.getTargetScope().theScoopLoop = returnLoop;
+
+ string counterName = logicOrder[1].word;
+ if (inputVariables.Length == 1)
+ returnLoop.setLoopVariables(counterName, 0,inputVariables [0].getNumber (), 1);
+
+ if (inputVariables.Length == 2)
+ returnLoop.setLoopVariables(counterName, inputVariables [0].getNumber (), inputVariables [1].getNumber (), 1);
+
+ if (inputVariables.Length == 3)
+ returnLoop.setLoopVariables(counterName, inputVariables [0].getNumber (), inputVariables [1].getNumber (), inputVariables [2].getNumber ());
+
+ returnLoop.doEnterScope = returnLoop.makeComparison (lineNumber, false);
+ returnLoop.addCounterVariableToScope(lineNumber);
+
+
+ return returnLoop;
+ }
+
+
+
+ private static void syntaxCheckForLoop(Logic[] logicOrder, int lineNumber){
+
+ if (logicOrder.Length == 4) {
+ checkCorrectWordsForLoop (logicOrder, lineNumber);
+ } else if (logicOrder.Length < 4 || logicOrder.Length > 5) {
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ForLoop, ForLoopErrorType.unknownFormat.ToString(), null);
+ } else {
+ checkCorrectWordsForLoop (logicOrder, lineNumber);
+ }
+ }
+
+ private static void checkCorrectWordsForLoop (Logic[] logicOrder, int lineNumber){
+
+ if (logicOrder [logicOrder.Length - 1].currentType != WordTypes.indentOperator)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ForLoop, ForLoopErrorType.missingIndentOperator.ToString(), null);
+
+ if (logicOrder [1].currentType != WordTypes.variable || logicOrder [1].word == "in")
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ForLoop, ForLoopErrorType.expectVariableAt2.ToString(), null);
+
+ if (logicOrder [2].word != "in")
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ForLoop, ForLoopErrorType.expectInAt3.ToString(), null);
+
+ if (logicOrder [3].currentType != WordTypes.functionCall) {
+ if (logicOrder [3].currentType == WordTypes.variable && logicOrder[3].word == "range")
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ForLoop, ForLoopErrorType.rangeMissingParenthesis.ToString(), null);
+ else
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ForLoop, ForLoopErrorType.expectRangeAt4.ToString(), null);
+ }
+
+ if ((logicOrder [3] as FunctionCall).name != "range")
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ForLoop, ForLoopErrorType.expectRangeAt4.ToString(), null);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/LineParser/Parsers/Statements/IfAndElifStatementParser.cs b/LineParser/Parsers/Statements/IfAndElifStatementParser.cs
new file mode 100644
index 0000000..1409d65
--- /dev/null
+++ b/LineParser/Parsers/Statements/IfAndElifStatementParser.cs
@@ -0,0 +1,28 @@
+using ErrorHandler;
+using System.Collections;
+using Runtime;
+
+namespace Compiler {
+ public class IfAndElifStatementParser{
+
+ public static Logic parseStatement(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ if (logicOrder.Length < 3)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.IfStatements, IfErrorType.unknownFormat.ToString(), null);
+
+ if (logicOrder [logicOrder.Length - 1].currentType != WordTypes.indentOperator)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.IfStatements, IfErrorType.missingIndentOperator.ToString(), null);
+
+
+ Logic[] statementLogic = InternalParseFunctions.getSubArray (logicOrder, 1, logicOrder.Length - 2, lineNumber);
+ (logicOrder [0] as ScopeStarter).doEnterScope = StatementParser.parseAndCheckStatement (statementLogic, lineNumber, currentScope);
+ (logicOrder [0] as ComparisonScope).initNextstatement ();
+
+ if(logicOrder[0] is IfStatement)
+ return (logicOrder[0] as IfStatement);
+
+ return (logicOrder[0] as ElifStatement);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/LineParser/Parsers/Statements/ReturnStatementParser.cs b/LineParser/Parsers/Statements/ReturnStatementParser.cs
new file mode 100644
index 0000000..240ef0f
--- /dev/null
+++ b/LineParser/Parsers/Statements/ReturnStatementParser.cs
@@ -0,0 +1,47 @@
+using System;
+using ErrorHandler;
+using Runtime;
+
+namespace Compiler
+{
+ public class ReturnStatementParser
+ {
+ public static Logic parseReturnStatement(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ if (logicOrder.Length <= 1) {
+ }
+
+ Variable returnSum;
+
+ if (logicOrder.Length <= 1) {
+ // Should return None if there is no sum to return
+ returnSum = new Variable ();
+
+ //This error should not exist
+ ErrorMessage.sendErrorMessage (lineNumber, "I detta moment måste du returnera något ur funktionen");
+ }
+ else {
+ Logic[] followOrder = InternalParseFunctions.getSubArray (logicOrder, 1, logicOrder.Length - 1, lineNumber);
+ returnSum = SumParser.parseIntoSum (followOrder, lineNumber, currentScope);
+ }
+
+ ReturnStatement theReturn = (logicOrder [0] as ReturnStatement);
+ theReturn.findFunctionParent (currentScope, lineNumber);
+
+ CodeLine parentLine = theReturn.FunctionParent.parentScope.codeLines [theReturn.FunctionParent.parentScope.lastReadLine];
+ ReturnMemoryControll.insertReturnValue (parentLine, lineNumber, returnSum);
+
+
+ currentScope.isReturning = true;
+ CodeWalker.setReturnTarget (theReturn.FunctionParent.parentScope);
+
+ return (logicOrder [0] as ReturnStatement);
+ }
+
+ }
+
+
+
+
+
+}
+
diff --git a/LineParser/Parsers/Statements/WhileLoopParser.cs b/LineParser/Parsers/Statements/WhileLoopParser.cs
new file mode 100644
index 0000000..f086e7a
--- /dev/null
+++ b/LineParser/Parsers/Statements/WhileLoopParser.cs
@@ -0,0 +1,40 @@
+using ErrorHandler;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Compiler {
+
+ public class WhileLoopParser{
+
+
+ // Could be optimized so that we save left, right and operators for next comparision so we do not need to parse every loop instance!
+
+
+ public static Logic parseWhileLoop(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ if (logicOrder.Length < 3)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.WhileLoop, WhileErrorType.unknownFormat.ToString(), null);
+
+ if (logicOrder [logicOrder.Length -1].currentType != WordTypes.indentOperator)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.WhileLoop, WhileErrorType.missingIndentOperator.ToString(), null);
+
+ Logic[] statementLogic = new Logic[logicOrder.Length - 2];
+ for (int i = 1; i < logicOrder.Length - 1; i++)
+ statementLogic [i - 1] = logicOrder [i];
+
+
+ WhileLoop returnLoop = new WhileLoop ();
+ returnLoop.setTargetScope((logicOrder [0] as ScopeStarter).getTargetScope());
+ returnLoop.getTargetScope().theScoopLoop = returnLoop;
+
+
+ returnLoop.doEnterScope = StatementParser.parseAndCheckStatement (statementLogic, lineNumber, currentScope);
+ returnLoop.theStatement = statementLogic;
+
+
+ return returnLoop;
+ }
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/LineParser/Parsers/SumParser/BooleanAlgebra/BoolAlgebraParser.cs b/LineParser/Parsers/SumParser/BooleanAlgebra/BoolAlgebraParser.cs
new file mode 100644
index 0000000..4fe2510
--- /dev/null
+++ b/LineParser/Parsers/SumParser/BooleanAlgebra/BoolAlgebraParser.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using ErrorHandler;
+using B83;
+using Runtime;
+
+namespace Compiler
+{
+ public class BoolAlgebraParser
+ {
+ public static bool parseBoolAlgebraStatement(BoolAlgebraWord[] logicOrder, int lineNumber){
+ string calcString = "";
+ foreach (BoolAlgebraWord w in logicOrder)
+ calcString += w.calcWord;
+
+ int sum = (int)SyntaxCheck.globalParser.Evaluate (calcString);
+
+ return Convert.ToBoolean(sum);
+ }
+
+
+
+
+ public static BoolAlgebraWord[] parseIntoBoolAlgebra(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ List algebraList = new List ();
+
+ int lastOperatorPos = -1;
+ for (int i = 0; i < logicOrder.Length; i++)
+ if (logicOrder [i] is AndOrOperator) {
+
+ Logic[] partStatement = InternalParseFunctions.getSubArray (logicOrder, lastOperatorPos + 1, i-1, lineNumber);
+
+ bool tempResult = StatementParser.parseExpression (partStatement, lineNumber, currentScope);
+ algebraList.Add (new BoolAlgebraWord (tempResult.ToString ()));
+ algebraList.Add (new BoolAlgebraWord (logicOrder [i].word));
+
+ lastOperatorPos = i;
+ }
+
+
+ Logic[] finalStatement = InternalParseFunctions.getSubArray (logicOrder, lastOperatorPos + 1, logicOrder.Length-1, lineNumber);
+ bool finalResult = StatementParser.parseExpression (finalStatement, lineNumber, currentScope);
+ algebraList.Add (new BoolAlgebraWord (finalResult.ToString ()));
+
+ return algebraList.ToArray ();
+ }
+
+ }
+
+}
+
diff --git a/LineParser/Parsers/SumParser/BooleanAlgebra/BoolAlgebraWord.cs b/LineParser/Parsers/SumParser/BooleanAlgebra/BoolAlgebraWord.cs
new file mode 100644
index 0000000..b888c4c
--- /dev/null
+++ b/LineParser/Parsers/SumParser/BooleanAlgebra/BoolAlgebraWord.cs
@@ -0,0 +1,29 @@
+using System;
+
+namespace Compiler
+{
+ public class BoolAlgebraWord
+ {
+ public string calcWord;
+
+ public BoolAlgebraWord (string word)
+ {
+ if (word == "and" || word == "or")
+ setOperatorSettings (word);
+ else
+ setValueSettings (word);
+ }
+
+ private void setOperatorSettings(string word){
+ if (word == "and")
+ calcWord = "*";
+ else
+ calcWord = "+";
+ }
+
+ private void setValueSettings(string word){
+ calcWord = Convert.ToInt32 (Convert.ToBoolean (word)).ToString();
+ }
+ }
+}
+
diff --git a/LineParser/Parsers/SumParser/BooleanAlgebra/BoolExpressionParser.cs b/LineParser/Parsers/SumParser/BooleanAlgebra/BoolExpressionParser.cs
new file mode 100644
index 0000000..12bf184
--- /dev/null
+++ b/LineParser/Parsers/SumParser/BooleanAlgebra/BoolExpressionParser.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using Runtime;
+using ErrorHandler;
+using System.Linq;
+
+namespace Compiler
+{
+ public class BoolExpressionParser
+ {
+
+
+ public static Logic[] compressAndOrStatements(Logic[] preLogicOrder, int lineNumber, Scope currentScope){
+ bool foundAndOr = BoolCompressExpressions.hasAndOr(preLogicOrder, lineNumber);
+
+ if (foundAndOr) {
+ string boolString = convertIntoBoolAlgebra (preLogicOrder, lineNumber, currentScope);
+ if (SyntaxCheck.globalParser.Evaluate (boolString) != 0)
+ return new Logic[1]{ new BooleanValue (true) };
+
+ return new Logic[1]{ new BooleanValue (false) };
+ }
+ else
+ return (preLogicOrder [0] as Package).logicOrder;
+ }
+
+
+ private static string convertIntoBoolAlgebra(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ string boolString = "";
+ for (int i = 0; i < logicOrder.Length; i++) {
+ if (logicOrder [i] is AndOrOperator) {
+ if(logicOrder[i].currentType == WordTypes.andOperator)
+ boolString += "*";
+ else
+ boolString += "+";
+
+ continue;
+ }
+
+ if (logicOrder [i].currentType == WordTypes.package) {
+ Variable tempSum = SumParser.parseIntoSum ((logicOrder [i] as Package).logicOrder, lineNumber, currentScope);
+ if (tempSum.getBool ())
+ boolString += "1";
+ else
+ boolString += "0";
+ }
+ else
+ ErrorMessage.sendErrorMessage (lineNumber, "Korrupt uttryck");
+ }
+
+ return boolString;
+ }
+
+
+ }
+}
+
diff --git a/LineParser/Parsers/SumParser/BooleanAlgebra/BoolExpressions/BoolCompressExpressions.cs b/LineParser/Parsers/SumParser/BooleanAlgebra/BoolExpressions/BoolCompressExpressions.cs
new file mode 100644
index 0000000..3117c0a
--- /dev/null
+++ b/LineParser/Parsers/SumParser/BooleanAlgebra/BoolExpressions/BoolCompressExpressions.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using ErrorHandler;
+using Runtime;
+
+
+namespace Compiler
+{
+ public class BoolCompressExpressions
+ {
+
+ public static Logic[] compressExpression(Logic[] preLogicOrder, int lineNumber, Scope currentScope, bool solveExpressions){
+ Logic[] logicOrder = splitAtAndOr ((Logic[])preLogicOrder.Clone (), lineNumber);
+
+ foreach (Logic l in logicOrder)
+ if (l is Package && hasValidComparison ((l as Package).logicOrder, lineNumber))
+ (l as Package).logicOrder = new Logic[1]{ new BooleanExpression ((l as Package).logicOrder, lineNumber, currentScope) };
+
+
+ return logicOrder;
+ }
+
+
+ private static bool hasValidComparison(Logic[] logicOrder, int lineNumber){
+ int foundCounter = 0;
+ bool foundComparison = false;
+
+ for (int i = 0; i < logicOrder.Length; i++) {
+ if (logicOrder [i] is ComparisonOperator)
+ foundCounter++;
+ else
+ foundCounter = 0;
+
+ if (foundCounter > 0) {
+ foundComparison = true;
+ if (foundCounter > 2)
+ ErrorMessage.sendErrorMessage (lineNumber, "Kombinationen: " + logicOrder [i - 2].word + logicOrder [i - 1].word + logicOrder [i].word + " är inte tillåten");
+ }
+ }
+ if (logicOrder [0] is ComparisonOperator)
+ ErrorMessage.sendErrorMessage (lineNumber, "Ett boolskt utryck kan inte börja med en jämförelseoperator");
+ if (logicOrder [logicOrder.Length-1] is ComparisonOperator)
+ ErrorMessage.sendErrorMessage (lineNumber, "Ett boolskt utryck kan inte sluta med en jämförelseoperator");
+
+ return foundComparison;
+ }
+
+
+ public static bool hasAndOr(Logic[] logicOrder, int lineNumber){
+ foreach (Logic l in logicOrder)
+ if (l is AndOrOperator)
+ return true;
+ return false;
+ }
+
+ private static Logic[] splitAtAndOr(Logic[] logicOrder, int lineNumber){
+ if(hasAndOr(logicOrder, lineNumber) == false)
+ return new Logic[1]{ new Package(logicOrder, lineNumber)};
+
+ List compressedOrder = new List ();
+ int lastFound = 0;
+
+ for(int i = 0; i < logicOrder.Length; i++){
+ if (logicOrder [i] is AndOrOperator) {
+ if (i == 0 || i == logicOrder.Length - 1)
+ ErrorMessage.sendErrorMessage (lineNumber, "Kan inte börja eller sluta med And/Or");
+
+ Logic[] subArray = InternalParseFunctions.getSubArray (logicOrder, lastFound, i - 1, lineNumber);
+ compressedOrder.Add (new Package (subArray, lineNumber));
+
+ if (logicOrder [i + 1] is AndOrOperator)
+ ErrorMessage.sendErrorMessage (lineNumber, "Kan inte ha 2 And/Or direkt efter varandra");
+
+ lastFound = i + 1;
+ compressedOrder.Add (logicOrder [i]);
+ }
+ }
+ Logic[] endArray = InternalParseFunctions.getSubArray (logicOrder, lastFound, logicOrder.Length-1, lineNumber);
+ compressedOrder.Add (new Package (endArray, lineNumber));
+
+
+ return compressedOrder.ToArray ();
+ }
+
+ }
+}
+
diff --git a/LineParser/Parsers/SumParser/BooleanAlgebra/BooleanExpression.cs b/LineParser/Parsers/SumParser/BooleanAlgebra/BooleanExpression.cs
new file mode 100644
index 0000000..822fffb
--- /dev/null
+++ b/LineParser/Parsers/SumParser/BooleanAlgebra/BooleanExpression.cs
@@ -0,0 +1,25 @@
+using System;
+using Runtime;
+
+namespace Compiler
+{
+ public class BooleanExpression : Logic, BoolType
+ {
+ private Logic[] logicOrder;
+ private int lineNumber;
+ private Scope currentScope;
+
+ public BooleanExpression (Logic[] logicOrder, int lineNumber, Scope currentScope)
+ {
+ base.currentType = WordTypes.booleanExpression;
+ this.logicOrder = logicOrder;
+ this.lineNumber = lineNumber;
+ this.currentScope = currentScope;
+ }
+
+ public BooleanValue parseExpression(){
+ return new BooleanValue(StatementParser.parseStatement(logicOrder, lineNumber, currentScope));
+ }
+ }
+}
+
diff --git a/LineParser/Parsers/SumParser/BooleanAlgebra/BooleanSumParser.cs b/LineParser/Parsers/SumParser/BooleanAlgebra/BooleanSumParser.cs
new file mode 100644
index 0000000..91dbf38
--- /dev/null
+++ b/LineParser/Parsers/SumParser/BooleanAlgebra/BooleanSumParser.cs
@@ -0,0 +1,49 @@
+using System.Collections;
+using Runtime;
+
+namespace Compiler{
+
+ internal class BooleanSumParser{
+
+ public static Variable validBoolSum(Logic[] logicOrder, int lineNumber){
+ #region parse out the not operators
+ int notNotIndex = 0;
+ int notCounter = 0;
+ for (int i = 0; i < logicOrder.Length; i++)
+ if (logicOrder [i].currentType == WordTypes.notOperator)
+ notCounter++;
+ else {
+ notNotIndex = i;
+ break;
+ }
+
+ if (logicOrder.Length - notNotIndex != 1)
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, "Korrupt Sant eller Falskt värde");
+ #endregion
+
+
+ if (logicOrder [notNotIndex].currentType == WordTypes.variable) {
+ if (notCounter % 2 == 0)
+ return new Variable("BoolVar", (logicOrder [notNotIndex] as Variable).getBool(), true);
+ else
+ return new Variable("BoolVar", !(logicOrder [notNotIndex] as Variable).getBool(), true);
+ }
+
+ if (logicOrder [notNotIndex].currentType == WordTypes.booleanValue) {
+ if (notCounter % 2 == 0)
+ return new Variable("BoolVar", (logicOrder [notNotIndex] as BooleanValue).value, true);
+ else
+ return new Variable("BoolVar", !(logicOrder [notNotIndex] as BooleanValue).value, true);
+ }
+
+ if (logicOrder [notNotIndex].currentType == WordTypes.booleanExpression)
+ return new Variable ("Possible Bool Sum", false, true);
+
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, "Något gick fel med Sant eller Falsk parsing");
+ return new Variable ();
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/Parsers/SumParser/Exceptions/FunctionCallException.cs b/LineParser/Parsers/SumParser/Exceptions/FunctionCallException.cs
new file mode 100644
index 0000000..1fc6670
--- /dev/null
+++ b/LineParser/Parsers/SumParser/Exceptions/FunctionCallException.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Compiler
+{
+ public class FunctionCallException : Exception
+ {
+ }
+}
+
diff --git a/LineParser/Parsers/SumParser/ExpressionParser.cs b/LineParser/Parsers/SumParser/ExpressionParser.cs
new file mode 100644
index 0000000..7e95269
--- /dev/null
+++ b/LineParser/Parsers/SumParser/ExpressionParser.cs
@@ -0,0 +1,576 @@
+/* * * * * * * * * * * * * *
+ * A simple expression parser
+ * --------------------------
+ *
+ * The parser can parse a mathematical expression into a simple custom
+ * expression tree. It can recognise methods and fields/contants which
+ * are user extensible. It can also contain expression parameters which
+ * are registrated automatically. An expression tree can be "converted"
+ * into a delegate.
+ *
+ * Written by Bunny83
+ * 2014-11-02
+ *
+ * Features:
+ * - Elementary arithmetic [ + - * / ]
+* - Power [ ^ ]
+* - Brackets ( )
+* - Most function from System.Math (abs, sin, round, floor, min, ...)
+* - Constants ( e, PI )
+* - MultiValue return (quite slow, produce extra garbage each call)
+ *
+ * * * * * * * * * * * * * */
+
+
+ using System.Linq;
+using System.Collections.Generic;
+ using Runtime;
+using System;
+
+namespace B83.ExpressionParser
+{
+ public interface IValue
+ {
+ double Value { get; }
+ }
+ public class Number : IValue
+ {
+ private double m_Value;
+ public double Value
+ {
+ get { return m_Value; }
+ set { m_Value = value; }
+ }
+ public Number(double aValue)
+ {
+ m_Value = aValue;
+ }
+ public override string ToString()
+ {
+ return "" + m_Value + "";
+ }
+ }
+ public class OperationSum : IValue
+ {
+ private IValue[] m_Values;
+ public double Value
+ {
+ get { return m_Values.Select(v => v.Value).Sum(); }
+ }
+ public OperationSum(params IValue[] aValues)
+ {
+ // collapse unnecessary nested sum operations.
+ List v = new List(aValues.Length);
+ foreach (var I in aValues)
+ {
+ var sum = I as OperationSum;
+ if (sum == null)
+ v.Add(I);
+ else
+ v.AddRange(sum.m_Values);
+ }
+ m_Values = v.ToArray();
+ }
+ public override string ToString()
+ {
+ return "( " + string.Join(" + ", m_Values.Select(v => v.ToString()).ToArray()) + " )";
+ }
+ }
+ public class OperationProduct : IValue
+ {
+ private IValue[] m_Values;
+ public double Value
+ {
+ get { return m_Values.Select(v => v.Value).Aggregate((v1, v2) => v1 * v2); }
+ }
+ public OperationProduct(params IValue[] aValues)
+ {
+ m_Values = aValues;
+ }
+ public override string ToString()
+ {
+ return "( " + string.Join(" * ", m_Values.Select(v => v.ToString()).ToArray()) + " )";
+ }
+
+ }
+ public class OperationPower : IValue
+ {
+ private IValue m_Value;
+ private IValue m_Power;
+ public double Value
+ {
+ get { return System.Math.Pow(m_Value.Value, m_Power.Value); }
+ }
+ public OperationPower(IValue aValue, IValue aPower)
+ {
+ m_Value = aValue;
+ m_Power = aPower;
+ }
+ public override string ToString()
+ {
+ return "( " + m_Value + "^" + m_Power + " )";
+ }
+
+ }
+ public class OperationNegate : IValue
+ {
+ private IValue m_Value;
+ public double Value
+ {
+ get { return -m_Value.Value; }
+ }
+ public OperationNegate(IValue aValue)
+ {
+ m_Value = aValue;
+ }
+ public override string ToString()
+ {
+ return "( -" + m_Value + " )";
+ }
+
+ }
+ public class OperationReciprocal : IValue
+ {
+ private IValue m_Value;
+ public double Value
+ {
+ get { return 1.0 / m_Value.Value; }
+ }
+ public OperationReciprocal(IValue aValue)
+ {
+ m_Value = aValue;
+ }
+ public override string ToString()
+ {
+ return "( 1/" + m_Value + " )";
+ }
+
+ }
+
+ public class MultiParameterList : IValue
+ {
+ private IValue[] m_Values;
+ public IValue[] Parameters { get { return m_Values; } }
+ public double Value
+ {
+ get { return m_Values.Select(v => v.Value).FirstOrDefault(); }
+ }
+ public MultiParameterList(params IValue[] aValues)
+ {
+ m_Values = aValues;
+ }
+ public override string ToString()
+ {
+ return string.Join(", ", m_Values.Select(v => v.ToString()).ToArray());
+ }
+ }
+
+ public class CustomFunction : IValue
+ {
+ private IValue[] m_Params;
+ private System.Func m_Delegate;
+ private string m_Name;
+ public double Value
+ {
+ get
+ {
+ if (m_Params == null)
+ return m_Delegate(null);
+ return m_Delegate(m_Params.Select(p => p.Value).ToArray());
+ }
+ }
+ public CustomFunction(string aName, System.Func aDelegate, params IValue[] aValues)
+ {
+ m_Delegate = aDelegate;
+ m_Params = aValues;
+ m_Name = aName;
+ }
+ public override string ToString()
+ {
+ if (m_Params == null)
+ return m_Name;
+ return m_Name + "( " + string.Join(", ", m_Params.Select(v => v.ToString()).ToArray()) + " )";
+ }
+ }
+ public class Parameter : Number
+ {
+ public string Name { get; private set; }
+ public override string ToString()
+ {
+ return Name+"["+base.ToString()+"]";
+ }
+ public Parameter(string aName) : base(0)
+ {
+ Name = aName;
+ }
+ }
+
+ public class Expression : IValue
+ {
+ public Dictionary Parameters = new Dictionary();
+ public IValue ExpressionTree { get; set; }
+ public double Value
+ {
+ get { return ExpressionTree.Value; }
+ }
+ public double[] MultiValue
+ {
+ get {
+ var t = ExpressionTree as MultiParameterList;
+ if (t != null)
+ {
+ double[] res = new double[t.Parameters.Length];
+ for (int i = 0; i < res.Length; i++)
+ res[i] = t.Parameters[i].Value;
+ return res;
+ }
+ return null;
+ }
+ }
+ public override string ToString()
+ {
+ return ExpressionTree.ToString();
+ }
+ public ExpressionDelegate ToDelegate(params string[] aParamOrder)
+ {
+ var parameters = new List(aParamOrder.Length);
+ for(int i = 0; i < aParamOrder.Length; i++)
+ {
+ if (Parameters.ContainsKey(aParamOrder[i]))
+ parameters.Add(Parameters[aParamOrder[i]]);
+ else
+ parameters.Add(null);
+ }
+ var parameters2 = parameters.ToArray();
+
+ return (p) => Invoke(p, parameters2);
+ }
+ public MultiResultDelegate ToMultiResultDelegate(params string[] aParamOrder)
+ {
+ var parameters = new List(aParamOrder.Length);
+ for (int i = 0; i < aParamOrder.Length; i++)
+ {
+ if (Parameters.ContainsKey(aParamOrder[i]))
+ parameters.Add(Parameters[aParamOrder[i]]);
+ else
+ parameters.Add(null);
+ }
+ var parameters2 = parameters.ToArray();
+
+
+ return (p) => InvokeMultiResult(p, parameters2);
+ }
+ double Invoke(double[] aParams, Parameter[] aParamList)
+ {
+ int count = System.Math.Min(aParamList.Length, aParams.Length);
+ for (int i = 0; i < count; i++ )
+ {
+ if (aParamList[i] != null)
+ aParamList[i].Value = aParams[i];
+ }
+ return Value;
+ }
+ double[] InvokeMultiResult(double[] aParams, Parameter[] aParamList)
+ {
+ int count = System.Math.Min(aParamList.Length, aParams.Length);
+ for (int i = 0; i < count; i++)
+ {
+ if (aParamList[i] != null)
+ aParamList[i].Value = aParams[i];
+ }
+ return MultiValue;
+ }
+ public static Expression Parse(string aExpression)
+ {
+ return new ExpressionParser().EvaluateExpression(aExpression);
+ }
+
+ public class ParameterException : System.Exception { public ParameterException(string aMessage) : base(aMessage) { } }
+ }
+ public delegate double ExpressionDelegate(params double[] aParams);
+ public delegate double[] MultiResultDelegate(params double[] aParams);
+
+
+
+ public class ExpressionParser
+ {
+ private List m_BracketHeap = new List();
+ private Dictionary> m_Consts = new Dictionary>();
+ private Dictionary> m_Funcs = new Dictionary>();
+ private Expression m_Context;
+
+ public ExpressionParser()
+ {
+ var rnd = new System.Random();
+ m_Consts.Add("PI", () => System.Math.PI);
+ m_Consts.Add("e", () => System.Math.E);
+ m_Funcs.Add("sqrt", (p) => System.Math.Sqrt(p.FirstOrDefault()));
+ m_Funcs.Add("abs", (p) => System.Math.Abs(p.FirstOrDefault()));
+ m_Funcs.Add("ln", (p) => System.Math.Log(p.FirstOrDefault()));
+ m_Funcs.Add("floor", (p) => System.Math.Floor(p.FirstOrDefault()));
+ m_Funcs.Add("ceiling", (p) => System.Math.Ceiling(p.FirstOrDefault()));
+ m_Funcs.Add("round", (p) => System.Math.Round(p.FirstOrDefault()));
+
+ m_Funcs.Add("sin", (p) => System.Math.Sin(p.FirstOrDefault()));
+ m_Funcs.Add("cos", (p) => System.Math.Cos(p.FirstOrDefault()));
+ m_Funcs.Add("tan", (p) => System.Math.Tan(p.FirstOrDefault()));
+
+ m_Funcs.Add("asin", (p) => System.Math.Asin(p.FirstOrDefault()));
+ m_Funcs.Add("acos", (p) => System.Math.Acos(p.FirstOrDefault()));
+ m_Funcs.Add("atan", (p) => System.Math.Atan(p.FirstOrDefault()));
+ m_Funcs.Add("atan2", (p) => System.Math.Atan2(p.FirstOrDefault(),p.ElementAtOrDefault(1)));
+ //System.Math.Floor
+ m_Funcs.Add("min", (p) => System.Math.Min(p.FirstOrDefault(), p.ElementAtOrDefault(1)));
+ m_Funcs.Add("max", (p) => System.Math.Max(p.FirstOrDefault(), p.ElementAtOrDefault(1)));
+ m_Funcs.Add("rnd", (p) =>
+ {
+ if (p.Length == 2)
+ return p[0] + rnd.NextDouble() * (p[1] - p[0]);
+ if (p.Length == 1)
+ return rnd.NextDouble() * p[0];
+ return rnd.NextDouble();
+ });
+ }
+
+ public void AddFunc(string aName, System.Func aMethod)
+ {
+ if (m_Funcs.ContainsKey(aName))
+ m_Funcs[aName] = aMethod;
+ else
+ m_Funcs.Add(aName, aMethod);
+ }
+
+ public void AddConst(string aName, System.Func aMethod)
+ {
+ if (m_Consts.ContainsKey(aName))
+ m_Consts[aName] = aMethod;
+ else
+ m_Consts.Add(aName, aMethod);
+ }
+ public void RemoveFunc(string aName)
+ {
+ if (m_Funcs.ContainsKey(aName))
+ m_Funcs.Remove(aName);
+ }
+ public void RemoveConst(string aName)
+ {
+ if (m_Consts.ContainsKey(aName))
+ m_Consts.Remove(aName);
+ }
+ public bool containgsConst(string name){
+ return m_Consts.ContainsKey (name);
+ }
+
+
+ int FindClosingBracket(ref string aText, int aStart, char aOpen, char aClose)
+ {
+ int counter = 0;
+ for (int i = aStart; i < aText.Length; i++)
+ {
+ if (aText[i] == aOpen)
+ counter++;
+ if (aText[i] == aClose)
+ counter--;
+ if (counter == 0)
+ return i;
+ }
+ return -1;
+ }
+
+ void SubstitudeBracket(ref string aExpression, int aIndex)
+ {
+ int closing = FindClosingBracket(ref aExpression, aIndex, '(', ')');
+ if (closing > aIndex + 1)
+ {
+ string inner = aExpression.Substring(aIndex + 1, closing - aIndex - 1);
+ m_BracketHeap.Add(inner);
+ string sub = "&" + (m_BracketHeap.Count - 1) + ";";
+ aExpression = aExpression.Substring(0, aIndex) + sub + aExpression.Substring(closing + 1);
+ }
+ else throw new ParseException("Bracket not closed!");
+ }
+
+ IValue Parse(string aExpression)
+ {
+ aExpression = aExpression.Trim();
+ int index = aExpression.IndexOf('(');
+ while (index >= 0)
+ {
+ SubstitudeBracket(ref aExpression, index);
+ index = aExpression.IndexOf('(');
+ }
+ if (aExpression.Contains(','))
+ {
+ string[] parts = aExpression.Split(',');
+ List exp = new List(parts.Length);
+ for (int i = 0; i < parts.Length; i++)
+ {
+ string s = parts[i].Trim();
+ if (!string.IsNullOrEmpty(s))
+ exp.Add(Parse(s));
+ }
+ return new MultiParameterList(exp.ToArray());
+ }
+ else if (aExpression.Contains('+'))
+ {
+ string[] parts = aExpression.Split('+');
+ List exp = new List(parts.Length);
+ for (int i = 0; i < parts.Length; i++)
+ {
+ string s = parts[i].Trim();
+ if (!string.IsNullOrEmpty(s))
+ exp.Add(Parse(s));
+ }
+ if (exp.Count == 1)
+ return exp[0];
+ return new OperationSum(exp.ToArray());
+ }
+ else if (aExpression.Contains('-'))
+ {
+ string[] parts = aExpression.Split('-');
+ List exp = new List(parts.Length);
+ if (!string.IsNullOrEmpty(parts[0].Trim()))
+ exp.Add(Parse(parts[0]));
+ for (int i = 1; i < parts.Length; i++)
+ {
+ string s = parts[i].Trim();
+ if (!string.IsNullOrEmpty(s))
+ exp.Add(new OperationNegate(Parse(s)));
+ }
+ if (exp.Count == 1)
+ return exp[0];
+ return new OperationSum(exp.ToArray());
+ }
+ else if (aExpression.Contains('*'))
+ {
+ string[] parts = aExpression.Split('*');
+ List exp = new List(parts.Length);
+ for (int i = 0; i < parts.Length; i++)
+ {
+ exp.Add(Parse(parts[i]));
+ }
+ if (exp.Count == 1)
+ return exp[0];
+ return new OperationProduct(exp.ToArray());
+ }
+ else if (aExpression.Contains('/'))
+ {
+ string[] parts = aExpression.Split('/');
+ List exp = new List(parts.Length);
+ if (!string.IsNullOrEmpty(parts[0].Trim()))
+ exp.Add(Parse(parts[0]));
+ for (int i = 1; i < parts.Length; i++)
+ {
+ if (parts[i].Trim() == "0")
+ throw new DivideByZeroException();
+
+ string s = parts[i].Trim();
+ if (!string.IsNullOrEmpty(s))
+ exp.Add(new OperationReciprocal(Parse(s)));
+ }
+ return new OperationProduct(exp.ToArray());
+ }
+ else if (aExpression.Contains('^'))
+ {
+ int pos = aExpression.IndexOf('^');
+ var val = Parse(aExpression.Substring(0, pos));
+ var pow = Parse(aExpression.Substring(pos + 1));
+ return new OperationPower(val, pow);
+ }
+ int pPos = aExpression.IndexOf("&");
+ if (pPos > 0)
+ {
+ string fName = aExpression.Substring(0, pPos);
+ foreach (var M in m_Funcs)
+ {
+ if (fName == M.Key)
+ {
+ var inner = aExpression.Substring(M.Key.Length);
+ var param = Parse(inner);
+ var multiParams = param as MultiParameterList;
+ IValue[] parameters;
+ if (multiParams != null)
+ parameters = multiParams.Parameters;
+ else
+ parameters = new IValue[] { param };
+ return new CustomFunction(M.Key, M.Value, parameters);
+ }
+ }
+ }
+ foreach (var C in m_Consts)
+ {
+ if (aExpression == C.Key)
+ {
+ return new CustomFunction(C.Key,(p)=>C.Value(),null);
+ }
+ }
+ int index2a = aExpression.IndexOf('&');
+ int index2b = aExpression.IndexOf(';');
+ if (index2a >= 0 && index2b >= 2)
+ {
+ var inner = aExpression.Substring(index2a + 1, index2b - index2a - 1);
+ int bracketIndex;
+ if (int.TryParse(inner, out bracketIndex) && bracketIndex >= 0 && bracketIndex < m_BracketHeap.Count)
+ {
+ return Parse(m_BracketHeap[bracketIndex]);
+ }
+ else
+ throw new ParseException("Can't parse substitude token");
+ }
+ double doubleValue;
+ if (double.TryParse(aExpression, out doubleValue))
+ {
+ return new Number(doubleValue);
+ }
+ if (ValidIdentifier(aExpression))
+ {
+ if (m_Context.Parameters.ContainsKey(aExpression))
+ return m_Context.Parameters[aExpression];
+ var val = new Parameter(aExpression);
+ m_Context.Parameters.Add(aExpression, val);
+ return val;
+ }
+
+ throw new ParseException("Reached unexpected end within the parsing tree");
+ }
+
+ private bool ValidIdentifier(string aExpression)
+ {
+ aExpression = aExpression.Trim();
+ if (string.IsNullOrEmpty(aExpression))
+ return false;
+ if (aExpression.Length < 1)
+ return false;
+ if (aExpression.Contains(" "))
+ return false;
+ if (!"abcdefghijklmnopqrstuvwxyz§$".Contains(char.ToLower(aExpression[0])))
+ return false;
+ if (m_Consts.ContainsKey(aExpression))
+ return false;
+ if (m_Funcs.ContainsKey(aExpression))
+ return false;
+ return true;
+ }
+
+ public Expression EvaluateExpression(string aExpression)
+ {
+ var val = new Expression();
+ m_Context = val;
+ val.ExpressionTree = Parse(aExpression);
+ m_Context = null;
+ m_BracketHeap.Clear();
+ return val;
+ }
+
+ public double Evaluate(string aExpression)
+ {
+ return EvaluateExpression(aExpression).Value;
+ }
+ public static double Eval(string aExpression)
+ {
+ return new ExpressionParser().Evaluate(aExpression);
+ }
+
+ public class ParseException : System.Exception { public ParseException(string aMessage) : base(aMessage) { } }
+ }
+}
diff --git a/LineParser/Parsers/SumParser/MathParser.cs b/LineParser/Parsers/SumParser/MathParser.cs
new file mode 100644
index 0000000..e161197
--- /dev/null
+++ b/LineParser/Parsers/SumParser/MathParser.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Compiler
+{
+ public class MathParser
+ {
+ public static readonly char[] mathOperators = { '+', '-', '/', '*', '%', '^'};
+ }
+}
+
diff --git a/LineParser/Parsers/SumParser/NumberSumParser.cs b/LineParser/Parsers/SumParser/NumberSumParser.cs
new file mode 100644
index 0000000..e515b1a
--- /dev/null
+++ b/LineParser/Parsers/SumParser/NumberSumParser.cs
@@ -0,0 +1,155 @@
+using System;
+using ErrorHandler;
+using System.Collections.Generic;
+using Runtime;
+
+namespace Compiler
+{
+ public class NumberSumParser{
+
+ public static Variable validNumberSum(Logic[] logicOrder, int lineNumber){
+ handleFirstAndLastWords(logicOrder, lineNumber);
+
+ logicOrder = calcPow (logicOrder, lineNumber);
+ logicOrder = calcModulo (logicOrder, lineNumber);
+
+ var calcString = LogicToCalcString(logicOrder, out bool corrupt);
+
+ if (!corrupt)
+ try{
+ double returnResult = SyntaxCheck.globalParser.Evaluate(calcString);
+ return new Variable ("calcVarMaten", returnResult, true);
+ }
+ catch(Exception e){
+ if (e is DivideByZeroException)
+ ErrorMessage.sendErrorMessage(lineNumber, "Kan inte dividera med noll!");
+ ErrorMessage.sendErrorMessage (lineNumber, "Något gick fel i uträkningen: " + e.ToString());
+ }
+
+
+ ErrorMessage.sendErrorMessage (lineNumber, "Något gick fel med nummertolkningen");
+ return new Variable ();
+ }
+
+ #region pow "**"
+ private static Logic[] calcPow(Logic[] logicOrder, int lineNumber){
+ List postPower = new List ();
+
+ for (int i = 0; i < logicOrder.Length; i++) {
+ if (logicOrder [i].currentType == WordTypes.mathOperator && logicOrder [i].word == "*" && i < logicOrder.Length - 1) {
+ if (logicOrder [i+1].currentType == WordTypes.mathOperator && logicOrder [i+1].word == "*") {
+ postPower.Add (new MathOperator ("^"));
+ i++;
+ }
+ else
+ postPower.Add (logicOrder[i]);
+ }
+ else
+ postPower.Add (logicOrder[i]);
+ }
+
+ return postPower.ToArray ();
+ }
+ #endregion
+
+
+ #region Modulo
+ private static Logic[] calcModulo(Logic[] logicOrder, int lineNumber){
+ List postModulo = new List ();
+
+ for (int i = 0; i < logicOrder.Length; i++) {
+
+ if (logicOrder [i].currentType == WordTypes.mathOperator && logicOrder [i].word == "%") {
+
+ if (i <= 0 || i >= logicOrder.Length - 1)
+ ErrorMessage.sendErrorMessage (lineNumber, "Modulo operatorn måste appliceras på två tal");
+
+ if(logicOrder[i-1].currentType != WordTypes.variable && logicOrder[i-1].currentType != WordTypes.number)
+ // Will not be reached because there can't be a number and a notNumber at the same row
+ ErrorMessage.sendErrorMessage (lineNumber, "Modulo operatorn måste appliceras på två tal");
+
+ double firstValue = getNumberValue (logicOrder [i - 1]);
+ double secondValue = getNumberValue (logicOrder [i + 1]);
+ double result = firstValue % secondValue;
+
+ postModulo.RemoveAt (postModulo.Count - 1);
+ postModulo.Add (new NumberValue (result));
+ i++;
+ }
+ else
+ postModulo.Add (logicOrder [i]);
+ }
+
+ return postModulo.ToArray ();
+ }
+
+ private static double getNumberValue(Logic l){
+ if (l.currentType == WordTypes.variable)
+ return (l as Variable).getNumber ();
+
+ return (l as NumberValue).value;
+ }
+ #endregion
+
+ private static void handleFirstAndLastWords(Logic[] logicOrder, int lineNumber){
+ string firstWord = logicOrder [0].word;
+ string lastWord = logicOrder [logicOrder.Length - 1].word;
+
+ if (lastWord == "*" || lastWord == "/")
+ ErrorMessage.sendErrorMessage (lineNumber, "Matematiska uttryck kan inte sluta med \"" + lastWord + "\"");
+ if (firstWord == "*" || firstWord == "/")
+ ErrorMessage.sendErrorMessage (lineNumber, "Matematiska uttryck kan inte börja med \"" + firstWord + "\"");
+
+ }
+
+ private static string LogicToCalcString(Logic[] logicOrder, out bool corrupt)
+ {
+ string calcString = "";
+ corrupt = false;
+
+ for (int i = 0; i < logicOrder.Length; i++)
+ {
+ if (logicOrder[i].currentType == WordTypes.variable)
+ {
+ if (shouldAddParenthesis(logicOrder, i))
+ calcString += "(" + (logicOrder[i] as Variable).getNumber() + ")";
+ else
+ calcString += (logicOrder[i] as Variable).getNumber().ToString();
+ }
+ else if (logicOrder[i].currentType == WordTypes.number)
+ {
+ if (shouldAddParenthesis(logicOrder, i))
+ {
+ calcString = calcString.Remove(calcString.Length - 1);
+ calcString += "(-" + logicOrder[i].word + ")";
+ }
+ else
+ calcString += logicOrder[i].word;
+ }
+ else if (logicOrder[i].currentType == WordTypes.mathOperator)
+ calcString += logicOrder[i].word;
+ else
+ corrupt = true;
+ }
+
+ return calcString;
+ }
+
+ private static bool shouldAddParenthesis(Logic[] logicOrder, int index)
+ {
+ if (index > 2 &&
+ logicOrder[index - 1].word == "-" &&
+ logicOrder[index - 2].currentType != WordTypes.number &&
+ logicOrder[index - 2].currentType != WordTypes.variable)
+ return true;
+
+ if (logicOrder[index].currentType == WordTypes.variable &&
+ (logicOrder[index] as Variable).variableType == VariableTypes.number &&
+ (logicOrder[index] as Variable).getNumber() < 0)
+ return true;
+ return false;
+ }
+ }
+
+}
+
diff --git a/LineParser/Parsers/SumParser/StatementParser.cs b/LineParser/Parsers/SumParser/StatementParser.cs
new file mode 100644
index 0000000..b5a26d8
--- /dev/null
+++ b/LineParser/Parsers/SumParser/StatementParser.cs
@@ -0,0 +1,157 @@
+using System;
+using ErrorHandler;
+using Runtime;
+
+namespace Compiler
+{
+ public class StatementParser{
+
+ public static bool parseAndCheckStatement(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ Variable sum = SumParser.parseIntoSum (logicOrder, lineNumber, currentScope);
+
+ if (sum.variableType == VariableTypes.number){
+ if (sum.getNumber() == 0)
+ return false;
+ else
+ return true;
+ }
+
+ if (sum.variableType == VariableTypes.textString) {
+ if (sum.getString () == "")
+ return false;
+ else
+ return true;
+ }
+
+ if (sum.variableType == VariableTypes.None)
+ return false;
+
+ if (sum.variableType != VariableTypes.boolean)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.IfStatements, IfErrorType.expressionNotCorrectType.ToString(), null);
+
+ return sum.getBool ();
+ }
+
+
+ public static bool parseStatement(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ BoolAlgebraWord[] algebra = BoolAlgebraParser.parseIntoBoolAlgebra (logicOrder, lineNumber, currentScope);
+ return BoolAlgebraParser.parseBoolAlgebraStatement (algebra, lineNumber);
+ }
+
+ public static bool parseExpression(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ #region findOperators
+ int operatorLow = -1;
+ int operatorHigh = -1;
+ int operatorAmount = 0;
+ for (int i = 0; i < logicOrder.Length; i++)
+ if (isStatementOperator (logicOrder [i])) {
+ if (operatorLow == -1)
+ operatorLow = i;
+ else
+ operatorHigh = i;
+ operatorAmount++;
+ }
+
+
+ #endregion
+
+
+ if (operatorAmount > 2 && operatorHigh - operatorLow != 1) {
+ ErrorMessage.sendErrorMessage (lineNumber, "I detta moment är det inte tillåtet att gör flera jämförelser direkt efter varandra. Använd \"and\" och \"or\" istället.");
+ }
+ if (operatorAmount == 0)
+ return handleOnlyValueStatement (logicOrder, lineNumber, currentScope);
+
+ if (operatorAmount == 2) {
+ if (operatorHigh - operatorLow != 1)
+ ErrorMessage.sendErrorMessage (lineNumber, "Operatorerna måste komma direkt efter varandra");
+ }
+ else
+ operatorHigh = operatorLow;
+
+
+
+
+
+ Logic[] leftSide = new Logic[operatorLow];
+ Logic[] rightSide = new Logic[logicOrder.Length - 1 - operatorHigh];
+ Logic[] operators = new Logic[operatorAmount];
+ setSidesOfStatement (logicOrder, leftSide, rightSide, operators, operatorLow, operatorHigh);
+
+
+ Variable firstSum = SumParser.parseIntoSum (leftSide, lineNumber, currentScope);
+ Variable secondSum = SumParser.parseIntoSum (rightSide, lineNumber, currentScope);
+ ComparisonType operatorType = ComparisonOperatorParser.parseOperators (operators);
+
+ if (operatorType == ComparisonType.unknown) {
+ if (operators[0].currentType == WordTypes.equalSign)
+ ErrorMessage.sendErrorMessage(lineNumber, "Fel vid tilldelning. Kom ihåg att använda == om du vill jämföra om två värden är lika.");
+ else
+ ErrorMessage.sendErrorMessage(lineNumber, "Operatorerna går inte att tyda");
+ }
+
+ if (firstSum.variableType == VariableTypes.unknown || secondSum.variableType == VariableTypes.unknown)
+ ErrorMessage.sendErrorMessage (lineNumber, "Korrupt värde");
+
+ if (firstSum.variableType != secondSum.variableType)
+ {
+ var firstSumType = SumParser.TypeToString(firstSum.variableType);
+ var secondSumType = SumParser.TypeToString(secondSum.variableType);
+
+ string errorMessage;
+
+ if (firstSumType == "" || secondSumType == "")
+ errorMessage = "Misslyckades med att jämföra " + firstSum.variableType + " med " + secondSum.variableType;
+ else
+ errorMessage = "Kan inte jämföra " + firstSumType + " med " + secondSumType + ".";
+
+ ErrorMessage.sendErrorMessage(lineNumber, errorMessage);
+ }
+
+ if (ComparisonOperatorParser.checkSumsToOperator(firstSum.variableType, operatorType,lineNumber)) {
+ bool resultOfComparison = ComparisonOperatorParser.makeComparison (firstSum, secondSum, operatorType, lineNumber);
+ return resultOfComparison;
+ }
+
+ ErrorMessage.sendErrorMessage (lineNumber, "Korrupt expression!");
+ return false;
+ }
+
+ public static bool isStatementOperator(Logic currentLogic){
+ if (currentLogic.currentType == WordTypes.equalSign)
+ return true;
+
+ if (currentLogic.currentType == WordTypes.lessThenSign || currentLogic.currentType == WordTypes.greaterThenSign)
+ return true;
+
+ if (currentLogic.currentType == WordTypes.xorOperator)
+ return true;
+
+ return false;
+ }
+
+
+ static void setSidesOfStatement(Logic[] logicOrder, Logic[] leftSide, Logic[] rightSide, Logic[] operators, int operatorLow, int operatorHigh){
+ for (int i = 0; i < leftSide.Length; i++)
+ leftSide [i] = logicOrder [i];
+
+ for (int i = operatorHigh+1; i < logicOrder.Length; i++)
+ rightSide [i - (operatorHigh+1)] = logicOrder [i];
+
+ for (int i = operatorLow; i <= operatorHigh; i++)
+ operators [i - operatorLow] = logicOrder [i];
+ }
+
+ static bool handleOnlyValueStatement(Logic[] logicOrder, int lineNumber, Scope currentScope){
+
+ Variable sum = SumParser.parseIntoSum (logicOrder, lineNumber, currentScope);
+
+ if (sum.variableType != VariableTypes.boolean)
+ ErrorMessage.sendErrorMessage (lineNumber, "När du skriver in endast ett värde, måste det vara Sant eller Falskt");
+
+ return sum.getBool ();
+ }
+ }
+
+}
+
diff --git a/LineParser/Parsers/SumParser/SumParser.cs b/LineParser/Parsers/SumParser/SumParser.cs
new file mode 100644
index 0000000..7a52b6f
--- /dev/null
+++ b/LineParser/Parsers/SumParser/SumParser.cs
@@ -0,0 +1,256 @@
+using System;
+using System.Linq;
+using ErrorHandler;
+using Runtime;
+
+namespace Compiler
+{
+ public class SumParser{
+
+
+ public static Variable parseIntoSum(Logic[] logicOrderInput, int lineNumber, Scope currentScope){
+ Logic[] logicOrder = (Logic[])logicOrderInput.Clone ();
+ UnpackPackages (logicOrder, lineNumber, currentScope);
+
+ logicOrder = BoolCompressExpressions.compressExpression (logicOrder, lineNumber, currentScope, true);
+ logicOrder = BoolExpressionParser.compressAndOrStatements (logicOrder, lineNumber, currentScope);
+
+ if (logicOrder.Length == 0)
+ return new Variable("CalcVar");
+
+ expectType theExpectedType = new expectType ();
+ calcSumType (logicOrder, theExpectedType, lineNumber, currentScope);
+ return getCalcSum (theExpectedType, logicOrder, lineNumber);
+ }
+
+ private static void UnpackPackages(Logic[] PrelogicOrder, int lineNumber, Scope currentScope){
+ for (int i = 0; i < PrelogicOrder.Length; i++)
+ if (PrelogicOrder [i].currentType == WordTypes.package) {
+ PrelogicOrder[i] = parseIntoSum ((PrelogicOrder[i] as Package).getLatestOrder(), lineNumber, currentScope);
+ }
+ }
+
+
+ private static void calcSumType(Logic[] logicOrder, expectType theExpectedType, int lineNumber, Scope currentScope){
+ for(int i = 0; i < logicOrder.Length; i++){
+ switch (logicOrder [i].currentType) {
+
+ #region values
+ case WordTypes.textString:
+ setNewExpectVariable (theExpectedType, VariableTypes.textString, lineNumber);
+ break;
+ case WordTypes.number:
+ setNewExpectVariable (theExpectedType, VariableTypes.number, lineNumber);
+ break;
+ case WordTypes.booleanValue:
+ setNewExpectVariable (theExpectedType, VariableTypes.boolean, lineNumber);
+ break;
+ #endregion
+
+ // booleanExpressions are for example a expression used in an if-statement
+ case WordTypes.booleanExpression:
+ logicOrder [i] = (logicOrder [i] as BooleanExpression).parseExpression ();
+ setNewExpectVariable (theExpectedType, VariableTypes.boolean, lineNumber);
+ break;
+
+ case WordTypes.variable:
+ handleVariable(logicOrder, theExpectedType, lineNumber, currentScope, i);
+ break;
+
+ case WordTypes.functionCall:
+ handleFunctionCall(logicOrder, theExpectedType, lineNumber, currentScope, i);
+ break;
+ }
+ }
+ }
+
+ private static void handleFunctionCall(Logic[] logicOrder, expectType theExpectedType, int lineNumber, Scope currentScope, int i){
+ FunctionParser.linkFunctionCall ((logicOrder [i] as FunctionCall), lineNumber, currentScope);
+
+ if ((logicOrder [i] as FunctionCall).targetFunc.isUserFunction) {
+ currentScope.getCurrentLine ().insertReturnExpect (logicOrder [i]);
+ (logicOrder [i] as FunctionCall).runFunction (currentScope);
+
+ throw new FunctionCallException ();
+ } else {
+ if ((logicOrder [i] as FunctionCall).targetFunc.pauseWalker)
+ CodeWalker.pauseWalker ();
+
+ if ((logicOrder[i] as FunctionCall).targetFunc.name == "input"){
+ CodeWalker.linkSubmitInput.Invoke(SubmitInput, currentScope);
+
+ Variable returnVariable = (logicOrder[i] as FunctionCall).runFunction(currentScope);
+ logicOrder[i] = returnVariable;
+
+ if (returnVariable.variableType == VariableTypes.boolean)
+ setNewExpectVariable(theExpectedType, VariableTypes.boolean, lineNumber);
+ else if (returnVariable.variableType == VariableTypes.number)
+ setNewExpectVariable(theExpectedType, VariableTypes.number, lineNumber);
+ else if (returnVariable.variableType == VariableTypes.textString)
+ setNewExpectVariable(theExpectedType, VariableTypes.textString, lineNumber);
+
+ CodeWalker.isWaitingForUserInput = true;
+ }
+ else {
+ Variable returnVariable = (logicOrder[i] as FunctionCall).runFunction(currentScope);
+ logicOrder[i] = returnVariable;
+
+ if (returnVariable.variableType == VariableTypes.boolean)
+ setNewExpectVariable(theExpectedType, VariableTypes.boolean, lineNumber);
+ else if (returnVariable.variableType == VariableTypes.number)
+ setNewExpectVariable(theExpectedType, VariableTypes.number, lineNumber);
+ else if (returnVariable.variableType == VariableTypes.textString)
+ setNewExpectVariable(theExpectedType, VariableTypes.textString, lineNumber);
+ }
+ }
+ }
+
+ private static void handleVariable(Logic[] logicOrder, expectType theExpectedType, int lineNumber, Scope currentScope, int i){
+ int varPos = currentScope.scopeVariables.containsVariable ((logicOrder [i] as Variable).name);
+ if (varPos >= 0) {
+ Variable foundVar = currentScope.scopeVariables.variableList [varPos];
+ setNewExpectVariable (theExpectedType, foundVar.variableType, lineNumber);
+ logicOrder [i] = foundVar;
+ }
+ else {
+ if ((logicOrder [i] as Variable).isCalcVar)
+ setNewExpectVariable (theExpectedType, (logicOrder [i] as Variable).variableType, lineNumber);
+ else{
+ if((logicOrder [i] as Variable).name.Length > 10)
+ ErrorMessage.sendErrorMessage (lineNumber, "Användning av icke deklarerad variabel!");
+
+ LevenshteinDist.checkForClosesVariable (logicOrder [i].word, lineNumber, currentScope);
+ ErrorMessage.sendErrorMessage (lineNumber, "Kunde inte hitta variabeln \"" + (logicOrder [i] as Variable).name + "\" i minnet.");
+ }
+ }
+ }
+
+ private static Variable getCalcSum(expectType theExpectedType, Logic[] logicOrder, int lineNumber){
+ if (theExpectedType.currentType == VariableTypes.boolean) {
+ Variable sumVar = BooleanSumParser.validBoolSum (logicOrder, lineNumber);
+ if (sumVar.variableType == VariableTypes.boolean)
+ return sumVar;
+ }
+
+ if (theExpectedType.currentType == VariableTypes.textString) {
+ Variable sumVar = TextSumParser.validTextSum (logicOrder, lineNumber);
+ if (sumVar.variableType == VariableTypes.textString)
+ return sumVar;
+ }
+
+ if (theExpectedType.currentType == VariableTypes.number) {
+ Variable sumVar = NumberSumParser.validNumberSum (logicOrder, lineNumber);
+ if (sumVar.variableType == VariableTypes.number)
+ return sumVar;
+ }
+
+ return new Variable ("CalcVar");
+ }
+
+ public static void SubmitInput(string inputFromUser, Scope currentScope){
+ if (!CodeWalker.isWaitingForUserInput)
+ return;
+
+ CodeWalker.isWaitingForUserInput = false;
+
+ var oldLine = currentScope.getCurrentLine().cloneLine();
+ var oldLineString = oldLine.getFullLine();
+ var newLine = ReplaceInputWithValue(oldLineString, inputFromUser);
+
+ var lines = SyntaxCheck.parseLines(newLine);
+ var words = lines.First().words;
+ var logic = WordsToLogicParser.determineLogicFromWords(words, 1, currentScope);
+
+ currentScope.getCurrentLine().words = words;
+ currentScope.getCurrentLine().logicOrder = logic;
+
+ CodeWalker.parseLine(currentScope.getCurrentLine(), oldLine);
+ }
+
+ private static string ReplaceInputWithValue(string currentLine, string value){
+ var currentCharIndex = 0;
+ var inputStartIndex = -1;
+ var inputEndIndex = -1;
+ var startedParanthesis = -1;
+
+ while (currentCharIndex < currentLine.Length){
+
+ if (currentLine[currentCharIndex] == 'i' && currentLine[currentCharIndex + 1] == 'n' && currentLine[currentCharIndex + 2] == 'p' &&
+ currentLine[currentCharIndex + 3] == 'u' && currentLine[currentCharIndex + 4] == 't' && currentLine[currentCharIndex + 5] == '('){
+
+ inputStartIndex = currentCharIndex;
+ startedParanthesis = 1;
+ currentCharIndex += 6;
+ }
+
+ if (currentLine[currentCharIndex] == '(')
+ startedParanthesis++;
+ else if (currentLine[currentCharIndex] == ')')
+ startedParanthesis--;
+
+ if (startedParanthesis == 0)
+ inputEndIndex = currentCharIndex + 1;
+
+ currentCharIndex++;
+ }
+
+ var subStringLength = inputEndIndex - inputStartIndex;
+ var subStringWithInput = currentLine.Substring(inputStartIndex, subStringLength);
+
+ var firstPartSubString = currentLine.Substring(0, inputStartIndex);
+ var secondPartSubString = currentLine.Substring(inputEndIndex);
+
+ var newLine = firstPartSubString + "\"" + value + "\"" + secondPartSubString;
+
+ return newLine;
+ }
+
+ #region Expected type
+ private class expectType
+ {
+ public VariableTypes currentType;
+ public expectType(){
+ currentType = VariableTypes.unsigned;
+ }
+ }
+
+ private static void setNewExpectVariable(expectType expect, VariableTypes newType, int lineNumber){
+ if (expect.currentType == VariableTypes.unsigned)
+ expect.currentType = newType;
+ else if (expect.currentType != newType) {
+ var firstSumType = TypeToString(expect.currentType);
+ var secondSumType = TypeToString(newType);
+
+ string errorMessage;
+
+ if (firstSumType == "" || secondSumType == "")
+ errorMessage = "Misslyckades med att para ihop " + expect.currentType + " med " + newType;
+ else
+ errorMessage = "Kan inte lägga ihop " + firstSumType + " med " + secondSumType + ".";
+
+ ErrorMessage.sendErrorMessage (lineNumber, errorMessage);
+ expect.currentType = VariableTypes.unknown;
+ }
+ }
+ #endregion
+
+ public static string TypeToString(VariableTypes variableType)
+ {
+ if (variableType == VariableTypes.number)
+ return "ett tal";
+ if (variableType == VariableTypes.textString)
+ return "en sträng";
+ if (variableType == VariableTypes.boolean)
+ return "ett boolskt värde";
+ if (variableType == VariableTypes.None)
+ return "None";
+ if (variableType == VariableTypes.unknown)
+ return "ett okänt värde";
+ if (variableType == VariableTypes.unsigned)
+ return "ett odefinierat värde";
+ return "";
+ }
+ }
+
+}
+
diff --git a/LineParser/Parsers/SumParser/TextSumParser.cs b/LineParser/Parsers/SumParser/TextSumParser.cs
new file mode 100644
index 0000000..606f3c1
--- /dev/null
+++ b/LineParser/Parsers/SumParser/TextSumParser.cs
@@ -0,0 +1,93 @@
+using System;
+using ErrorHandler;
+
+namespace Compiler
+{
+
+ internal class TextSumParser{
+
+ public static Variable validTextSum(Logic[] logicOrder, int lineNumber){
+
+ if (logicOrder.Length < 1)
+ return new Variable("Unknown Variable");
+
+
+ string returnValue = "";
+ bool corrupt = false;
+
+ for (int i = 0; i < logicOrder.Length; i++) {
+
+ if (i % 2 == 1) {
+ if (!isPlusSign (logicOrder [i], lineNumber)) {
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.Text, TextErrorType.expectedPlusSignBetweenStrings.ToString(), null);
+ corrupt = true;
+ break;
+ }
+ }
+ else {
+ if (isStringType (logicOrder [i], lineNumber))
+ returnValue += getStringValue (logicOrder [i]);
+
+ else {
+ // Can never reach this?
+ corrupt = true;
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.Text, TextErrorType.expectedATextValue.ToString(), null);
+ }
+ }
+ }
+
+
+ //Check so it ends with a String
+ if(isStringType( logicOrder[logicOrder.Length -1], lineNumber) == false){
+ corrupt = true;
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.Text, TextErrorType.expressionNeedsToEndWithAString.ToString(), null);
+ }
+
+
+ if (corrupt) {
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.System, SystemFailureErrorType.textParsingMalfunction.ToString(), null);
+ return new Variable ("Unknown Variable");
+ }
+ else
+ return new Variable ("TextVar", returnValue, true);
+ }
+
+
+
+ static bool isPlusSign(Logic currentLogic, int lineNumber){
+ if (currentLogic.currentType == WordTypes.mathOperator)
+ if ((currentLogic as MathOperator).word == "+")
+ return true;
+
+ return false;
+ }
+
+ static bool isStringType(Logic currentLogic, int lineNumber){
+ if (currentLogic.currentType == WordTypes.textString)
+ return true;
+
+ if (currentLogic.currentType == WordTypes.variable) {
+
+ if ((currentLogic as Variable).variableType == VariableTypes.textString)
+ return true;
+ }
+
+
+ return false;
+ }
+
+ static string getStringValue(Logic currentLogic){
+ if (currentLogic.currentType == WordTypes.textString)
+ return (currentLogic as TextValue).value;
+
+ if (currentLogic.currentType == WordTypes.variable)
+ if ((currentLogic as Variable).variableType == VariableTypes.textString)
+ return (currentLogic as Variable).getString();
+
+ return "";
+ }
+
+ }
+
+}
+
diff --git a/LineParser/Parsers/SumParser/ValidSumCheck.cs b/LineParser/Parsers/SumParser/ValidSumCheck.cs
new file mode 100644
index 0000000..6dcb0f9
--- /dev/null
+++ b/LineParser/Parsers/SumParser/ValidSumCheck.cs
@@ -0,0 +1,103 @@
+using System;
+using ErrorHandler;
+using Runtime;
+
+namespace Compiler
+{
+ public class ValidSumCheck{
+
+
+ public static Variable checkIfValidSum(Logic[] PrelogicOrder, int lineNumber){
+ Logic[] logicOrder = (Logic[])PrelogicOrder.Clone ();
+ UnpackPackages (logicOrder, lineNumber);
+
+ logicOrder = BoolCompressExpressions.compressExpression (logicOrder, lineNumber, null, false);
+ logicOrder = BoolExpressionParser.compressAndOrStatements (logicOrder, lineNumber, null);
+
+ if (logicOrder.Length == 0)
+ return new Variable("No var");
+
+ expectType theExpectedType = new expectType ();
+
+ for(int i = 0; i < logicOrder.Length; i++){
+
+ if(logicOrder[i].currentType == WordTypes.booleanExpression)
+ setNewExpectVariable (theExpectedType, VariableTypes.boolean, lineNumber, logicOrder);
+
+ else if (logicOrder [i].currentType == WordTypes.variable)
+ logicOrder [i] = new Variable (logicOrder [i].word);
+ else if (logicOrder [i].currentType == WordTypes.mathOperator) {
+
+ }
+ else if (logicOrder [i].currentType == WordTypes.number)
+ setNewExpectVariable (theExpectedType, VariableTypes.number, lineNumber, logicOrder);
+ else if (logicOrder [i].currentType == WordTypes.textString)
+ setNewExpectVariable (theExpectedType, VariableTypes.textString, lineNumber, logicOrder);
+ else if (logicOrder [i].currentType == WordTypes.booleanValue)
+ setNewExpectVariable (theExpectedType, VariableTypes.boolean, lineNumber, logicOrder);
+ }
+
+ if (theExpectedType.currentType == VariableTypes.unknown)
+ return new Variable ();
+
+ return theExpectedType.returnExpectedVariable();
+ }
+
+ private static void UnpackPackages(Logic[] PrelogicOrder, int lineNumber){
+ for(int i = 0; i < PrelogicOrder.Length; i++)
+ if (PrelogicOrder[i].currentType == WordTypes.package)
+ PrelogicOrder[i] = checkIfValidSum ((PrelogicOrder[i] as Package).getLatestOrder(), lineNumber);
+ }
+
+
+ #region Expect type
+ static void setNewExpectVariable(expectType expect, VariableTypes newType, int lineNumber, Logic[] logicOrder){
+ if (expect.currentType == VariableTypes.unknown)
+ return;
+
+ if (expect.currentType == VariableTypes.unsigned)
+ expect.currentType = newType;
+ else if (expect.currentType != newType)
+ {
+ var firstSumType = SumParser.TypeToString(expect.currentType);
+ var secondSumType = SumParser.TypeToString(newType);
+
+ string errorMessage;
+
+ if (firstSumType == "" || secondSumType == "")
+ errorMessage = "Misslyckades med att para ihop " + expect.currentType + " med " + newType;
+ else
+ errorMessage = "Kan inte para ihop " + firstSumType + " med " + secondSumType + ".";
+
+ ErrorMessage.sendErrorMessage (lineNumber, errorMessage);
+ }
+
+ if (expect.currentType == VariableTypes.boolean)
+ BooleanSumParser.validBoolSum (logicOrder, lineNumber);
+ }
+
+
+ private class expectType
+ {
+ public VariableTypes currentType;
+ public expectType(){
+ currentType = VariableTypes.unsigned;
+ }
+
+ public Variable returnExpectedVariable(){
+ if (currentType == VariableTypes.boolean)
+ return new Variable ("Type Variable", false);
+ if (currentType == VariableTypes.number)
+ return new Variable ("Type Variable", 0);
+ if (currentType == VariableTypes.textString)
+ return new Variable ("Type Variable", "");
+
+ return new Variable ("Type Variable");
+ }
+ }
+ #endregion
+
+ }
+
+}
+
diff --git a/LineParser/Parsers/Words.cs b/LineParser/Parsers/Words.cs
new file mode 100644
index 0000000..1cf659c
--- /dev/null
+++ b/LineParser/Parsers/Words.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace LineParser
+{
+ public class Words
+ {
+ public Words ()
+ {
+ }
+ }
+}
+
diff --git a/LineParser/Parsers/Words/WordParser.cs b/LineParser/Parsers/Words/WordParser.cs
new file mode 100644
index 0000000..55f2aec
--- /dev/null
+++ b/LineParser/Parsers/Words/WordParser.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+
+namespace Compiler
+{
+ public class WordParser {
+
+ //Parses entered text into a string array of all the seperate words entered
+
+ private static char[] saveOperators = { ':', '=', '!', ',', '>', '<' };
+
+ //Everything included into Parentheses will be returnd as ONE word.
+ //The logic for this word will later be *Package*.
+
+ internal static string[] parseWords(string trimedString){
+
+ List words = new List ();
+
+ int lastBreak = -1;
+ int foundLetters = 0;
+ int functionParantes = 0;
+ int functionQoutes = 0;
+ for (int i = 0; i < trimedString.Length; i++) {
+
+
+ //Checks if current Char is a "BreakWordChar" meaning it stops the current word recording.
+ if (isBreakWordChar (trimedString [i], functionParantes, functionQoutes)) {
+
+ if (foundLetters > 0) {
+ string temp = trimedString.Substring (lastBreak + 1, foundLetters);
+ words.Add (temp);
+ }
+
+ foundLetters = 0;
+ lastBreak = i;
+
+ //If the current breakchar is worth saving!
+ if (isSaveOperator (trimedString [i])) {
+ string temp = "";
+ temp += trimedString [i];
+ words.Add (temp);
+ }
+ } else {
+ functionQoutes = isInFunctionQuotes (trimedString [i], functionQoutes);
+ functionParantes += isInFunctionParameter (trimedString [i], foundLetters, functionQoutes);
+ foundLetters++;
+ }
+
+
+ }
+
+ if (foundLetters > 0) {
+ string temp = trimedString.Substring (lastBreak + 1, foundLetters);
+ words.Add (temp);
+ }
+
+
+ return words.ToArray ();
+ }
+
+
+
+
+ #region char checks
+ static bool isSaveOperator(char c){
+
+ foreach (char Operator in saveOperators)
+ if (c == Operator)
+ return true;
+
+ for(int i = 0; i < MathParser.mathOperators.Length; i++)
+ if(c == MathParser.mathOperators[i])
+ return true;
+
+ return false;
+ }
+
+
+ static int isInFunctionQuotes(char c, int functionQoutes){
+
+ if (c == '"') {
+ if (functionQoutes > 0)
+ return 0;
+ else
+ return 1;
+ }
+ return functionQoutes;
+
+ }
+
+ static int isInFunctionParameter(char c, int foundLetters, int functionQoutes){
+
+ if (functionQoutes > 0)
+ return 0;
+
+ if (c == '(')
+ return 1;
+
+ if (c == ')')
+ return -1;
+
+ return 0;
+ }
+
+
+ static bool isBreakWordChar(char c, int functionParantes, int functionQoutes){
+ if (c == '\n')
+ return true;
+
+ if (functionParantes > 0 || functionQoutes > 0)
+ return false;
+
+
+ if (c == ' ' || c == '\t')
+ return true;
+
+ if (c == ':' || c == '=' || c == '!' || c == ',' || c == '>' || c == '<' )
+ return true;
+
+
+ for(int i = 0; i < MathParser.mathOperators.Length; i++)
+ if(c == MathParser.mathOperators[i])
+ return true;
+
+ return false;
+ }
+ #endregion
+ }
+
+}
+
diff --git a/LineParser/Properties/AssemblyInfo.cs b/LineParser/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c00f166
--- /dev/null
+++ b/LineParser/Properties/AssemblyInfo.cs
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle ("Compiler")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("")]
+[assembly: AssemblyCopyright ("FreddeFrallan")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion ("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/LineParser/Runtime/CodeWalker.cs b/LineParser/Runtime/CodeWalker.cs
new file mode 100644
index 0000000..3f5b8a7
--- /dev/null
+++ b/LineParser/Runtime/CodeWalker.cs
@@ -0,0 +1,282 @@
+using Compiler;
+using ErrorHandler;
+using System;
+using System.Linq;
+
+namespace Runtime
+{
+ public class CodeWalker
+ {
+ private static Scope currentScope;
+ private static int currentLineIndex = 0;
+ private static Scope returnTarget;
+ private static bool isReturning = false;
+
+ public static bool switchedToUserFunc = false;
+ public static bool isWaitingForUserInput;
+
+ internal static Action doEndWalker, pauseWalker, activateFunctionColor;
+ internal static Action, Scope> linkSubmitInput;
+ static Action showCurrentActiveCodeLine;
+
+ #region initWalker
+ ///
+ /// Setup for CodeWalker.
+ ///
+ public static void setActions(Action endWalker, Action walkerPause, Action, Scope> linkInputTrigger, Action funcColor, Action showCurrentLine, Scope main){
+ doEndWalker = endWalker;
+ pauseWalker = walkerPause;
+ linkSubmitInput = linkInputTrigger;
+ activateFunctionColor = funcColor;
+ showCurrentActiveCodeLine = showCurrentLine;
+ currentScope = main;
+ isWaitingForUserInput = false;
+ currentLineIndex = 0;
+ }
+ #endregion
+
+
+ #region runtime
+ public static void parseLine(){
+ if (handleReturn ())
+ return;
+
+ if (currentLineIndex >= currentScope.codeLines.Count)
+ if (currentScope.parentScope == null) {
+ doEndWalker.Invoke ();
+ return;
+ }
+ else {
+ SetFinalScopeCommands (false, currentScope.codeLines[currentScope.codeLines.Count-1].lineNumber);
+ return;
+ }
+
+ if (!isWaitingForUserInput)
+ currentScope.lastReadLine = currentLineIndex;
+
+ CodeLine currentLine = currentScope.getCurrentLine ();
+
+ if (currentLine.logicOrder [0] is ScopeStarter) {
+
+ if ((currentLine.logicOrder [0] as ScopeStarter).doParseLine == false) {
+ currentLineIndex++;
+ parseLine();
+ return;
+ }
+ }
+
+ showCurrentActiveCodeLine.Invoke (currentLine.lineNumber);
+
+ try{
+ currentLine.theCommandType = parseCommandType (currentLine.lineNumber, currentScope);
+ }
+ catch(Exception e){
+ if (e is FunctionCallException)
+ return;
+ throw e;
+ }
+
+ if (!isWaitingForUserInput)
+ {
+ ReturnMemoryClear.clearLineMemory (currentLine);
+
+ //Enter New Scope
+ if ((currentLine.logicOrder[0] is ScopeStarter) && NTScopeStarter (currentLine))
+ return;
+
+ VariableWindow.sendStackVariables (currentScope);
+ currentLineIndex++;
+ }
+ }
+
+ public static void parseLine(CodeLine currentLine, CodeLine originalLine){
+ if (handleReturn())
+ return;
+
+ if (currentLineIndex >= currentScope.codeLines.Count)
+ if (currentScope.parentScope == null)
+ {
+ doEndWalker.Invoke();
+ return;
+ }
+ else
+ {
+ SetFinalScopeCommands(false, currentScope.codeLines[currentScope.codeLines.Count - 1].lineNumber);
+ return;
+ }
+
+ currentScope.lastReadLine = currentLineIndex;
+
+ if (currentLine.logicOrder[0] is ScopeStarter){
+
+ if ((currentLine.logicOrder[0] as ScopeStarter).doParseLine == false)
+ {
+ currentLineIndex++;
+ parseLine();
+ return;
+ }
+ }
+
+ showCurrentActiveCodeLine.Invoke(currentLine.lineNumber);
+
+ try{
+ currentLine.theCommandType = parseCommandType(currentLine.lineNumber, currentScope);
+ }
+ catch (Exception e){
+ if (e is FunctionCallException)
+ return;
+ throw e;
+ }
+
+ ReturnMemoryClear.clearLineMemory(currentLine);
+
+ //Enter New Scope
+ if ((currentLine.logicOrder[0] is ScopeStarter) && NTScopeStarter(currentLine))
+ return;
+
+ VariableWindow.sendStackVariables(currentScope);
+ currentLineIndex++;
+
+ // Reset current line so input can be run again if line is inside loop
+ currentScope.setCurrentLine(originalLine);
+ }
+ #endregion
+
+
+ #region internal public methods
+ internal static void switchToUserFunc(Scope current, Scope target){
+ switchedToUserFunc = true;
+ target.parentScope = current;
+ setScopeToParse (target, current);
+ }
+
+ internal static void setScopeToParse(Scope newScope, Scope parentScope){
+ newScope.parentScope = parentScope;
+ currentScope = newScope;
+ currentLineIndex = 0;
+ }
+
+ internal static void breakLoop(Scope targetLoop, int lineNumber){
+ currentScope.upInheritVariable (targetLoop);
+ currentScope = targetLoop;
+ SetFinalScopeCommands (true, lineNumber);
+ throw new FunctionCallException();
+ }
+
+ internal static void continueLoop(Scope targetLoop, int lineNumber){
+ currentScope.upInheritVariable (targetLoop);
+ currentScope = targetLoop;
+ SetFinalScopeCommands (false, lineNumber);
+ throw new FunctionCallException();
+ }
+ #endregion
+
+
+
+ #region runtime backend logic
+
+ #region finalCommands
+ private static void SetFinalScopeCommands(bool forceQuit, int lineNumber){
+
+ if ((currentScope.theScopeType == ScopeType.forLoop || currentScope.theScopeType == ScopeType.whileLoop)) {
+ bool doLoopAgain = forceQuit ? false : (currentScope.theScoopLoop as Loop).makeComparison (currentScope.codeLines [0].lineNumber);
+ if (doLoopAgain) {
+ currentLineIndex = 0;
+ return;
+ }
+ }
+
+ if (currentScope.theScopeType != ScopeType.main) {
+ currentScope = findTargetParentScope (currentScope, lineNumber);
+ currentLineIndex = currentScope.lastReadLine + 1;
+ parseLine ();
+ }
+ else
+ doEndWalker.Invoke ();
+ }
+
+
+ private static Scope findTargetParentScope(Scope currentScope, int lineNumber){
+ if (currentScope.parentScope == null)
+ ErrorMessage.sendErrorMessage (lineNumber, "Parent scope is missing");
+
+ if (currentScope.theScopeType != ScopeType.function)
+ currentScope.upInheritVariable (currentScope.parentScope);
+
+ if (currentScope.parentScope.lastReadLine != currentScope.parentScope.codeLines.Count - 1 || currentScope.parentScope.theScopeType == ScopeType.main)
+ return currentScope.parentScope;
+
+ if (currentScope.parentScope.theScoopLoop != null && (currentScope.parentScope.theScoopLoop as Loop).makeComparison (lineNumber)) {
+ currentScope.parentScope.lastReadLine = -1;
+ return currentScope.parentScope;
+ }
+
+ return findTargetParentScope (currentScope.parentScope, lineNumber);
+ }
+ #endregion
+
+
+ private static Logic parseCommandType(int lineNumber, Scope currentScope){
+ CodeLine currentLine = currentScope.getCurrentLine ();
+ Logic[] logicOrder = currentLine.getLatestOrder();
+ checkForUnknown (logicOrder, lineNumber);
+
+ Logic result = VariableDeclareParser.checkForVariableDecleration (logicOrder, lineNumber, currentScope);
+ if(result.currentType != WordTypes.unknown)
+ return result;
+
+ result = SpecialWordParser.parseSpecialLine (logicOrder, lineNumber, currentScope);
+ if(result.currentType != WordTypes.unknown)
+ return result;
+
+ result = PureFunctionCallParser.parsePureFunctionCall (logicOrder, lineNumber, currentScope);
+ if(result.currentType != WordTypes.unknown)
+ return result;
+
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.System, SystemFailureErrorType.unknownLogic.ToString(), new string[]{"2"});
+ return new UnknownLogic(lineNumber);
+ }
+
+ private static void checkForUnknown(Logic[] logicOrder, int lineNumber){
+ foreach (Logic L in logicOrder)
+ if (L.currentType == WordTypes.unknown)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.System, SystemFailureErrorType.unknownLogic.ToString(), new string[]{"3"});
+ }
+
+ private static bool NTScopeStarter(CodeLine tempLine){
+ Logic currentScopeStarter = tempLine.theCommandType;
+
+
+ if((currentScopeStarter as ScopeStarter).doEnterScope){
+ Scope targetScope = (currentScopeStarter as ScopeStarter).getTargetScope();
+ targetScope.scopeFunctions.savedFunctions = currentScope.scopeFunctions.getShallowCopy();
+ targetScope.giveInheritVariables (currentScope.scopeVariables.variableList);
+ setScopeToParse (targetScope, currentScope);
+ return true;
+ }
+ return false;
+ }
+
+
+ private static bool handleReturn(){
+ if (isReturning == false)
+ return false;
+
+ currentLineIndex = returnTarget.lastReadLine;
+ currentScope = returnTarget;
+
+ isReturning = false;
+ return true;
+ }
+
+ public static void setReturnTarget(Scope newReturnTarget){
+ isReturning = true;
+ returnTarget = newReturnTarget;
+ }
+
+ #endregion
+
+
+ }
+}
+
diff --git a/LineParser/Runtime/Commands/BreakAndContinueStatementParser.cs b/LineParser/Runtime/Commands/BreakAndContinueStatementParser.cs
new file mode 100644
index 0000000..941cbb0
--- /dev/null
+++ b/LineParser/Runtime/Commands/BreakAndContinueStatementParser.cs
@@ -0,0 +1,42 @@
+using System;
+using ErrorHandler;
+using Runtime;
+
+namespace Compiler
+{
+ public class BreakAndContinueStatementParser
+ {
+ public static Logic parseContinueStatement(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ //We use a shallow copy because we alter logicOrder in case of speciall operators
+ Logic[] cloneLogicOrder = (Logic[])logicOrder.Clone ();
+ if (cloneLogicOrder.Length != 1 || cloneLogicOrder[0].currentType != WordTypes.continueStatement)
+ return new UnknownLogic (lineNumber);
+
+ CodeWalker.continueLoop (findParentLoop (currentScope, lineNumber), lineNumber);
+ return new Variable ();
+ }
+
+ public static Logic parseBreakStatement(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ //We use a shallow copy because we alter logicOrder in case of speciall operators
+ Logic[] cloneLogicOrder = (Logic[])logicOrder.Clone ();
+ if (cloneLogicOrder.Length != 1 || cloneLogicOrder[0].currentType != WordTypes.breakStatement)
+ return new UnknownLogic (lineNumber);
+
+ CodeWalker.breakLoop (findParentLoop (currentScope, lineNumber), lineNumber);
+ return new Variable ();
+ }
+
+
+
+ private static Scope findParentLoop(Scope currentScope, int lineNumber){
+ if (currentScope.theScopeType == ScopeType.forLoop || currentScope.theScopeType == ScopeType.whileLoop)
+ return currentScope;
+
+ if (currentScope.parentScope == null || currentScope.parentScope.theScopeType == ScopeType.function)
+ ErrorMessage.sendErrorMessage (lineNumber, "Du kan endast använda break i en loop");
+
+ return findParentLoop (currentScope.parentScope, lineNumber);
+ }
+ }
+}
+
diff --git a/LineParser/Runtime/Commands/PureFunctionCallParser.cs b/LineParser/Runtime/Commands/PureFunctionCallParser.cs
new file mode 100644
index 0000000..0f9aebf
--- /dev/null
+++ b/LineParser/Runtime/Commands/PureFunctionCallParser.cs
@@ -0,0 +1,32 @@
+using System;
+using Compiler;
+
+namespace Runtime
+{
+ public class PureFunctionCallParser
+ {
+ public static Logic parsePureFunctionCall(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ if (logicOrder.Length != 1)
+ return new UnknownLogic(lineNumber);
+
+ if (logicOrder [0].currentType == WordTypes.functionCall) {
+ FunctionCall tempCall = (logicOrder [0] as FunctionCall);
+ FunctionParser.linkFunctionCall (tempCall, lineNumber, currentScope);
+
+
+ if (tempCall.targetFunc.pauseWalker)
+ CodeWalker.pauseWalker ();
+
+ tempCall.runFunction (currentScope);
+
+ if(tempCall.targetFunc.isUserFunction)
+ throw new FunctionCallException ();
+
+ return tempCall;
+ }
+ else
+ return new UnknownLogic(lineNumber);
+ }
+ }
+}
+
diff --git a/LineParser/Runtime/Commands/ReturnStatementCommand.cs b/LineParser/Runtime/Commands/ReturnStatementCommand.cs
new file mode 100644
index 0000000..c3313ac
--- /dev/null
+++ b/LineParser/Runtime/Commands/ReturnStatementCommand.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace LineParser
+{
+ public class ReturnStatementCommand
+ {
+ public ReturnStatementCommand ()
+ {
+ }
+ }
+}
+
diff --git a/LineParser/Runtime/Commands/SpecialVariableDeclare/TextSpeciallVariableDeclare.cs b/LineParser/Runtime/Commands/SpecialVariableDeclare/TextSpeciallVariableDeclare.cs
new file mode 100644
index 0000000..98006e1
--- /dev/null
+++ b/LineParser/Runtime/Commands/SpecialVariableDeclare/TextSpeciallVariableDeclare.cs
@@ -0,0 +1,53 @@
+using System;
+using ErrorHandler;
+using Runtime;
+
+namespace Compiler
+{
+ public class TextSpeciallVariableDeclare
+ {
+
+
+ internal static Variable handleTextVariable(Logic[] cloneLogicOrder, int lineNumber, Variable afterEqualSign, Scope currentScope, string variableName){
+ Variable returnVar = new Variable(variableName, "");
+ string originalStringValue = (cloneLogicOrder [0] as Variable).getString ();
+
+ if (afterEqualSign.variableType == VariableTypes.number)
+ return handleNumberValue (cloneLogicOrder, returnVar, afterEqualSign, originalStringValue, lineNumber);
+
+ else if (afterEqualSign.variableType == VariableTypes.textString)
+ return handeTextValue (cloneLogicOrder, returnVar, afterEqualSign, originalStringValue, lineNumber);
+
+
+ // ErrorMessage.sendErrorMessage (lineNumber, "Ogiltig använding av extra operatorer");
+ return returnVar;
+ }
+
+
+ private static Variable handeTextValue(Logic[] cloneLogicOrder, Variable returnVar, Variable afterEqualSign, string originalStringValue, int lineNumber){
+ if (cloneLogicOrder [1].word != "+")
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, "När du använder extra operatorer på en text variabel med en annan text kan du endast använda \"+\"");
+
+ returnVar.setValue (originalStringValue + afterEqualSign.getString());
+ return returnVar;
+ }
+
+
+ private static Variable handleNumberValue(Logic[] cloneLogicOrder, Variable returnVar, Variable afterEqualSign, string originalStringValue, int lineNumber){
+ if (cloneLogicOrder [1].word != "*")
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, "När du använder extra operatorer på en text variabel med en siffra kan du endast använda \"*\"");
+
+ if (afterEqualSign.getNumber() % 1 != 0)
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, "Du kan endast multiplicera strängar med heltal");
+
+ if (afterEqualSign.getNumber() <= 0)
+ return returnVar;
+
+ for (int i = 0; i < afterEqualSign.getNumber (); i++)
+ returnVar.setValue (returnVar.getString () + originalStringValue);
+
+ return returnVar;
+ }
+ }
+}
+
diff --git a/LineParser/Runtime/Commands/SpeciallVariableDeclareParser.cs b/LineParser/Runtime/Commands/SpeciallVariableDeclareParser.cs
new file mode 100644
index 0000000..c7a3f5b
--- /dev/null
+++ b/LineParser/Runtime/Commands/SpeciallVariableDeclareParser.cs
@@ -0,0 +1,56 @@
+using System;
+using ErrorHandler;
+using Compiler;
+
+namespace Runtime
+{
+ public class SpeciallVariableDeclareParser
+ {
+
+ internal static Variable speciallVariableDeclare(Logic[] cloneLogicOrder, int lineNuber, Variable afterEqualSign, Scope currentScope){
+ string variableName = cloneLogicOrder [0].word;
+
+ if (cloneLogicOrder [1].currentType != WordTypes.mathOperator)
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNuber, "Extra operator måste vara en matteoperator");
+
+ int varPos = currentScope.scopeVariables.containsVariable (cloneLogicOrder [0].word);
+ if(varPos < 0)
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNuber, "För att kunna använda extra operatorer måste variabeln med namn \"" + cloneLogicOrder[0].word + "\" redan vara deklarerad ");
+ cloneLogicOrder [0] = currentScope.scopeVariables.variableList [varPos];
+
+ if ((cloneLogicOrder [0] as Variable).variableType == VariableTypes.number)
+ return handleNumberVariable (cloneLogicOrder, lineNuber, afterEqualSign, currentScope);
+
+ if ((cloneLogicOrder [0] as Variable).variableType == VariableTypes.textString)
+ return TextSpeciallVariableDeclare.handleTextVariable (cloneLogicOrder, lineNuber, afterEqualSign, currentScope, variableName);
+
+
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNuber, "Endast variabler med Nummer eller Text kan använda extra operatorer");
+
+ return new Variable ("Temp");
+ }
+
+
+ private static Variable handleNumberVariable(Logic[] cloneLogicOrder, int lineNumber, Variable tempSum, Scope currentScope){
+ Logic[] calcSum = new Logic[3];
+ calcSum [0] = cloneLogicOrder [0];
+ calcSum [1] = cloneLogicOrder [1];
+ calcSum [2] = new NumberValue (tempSum.getNumber().ToString());
+ Variable tempVar = SumParser.parseIntoSum (calcSum, lineNumber, currentScope);
+
+ tempVar.name = (calcSum [0] as Variable).name;
+
+ return tempVar;
+ }
+
+ [System.Obsolete("This function should not be in use", true)]
+ private static Variable getAfterEqualSignSum(Logic[] cloneLogicOrder, int lineNuber, Scope currentScope){
+ Logic[] afterEqualSign = InternalParseFunctions.getSubArray(cloneLogicOrder, 3, cloneLogicOrder.Length-1, lineNuber);
+
+ //Debugger.printLogicOrder (afterEqualSign, "Checking how dis turns out");
+ return new Variable ();
+ }
+
+ }
+}
+
diff --git a/LineParser/Runtime/Commands/VariableDeclareParser.cs b/LineParser/Runtime/Commands/VariableDeclareParser.cs
new file mode 100644
index 0000000..d7cdf82
--- /dev/null
+++ b/LineParser/Runtime/Commands/VariableDeclareParser.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Linq;
+using System.Collections;
+using Compiler;
+
+
+namespace Runtime
+{
+ public class VariableDeclareParser{
+
+
+ public static Logic checkForVariableDecleration(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ //We use a shallow copy because we alter logicOrder in case of speciall operators
+ Logic[] cloneLogicOrder = (Logic[])logicOrder.Clone ();
+
+ if(couldBeVariableDec(cloneLogicOrder, lineNumber) == false)
+ return new UnknownLogic(lineNumber);
+
+
+ Logic[] afterEqualSign = getAfterEqualSign (cloneLogicOrder, lineNumber, currentScope);
+ if(afterEqualSign == null || afterEqualSign.Length == 0)
+ return new UnknownLogic(lineNumber);
+
+ Variable afterEqualSignSum = SumParser.parseIntoSum (afterEqualSign, lineNumber, currentScope);
+
+ //Determine whether to use speciallOperators or not
+ if (cloneLogicOrder [1].currentType != WordTypes.equalSign)
+ afterEqualSignSum = SpeciallVariableDeclareParser.speciallVariableDeclare (cloneLogicOrder, lineNumber, afterEqualSignSum, currentScope);
+ else
+ afterEqualSignSum.name = (cloneLogicOrder[0] as Variable).name;
+
+ //Add the newly declared variable
+ if (afterEqualSignSum.variableType != VariableTypes.unknown) {
+ currentScope.scopeVariables.addVariable(afterEqualSignSum, currentScope.scopeParser, lineNumber);
+ return afterEqualSignSum;
+ }
+
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, "Något gick fel i variabeldeklareringen");
+ return new UnknownLogic(lineNumber);
+ }
+
+
+
+ #region Basic Checks
+ private static bool couldBeVariableDec(Logic[] cloneLogicOrder, int lineNumber){
+ if (cloneLogicOrder.Length < 3)
+ return false;
+
+ if (cloneLogicOrder [0].currentType != WordTypes.variable)
+ return false;
+
+ return true;
+ }
+ #endregion
+
+
+
+
+ #region getLogicAfterEqualSign
+ private static Logic[] getAfterEqualSign(Logic[] cloneLogicOrder, int lineNumber, Scope currentScope){
+
+ int equalPos = getEqualPos (cloneLogicOrder);
+ if ((equalPos != 1 && equalPos != 2))
+ return null;
+
+
+ Logic[] afterEqualSign = new Logic[cloneLogicOrder.Length - (equalPos+1)];
+ for (int i = equalPos+1; i < cloneLogicOrder.Length; i++)
+ afterEqualSign [i-(equalPos+1)] = cloneLogicOrder [i];
+
+ return afterEqualSign;
+ }
+
+
+ private static int getEqualPos(Logic[] logicOrder){
+ int equalPos = 0;
+ for (int i = 0; i < logicOrder.Length; i++, equalPos++)
+ if (logicOrder [i].currentType == WordTypes.equalSign)
+ break;
+
+ return equalPos;
+ }
+ #endregion
+ }
+}
+
diff --git a/LineParser/Runtime/Debugger.cs b/LineParser/Runtime/Debugger.cs
new file mode 100644
index 0000000..0888e57
--- /dev/null
+++ b/LineParser/Runtime/Debugger.cs
@@ -0,0 +1,34 @@
+using System;
+using Compiler;
+
+namespace Runtime
+{
+ public class Debugger
+ {
+
+ public static void printLogicOrder(Logic[] logicOrder, string message){
+ Print.print (message + "************");
+ foreach (Logic l in logicOrder)
+ Print.print (l.currentType.ToString ());
+ Print.print ("*********************");
+ }
+
+ public static void printStackTrace(Scope currentScope){
+ string stackString = "";
+
+ Scope tempScope = currentScope;
+ while (tempScope != null) {
+ if (tempScope.theScopeType == ScopeType.main || tempScope.theScopeType == ScopeType.function)
+ stackString += tempScope.theScopeType.ToString () + " - ";
+
+ tempScope = tempScope.parentScope;
+ }
+
+ Print.print ("Stack trace: ******");
+ Print.print (stackString);
+ Print.print ("**********");
+ }
+
+ }
+}
+
diff --git a/LineParser/Runtime/Print.cs b/LineParser/Runtime/Print.cs
new file mode 100644
index 0000000..37da22f
--- /dev/null
+++ b/LineParser/Runtime/Print.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Runtime
+{
+ public class Print
+ {
+ public static Action printFunction;
+
+ internal static void print(string message){
+ printFunction.Invoke (message);
+ }
+ }
+}
+
diff --git a/LineParser/Runtime/Stack/ReturnMemoryClear.cs b/LineParser/Runtime/Stack/ReturnMemoryClear.cs
new file mode 100644
index 0000000..1a9d983
--- /dev/null
+++ b/LineParser/Runtime/Stack/ReturnMemoryClear.cs
@@ -0,0 +1,39 @@
+using System;
+
+namespace Compiler
+{
+ public class ReturnMemoryClear
+ {
+ public static void clearLineMemory(CodeLine currentLine){
+ searchLogicOrder(currentLine.getLatestOrder());
+ currentLine.resetCalculations ();
+ }
+
+ private static void searchLogicOrder(Logic[] logicOrder){
+ foreach (Logic l in logicOrder)
+ if (l.currentType == WordTypes.package)
+ clearPackageMemory (l as Package);
+ else if(l.currentType == WordTypes.functionCall)
+ clearFuncCallMemory (l as FunctionCall);
+ }
+
+
+ private static void clearPackageMemory(Package thePackage){
+ searchLogicOrder(thePackage.getLatestOrder());
+ thePackage.resetCalculations ();
+ }
+
+
+ private static void clearFuncCallMemory(FunctionCall theFuncCall){
+ if (theFuncCall.returnCalculations == null)
+ return;
+
+ foreach(Logic[] l in theFuncCall.returnCalculations)
+ searchLogicOrder(l);
+
+ theFuncCall.resetCalculations ();
+ }
+
+ }
+}
+
diff --git a/LineParser/Runtime/Stack/ReturnMemoryControll.cs b/LineParser/Runtime/Stack/ReturnMemoryControll.cs
new file mode 100644
index 0000000..b1efeaf
--- /dev/null
+++ b/LineParser/Runtime/Stack/ReturnMemoryControll.cs
@@ -0,0 +1,135 @@
+using System;
+using ErrorHandler;
+using Runtime;
+
+namespace Compiler
+{
+ public class ReturnMemoryControll
+ {
+ public static void insertReturnExpectation(CodeLine currentLine, int lineNumber, Logic targetLogic){
+ if (currentLine.returnCalculations == null)
+ currentLine.returnCalculations = (Logic[])currentLine.logicOrder.Clone ();
+
+ Logic[] tempOrder = (Logic[])currentLine.getLatestOrder();
+
+ searchInLogicOrderExpect (tempOrder, lineNumber, targetLogic);
+ }
+
+
+ private static bool searchInLogicOrderExpect(Logic[] logicOrder, int lineNumber, Logic targetLogic){
+ for (int i = 0; i < logicOrder.Length; i++)
+ if (logicOrder [i] == targetLogic) {
+ logicOrder [i] = new ReturnValue();
+
+ return true;
+ }
+ else if (logicOrder [i].currentType == WordTypes.package) {
+ if (insertReturnValueIntoPackageExpect (logicOrder[i] as Package, lineNumber, targetLogic))
+ return true;
+ }
+ else if (logicOrder [i].currentType == WordTypes.functionCall) {
+ if (insertReturnValueIntoFuncCallExpect (logicOrder[i] as FunctionCall, lineNumber, targetLogic))
+ return true;
+ }
+
+ return false;
+ }
+
+
+
+ private static bool insertReturnValueIntoPackageExpect(Package thePackage, int lineNumber, Logic targetLogic){
+ if (thePackage.returnCalculations == null)
+ thePackage.returnCalculations = (Logic[])thePackage.logicOrder.Clone ();
+
+ Logic[] tempOrder = thePackage.getLatestOrder();
+ return searchInLogicOrderExpect (tempOrder, lineNumber, targetLogic);
+ }
+
+
+
+
+ private static bool insertReturnValueIntoFuncCallExpect(FunctionCall theFuncCall, int lineNumber, Logic targetLogic){
+ if (theFuncCall.returnCalculations == null)
+ return false;
+
+
+ foreach (Logic[] l in theFuncCall.returnCalculations) {
+ if (searchInLogicOrderExpect (l, lineNumber, targetLogic))
+ return true;
+ }
+
+ return false;
+ }
+
+
+
+
+
+ //**********************************
+
+ public static void insertReturnValue(CodeLine currentLine, int lineNumber, Variable returnVar){
+ Logic[] tempOrder = currentLine.getLatestOrder();
+
+ // Debugger.printLogicOrder (tempOrder, "Return insert Order");
+
+ searchInLogicOrder (tempOrder, lineNumber, returnVar);
+ }
+
+
+ private static bool searchInLogicOrder(Logic[] logicOrder, int lineNumber, Variable returnVar){
+
+ for (int i = 0; i < logicOrder.Length; i++)
+ if (logicOrder [i].currentType == WordTypes.returnValue) {
+ // Debugger.printLogicOrder (logicOrder, "Pre Order");
+ logicOrder[i] = insertTheValue (returnVar);
+ // Debugger.printLogicOrder (logicOrder, "Post Order");
+ return true;
+ }
+ else if (logicOrder [i].currentType == WordTypes.package) {
+ if (insertReturnValueIntoPackage (logicOrder[i] as Package, lineNumber, returnVar))
+ return true;
+ }
+ else if (logicOrder [i].currentType == WordTypes.functionCall) {
+ if (insertReturnValueIntoFuncCall (logicOrder[i] as FunctionCall, lineNumber, returnVar))
+ return true;
+ }
+
+ return false;
+ }
+
+
+
+ private static bool insertReturnValueIntoPackage(Package thePackage, int lineNumber, Variable returnVar){
+ Logic[] tempOrder = thePackage.getLatestOrder();
+ return searchInLogicOrder (tempOrder, lineNumber, returnVar);
+ }
+
+ private static bool insertReturnValueIntoFuncCall(FunctionCall theFuncCall, int lineNumber, Variable returnVar){
+ if (theFuncCall.returnCalculations == null)
+ return false;
+
+ foreach (Logic[] l in theFuncCall.returnCalculations)
+ if (searchInLogicOrder (l, lineNumber, returnVar)) {
+ return true;
+ }
+
+ return false;
+ }
+
+
+ private static Logic insertTheValue(Variable returnVar){
+ Print.print ("Var type: " + returnVar.variableType);
+
+ if (returnVar.variableType == VariableTypes.boolean)
+ return new BooleanValue (returnVar.getBool ());
+ else if (returnVar.variableType == VariableTypes.number)
+ return new NumberValue (returnVar.getNumber ());
+ else if (returnVar.variableType == VariableTypes.textString)
+ return new TextValue (returnVar.getString ());
+
+ return new Variable ("Nill");
+ }
+
+ }
+}
+
diff --git a/LineParser/Runtime/VariableWindow/VariableWindow.cs b/LineParser/Runtime/VariableWindow/VariableWindow.cs
new file mode 100644
index 0000000..91f07b9
--- /dev/null
+++ b/LineParser/Runtime/VariableWindow/VariableWindow.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using Compiler;
+
+namespace Runtime
+{
+ public class VariableWindow
+ {
+
+ private static Action insertVariable;
+ private static Action resetList;
+
+ private static List tempVariables = new List();
+
+ public static void setVariableWindowFunctions(Action insertVariableToList, Action resetTheList){
+ insertVariable = insertVariableToList;
+ resetList = resetTheList;
+ }
+
+ internal static void sendStackVariables(Scope currentScope){
+ resetList.Invoke ();
+ tempVariables.Clear ();
+ tempVariables.Add (new Variables ());
+ sendScopeVariables (currentScope);
+
+ foreach (Variables Vars in tempVariables)
+ {
+ foreach (Variable v in Vars.variableList)
+ {
+ //Print.print("Variable to send: " + v.name);
+ insertVariable(v);
+ }
+ }
+ }
+
+ private static void sendScopeVariables(Scope currentScope){
+ Variables latestList = tempVariables [tempVariables.Count - 1];
+ foreach (Variable v in currentScope.scopeVariables.variableList)
+ if (latestList.containsVariable (v.name) < 0)
+ latestList.addVariable (v, currentScope.scopeParser, 0);
+
+
+
+ /*
+ if (tempVariables == null)
+ tempVariables = new Variables ();
+
+ foreach (Variable v in currentScope.scopeVariables.variableList)
+ tempVariables.addVariable (v, Compiler.SyntaxCheck.globalParser, 0);
+
+
+ if (currentScope.theScopeType == ScopeType.main || currentScope.theScopeType == ScopeType.function) {
+ for (int i = tempVariables.variableList.Count - 1; i >= 0; i--)
+ insertVariable (tempVariables.variableList [i]);
+ tempVariables = null;
+ }
+ */
+ if (currentScope.parentScope != null) {
+ if (currentScope.theScopeType == ScopeType.function)
+ tempVariables.Add (new Variables ());
+ sendScopeVariables (currentScope.parentScope);
+ }
+ }
+
+ }
+}
+
diff --git a/LineParser/Scope/Parser/IndentParser.cs b/LineParser/Scope/Parser/IndentParser.cs
new file mode 100644
index 0000000..2bd9305
--- /dev/null
+++ b/LineParser/Scope/Parser/IndentParser.cs
@@ -0,0 +1,115 @@
+using System;
+using System.Collections.Generic;
+using ErrorHandler;
+
+namespace Compiler
+{
+ public class IndentParser
+ {
+ public static Scope parseIntoScopes(List programLines){
+
+ Scope mainScope = parseCurrentScope (0, 0, programLines, true);
+
+ return mainScope;
+ }
+
+
+ static Scope parseCurrentScope(int indentLevel, int startNumber, List programLines, bool isMain){
+ List scopeLines = new List ();
+ List childScopes = new List ();
+ ScopeType currentScopeType;
+
+ //Set current Scope Type
+ if (!isMain) {
+ if (startNumber > 0) {
+ scopeLines.Add (programLines [startNumber - 1]);
+ currentScopeType = getNonMainScopeType (programLines [startNumber - 1].words, programLines [startNumber - 1].lineNumber);
+ }
+ else
+ currentScopeType = ScopeType.unknown;
+ }
+ else
+ currentScopeType = ScopeType.main;
+
+
+ int lastLine = startNumber;
+ for (int i = startNumber; i < programLines.Count; i++) {
+ int currentIndent = programLines [i].indentLevel;
+
+ if (currentIndent == indentLevel) {
+ lastLine = i;
+ scopeLines.Add(programLines[i]);
+ }
+ else if (currentIndent < indentLevel)
+ return new Scope (currentScopeType, startNumber, lastLine, indentLevel, scopeLines, childScopes, false);
+
+ else if (currentIndent > indentLevel) {
+ Scope childScope = parseCurrentScope (currentIndent, i, programLines, false);
+ i = childScope.endLine;
+ childScopes.Add (childScope);
+
+ if (i != programLines.Count - 1)
+ if (programLines [i + 1].indentLevel < indentLevel)
+ lastLine = i;
+ }
+
+ if (i == programLines.Count - 1) {
+
+ if (childScopes.Count > 0) {
+ int childLastValue = childScopes [childScopes.Count - 1].endLine;
+ if (childLastValue > lastLine)
+ lastLine = childLastValue;
+ }
+ return new Scope (currentScopeType, startNumber, lastLine, indentLevel, scopeLines, childScopes, false);
+ }
+
+ }
+
+ return new Scope (currentScopeType, startNumber, lastLine, indentLevel, scopeLines, childScopes, false);
+ }
+
+
+
+
+ static ScopeType getNonMainScopeType(string[] words, int lineNumber){
+
+ ScopeType tempType = ScopeType.unknown;
+ if (words [0].StartsWith("for"))
+ tempType = ScopeType.forLoop;
+ else if (words [0].StartsWith("while"))
+ tempType = ScopeType.whileLoop;
+ else if (words [0].StartsWith("def"))
+ tempType = ScopeType.function;
+ else if (words [0].StartsWith("if"))
+ tempType = ScopeType.ifStatement;
+ else if (words [0].StartsWith("else"))
+ tempType = ScopeType.elseStatement;
+ else if (words [0].StartsWith("elif"))
+ tempType = ScopeType.elifStatement;
+
+ if (tempType == ScopeType.unknown) {
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, ErrorHandler.ErrorType.Indentation, IndentationErrorType.unknownIndentStarter.ToString(), null);
+ return tempType;
+ }
+
+ return tempType;
+ }
+
+
+
+ static bool scopeCheck(Scope currentScope){
+
+ foreach (Scope tempScope in currentScope.childScopes)
+ if (!scopeCheck (tempScope))
+ return false;
+
+ if (currentScope.theScopeType == ScopeType.unknown)
+ return false;
+
+
+ return true;
+ }
+
+ }
+}
+
diff --git a/LineParser/Scope/Parser/ScopeLogicParser.cs b/LineParser/Scope/Parser/ScopeLogicParser.cs
new file mode 100644
index 0000000..1c45c36
--- /dev/null
+++ b/LineParser/Scope/Parser/ScopeLogicParser.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace Compiler
+{
+ public class ScopeLogicParser
+ {
+
+ public static void parseScopeLineLogic(Scope currentScope){
+ if (currentScope.childScopes.Count == 0) {
+ parseCodeLineLogic (currentScope);
+ return;
+ }
+ else
+ foreach (Scope tempScope in currentScope.childScopes)
+ parseScopeLineLogic (tempScope);
+
+
+ parseCodeLineLogic (currentScope);
+ }
+
+ static void parseCodeLineLogic(Scope currentScope){
+ foreach (CodeLine tempLine in currentScope.codeLines)
+ tempLine.logicOrder = WordsToLogicParser.determineLogicFromWords (tempLine.words, tempLine.lineNumber, currentScope);
+ }
+
+ }
+}
+
diff --git a/LineParser/Scope/Parser/ScopeParser.cs b/LineParser/Scope/Parser/ScopeParser.cs
new file mode 100644
index 0000000..2ed46b9
--- /dev/null
+++ b/LineParser/Scope/Parser/ScopeParser.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using SyntaxCheck;
+
+namespace Compiler
+{
+ public class ScopeParser
+ {
+ ///
+ /// Parses all text into lines and lines into words. Parses the into scopes. Checks syntax for indentation, scopeStarters
+ ///
+ /// The into scopes.
+ /// Code text.
+ public static Scope parseIntoScopes(string codeText){
+
+ // Creates list with CodeLine objects with lineNumber, indentNumber and word list
+ List programLines = SyntaxCheck.parseLines(codeText);
+
+ Scope mainScope = IndentParser.parseIntoScopes (programLines);
+ ScopeLogicParser.parseScopeLineLogic (mainScope);
+ ScopeStarterParser.checkScopeStarters (programLines, mainScope);
+ //CodeSyntaxWalker.walkAllLines (programLines.ToArray (), mainScope);
+
+ return mainScope;
+ }
+
+
+ }
+}
+
diff --git a/LineParser/Scope/Parser/ScopeReturnParser.cs b/LineParser/Scope/Parser/ScopeReturnParser.cs
new file mode 100644
index 0000000..f9bea70
--- /dev/null
+++ b/LineParser/Scope/Parser/ScopeReturnParser.cs
@@ -0,0 +1,29 @@
+using System;
+using Runtime;
+using ErrorHandler;
+
+namespace Compiler
+{
+ public class ScopeReturnParser
+ {
+ public static void parseScopeReturns(Scope currentSuperParent, Scope currentScope){
+ checkLinesInScope (currentSuperParent, currentScope);
+
+ foreach (Scope s in currentScope.childScopes)
+ parseScopeReturns (currentSuperParent, s);
+ }
+
+ private static void checkLinesInScope(Scope currentSuperParent, Scope currentScope){
+ foreach (CodeLine c in currentScope.codeLines)
+ if (c.logicOrder [0].currentType == WordTypes.returnStatement) {
+ if (currentSuperParent.theScopeType != ScopeType.function)
+ ErrorMessage.sendErrorMessage (c.lineNumber, "Du kan bara returnera värden ifrån en funktion " + currentSuperParent.theScopeType);
+
+
+ (c.logicOrder [0] as ReturnStatement).FunctionParent = currentSuperParent;
+ }
+
+ }
+ }
+}
+
diff --git a/LineParser/Scope/Parser/ScopeStarterParser.cs b/LineParser/Scope/Parser/ScopeStarterParser.cs
new file mode 100644
index 0000000..4b41429
--- /dev/null
+++ b/LineParser/Scope/Parser/ScopeStarterParser.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using ErrorHandler;
+using Runtime;
+
+namespace Compiler
+{
+
+ public class ScopeStarterParser{
+
+ public static void checkScopeStarters(List programLines, Scope mainScope){
+
+ int expectedIndent = 0;
+ bool expectedHigherIndent = true;
+ bool isFirst = true;
+
+ for (int i = 0; i < programLines.Count; i++) {
+ if (expectedHigherIndent) {
+ if (isFirst) {
+ if (programLines [i].indentLevel != 0)
+ ErrorMessage.sendErrorMessage (programLines [i].lineNumber, ErrorType.Indentation, IndentationErrorType.firstLineIndentError.ToString(), null);
+ isFirst = false;
+ } else {
+ if (programLines [i].indentLevel != expectedIndent)
+ ErrorMessage.sendErrorMessage (programLines [i].lineNumber, ErrorType.Indentation, IndentationErrorType.indentationError.ToString(), null);
+ }
+ }
+
+ if (SpecialWordParser.isValidScopeStarter (programLines [i].logicOrder, programLines [i].lineNumber)) {
+ expectedIndent = programLines [i].indentLevel + 1;
+ expectedHigherIndent = true;
+
+ if (i == programLines.Count - 1)
+ ErrorMessage.sendErrorMessage (programLines [i].lineNumber, ErrorType.Indentation, IndentationErrorType.expectingBodyAfterScopeStarter.ToString(), null);
+ }
+ else
+ expectedHigherIndent = false;
+ }
+
+ setScopeStarterTargets (mainScope);
+ }
+
+ static void setScopeStarterTargets(Scope currentScope){
+ int currentChildScope = 0;
+ int linkCounter = 0;
+
+ for(int i = 0; i < currentScope.codeLines.Count; i++){
+ CodeLine line = currentScope.codeLines [i];
+
+ if (SpecialWordParser.isValidScopeStarter (line.logicOrder, line.lineNumber)) {
+ if (currentChildScope > currentScope.childScopes.Count - 1)
+ ErrorMessage.sendErrorMessage (line.lineNumber, ErrorType.System, SystemFailureErrorType.scopeParsingMalfunction.ToString(), null);
+
+ (line.logicOrder [0] as ScopeStarter).setTargetScope(currentScope.childScopes [currentChildScope]);
+ currentChildScope++;
+
+
+ // Links else/elif
+ if (line.logicOrder [0] is ComparisonScope) {
+ if (i == 0 && line.logicOrder [0] is IfStatement == false)
+ ErrorMessage.sendErrorMessage (line.lineNumber , ErrorType.ElseStatements, ElseErrorType.missingIfBeforeElse.ToString(), null);
+
+ if (line.logicOrder [0] is IfStatement == false)
+ linkElseStatement (line.logicOrder [0], currentScope.codeLines [i - 1].logicOrder [0], currentScope, linkCounter, line.lineNumber);
+
+
+ linkCounter++;
+ } else
+ linkCounter = 0;
+ }
+
+
+ }
+
+ foreach (Scope tempScope in currentScope.childScopes)
+ setScopeStarterTargets (tempScope);
+
+ }
+
+ static void linkElseStatement(Logic newStatement, Logic preLineLogic, Scope currentScope, int linkCounter, int lineNumber){
+ if (linkCounter == 0)
+ ErrorMessage.sendErrorMessage (lineNumber , ErrorType.ElseStatements, ElseErrorType.missingIfBeforeElse.ToString(), null);
+ if(preLineLogic is ElseStatement)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.ElseStatements, ElseErrorType.elseCantLinkToElse.ToString(), null);
+
+ (preLineLogic as ComparisonScope).linkNextStatement (newStatement as ComparisonScope);
+ }
+
+
+ }
+
+}
+
diff --git a/LineParser/Scope/Scope.cs b/LineParser/Scope/Scope.cs
new file mode 100644
index 0000000..5d7eabb
--- /dev/null
+++ b/LineParser/Scope/Scope.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using B83.ExpressionParser;
+using Runtime;
+using System.IO;
+using System.Runtime.Serialization.Formatters.Binary;
+
+namespace Compiler
+{
+
+ public class Scope
+ {
+ public ScopeType theScopeType;
+ public ScopeLoop theScoopLoop;
+
+ public int indentLevel = 0;
+ public int startLine, endLine;
+ public bool isReturning = false;
+
+ public List codeLines;
+ public List childScopes;
+ private Scope secretParent;
+ public Scope parentScope{
+ get{
+ return secretParent;
+ }
+ set{
+ secretParent = value;
+ }
+ }
+
+ public CurrentFunctions scopeFunctions;
+ public Variables scopeVariables;
+ public ExpressionParser scopeParser;
+ public int lastReadLine = 0;
+
+
+ public Scope(ScopeType theScopeType, int startLine, int endLine, int indentLevel, List codeLines, List childScopes, bool isClone){
+ scopeParser = new ExpressionParser ();
+
+ this.theScopeType = theScopeType;
+ this.startLine = startLine;
+ this.endLine = endLine;
+ this.indentLevel = indentLevel;
+
+ this.codeLines = codeLines;
+ this.childScopes = childScopes;
+
+ scopeVariables = new Variables ();
+ scopeFunctions = new CurrentFunctions ();
+ scopeParser = new ExpressionParser ();
+
+ if (theScopeType == ScopeType.main || isClone)
+ theScopeType = ScopeType.main;
+ else
+ this.codeLines.RemoveAt (0);
+ }
+
+ public void giveInheritVariables(List inheritVariables){
+ foreach (Variable var in inheritVariables) {
+
+ int varPos = scopeVariables.containsVariable (var.name);
+ if (varPos >= 0) {
+ if (scopeVariables.variableList [varPos].isForLoopVariable) {
+ double value = scopeVariables.variableList [varPos].getNumber();
+ scopeVariables.addVariable (var, scopeParser, -1);
+ scopeVariables.variableList [varPos].setValue (value);
+ }
+ else
+ scopeVariables.addVariable (var, scopeParser, codeLines[0].lineNumber);
+ }
+ else
+ scopeVariables.addVariable (var, scopeParser, codeLines[0].lineNumber);
+
+ }
+
+ }
+
+ public void upInheritVariable(Scope targetScope){
+ foreach (Variable v in scopeVariables.variableList)
+ targetScope.scopeVariables.addVariable (v, scopeParser, codeLines [0].lineNumber);
+ }
+
+ public CodeLine getCurrentLine(){
+ return codeLines [lastReadLine];
+ }
+
+ public void setCurrentLine(CodeLine newLine)
+ {
+ codeLines[lastReadLine] = newLine;
+ }
+
+
+ //Not working ish....
+ public Scope createDeepCopy(){
+
+ List tempCodeLines = new List ();
+ foreach (CodeLine c in codeLines)
+ tempCodeLines.Add (c.cloneLine ());
+
+ List tempChildScopes = new List ();
+ foreach (Scope s in childScopes)
+ tempChildScopes.Add (s.createDeepCopy());
+
+ Scope tempScope = new Scope (theScopeType, startLine, endLine, indentLevel, tempCodeLines, tempChildScopes, true);
+
+
+ return tempScope;
+ }
+
+
+ public void linkChildScopes(Scope currentScope){
+ int counter = 0;
+ foreach (CodeLine c in currentScope.codeLines) {
+
+ if (c.logicOrder [0] is ScopeStarter) {
+ (c.logicOrder [0] as ScopeStarter).setTargetScope(currentScope.childScopes [counter]);
+ counter++;
+ }
+ }
+
+ foreach (Scope s in currentScope.childScopes)
+ linkChildScopes (s);
+ }
+ }
+}
+
diff --git a/LineParser/Scope/ScopeLoop.cs b/LineParser/Scope/ScopeLoop.cs
new file mode 100644
index 0000000..5f622fb
--- /dev/null
+++ b/LineParser/Scope/ScopeLoop.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Compiler
+{
+
+ public class ScopeLoop : ScopeStarter {
+
+ public ComparisonType theComparisonType;
+ public Variable leftValue;
+ public Variable rightValue;
+
+ }
+}
+
diff --git a/LineParser/Scope/ScopeStarter.cs b/LineParser/Scope/ScopeStarter.cs
new file mode 100644
index 0000000..79b968c
--- /dev/null
+++ b/LineParser/Scope/ScopeStarter.cs
@@ -0,0 +1,22 @@
+using System;
+using Runtime;
+
+namespace Compiler
+{
+ public abstract class ScopeStarter : Logic {
+
+ private Scope targetScope;
+ public bool doEnterScope;
+ public bool doParseLine = true;
+
+
+ public void setTargetScope(Scope targetScope){
+ this.targetScope = targetScope;
+ }
+
+ public Scope getTargetScope(){
+ return targetScope;
+ }
+ }
+}
+
diff --git a/LineParser/Scope/ScopeType.cs b/LineParser/Scope/ScopeType.cs
new file mode 100644
index 0000000..a2bec3c
--- /dev/null
+++ b/LineParser/Scope/ScopeType.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace Compiler{
+
+
+ public enum ScopeType{
+ function,
+ forLoop,
+ whileLoop,
+ ifStatement,
+ elseStatement,
+ elifStatement,
+ main,
+ unknown
+ }
+}
\ No newline at end of file
diff --git a/LineParser/SyntaxCheck.cs b/LineParser/SyntaxCheck.cs
new file mode 100644
index 0000000..3a06be1
--- /dev/null
+++ b/LineParser/SyntaxCheck.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using B83;
+
+namespace Compiler
+{
+ public class SyntaxCheck
+ {
+
+ public static B83.ExpressionParser.ExpressionParser globalParser;
+
+ ///
+ /// Declares globalParser and returns parsed lines in list of Codelines.
+ ///
+ public static List parseLines(string currentText){
+ globalParser = new B83.ExpressionParser.ExpressionParser ();
+
+ List textLines = LineSplitter.splitTextIntoLines(currentText);
+ return LineParser.parseLines (textLines);
+
+ }
+
+ /// Links fullText and actions (endWalker etc) to CodeWalker via setActions.
+ public static void CompileCode(string fullText, Action endWalker, Action pauseWalker, Action, Scope> linkSubmitInput, Action activateFunctionColor, Action setWalkerPos){
+ Scope mainScope = ScopeParser.parseIntoScopes (fullText);
+ Runtime.CodeWalker.setActions(endWalker, pauseWalker, linkSubmitInput, activateFunctionColor, setWalkerPos, mainScope);
+ }
+ }
+}
+
diff --git a/LineParser/SyntaxCheck/CodeSyntaxWalker.cs b/LineParser/SyntaxCheck/CodeSyntaxWalker.cs
new file mode 100644
index 0000000..e20ba33
--- /dev/null
+++ b/LineParser/SyntaxCheck/CodeSyntaxWalker.cs
@@ -0,0 +1,33 @@
+using ErrorHandler;
+using System.Collections;
+using Compiler;
+using Runtime;
+
+namespace SyntaxCheck{
+
+ internal class CodeSyntaxWalker{
+
+ private static void findCommandType(CodeLine c, Scope mainScope){
+ checkForUnknown (c.logicOrder, c.lineNumber);
+
+ if (PossibleVariableDeclare.checkForVariableDecleration (c.logicOrder, c.lineNumber))
+ return;
+
+ if (PossibleSpeciallWord.checkForSpeciallWord (c.logicOrder, c.lineNumber, mainScope))
+ return;
+
+ if (PossibleFunctionCall.possibleFunctionCall (c.logicOrder, c.lineNumber))
+ return;
+
+ ErrorMessage.sendErrorMessage (c.lineNumber, ErrorType.System, SystemFailureErrorType.unknownLogic.ToString(), new string[]{"0"});
+ }
+
+ static void checkForUnknown(Logic[] logicOrder, int lineNumber){
+ foreach (Logic L in logicOrder)
+ if (L.currentType == WordTypes.unknown)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.System, SystemFailureErrorType.unknownLogic.ToString(), new string[]{"1"});
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/LineParser/SyntaxCheck/PossibleFunctionCall.cs b/LineParser/SyntaxCheck/PossibleFunctionCall.cs
new file mode 100644
index 0000000..73fc34e
--- /dev/null
+++ b/LineParser/SyntaxCheck/PossibleFunctionCall.cs
@@ -0,0 +1,16 @@
+using System.Collections;
+using Compiler;
+
+namespace SyntaxCheck{
+
+ internal class PossibleFunctionCall {
+
+ public static bool possibleFunctionCall(Logic[] logicOrder, int lineNumber){
+ if (logicOrder.Length == 1 && logicOrder [0].currentType == WordTypes.functionCall)
+ return true;
+
+ return false;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/LineParser/SyntaxCheck/PossibleSpeciallWord.cs b/LineParser/SyntaxCheck/PossibleSpeciallWord.cs
new file mode 100644
index 0000000..07a11a4
--- /dev/null
+++ b/LineParser/SyntaxCheck/PossibleSpeciallWord.cs
@@ -0,0 +1,135 @@
+using ErrorHandler;
+using System.Collections;
+using Compiler;
+
+namespace SyntaxCheck{
+
+ internal class PossibleSpeciallWord{
+
+ public static bool checkForSpeciallWord(Logic[] logicOrder, int lineNumber, Scope mainScope){
+ switch (logicOrder[0].currentType) {
+
+ case WordTypes.ifOperator:
+ return ifCheck (logicOrder, lineNumber);
+ case WordTypes.elseOperator:
+ return elseCheck(logicOrder, lineNumber);
+
+ case WordTypes.forLoop:
+ return forCheck(logicOrder, lineNumber, mainScope);
+
+ case WordTypes.whileLoop:
+ return whileCheck (logicOrder, lineNumber);
+
+ case WordTypes.defStatement:
+ return defCheck (logicOrder, lineNumber);
+
+ case WordTypes.returnStatement:
+ return returnCheck (logicOrder, lineNumber);
+
+ default:
+ return false;
+ }
+
+ }
+
+ private static bool returnCheck(Logic[] logicOrder, int lineNumber){
+ if (logicOrder.Length < 2)
+ ErrorMessage.sendErrorMessage (lineNumber, "Du måste returnera något");
+
+ ValidSumCheck.checkIfValidSum ((InternalParseFunctions.getSubArray(logicOrder, 1, logicOrder.Length-1, lineNumber)), lineNumber);
+
+
+ return true;
+ }
+
+
+ private static bool ifCheck(Logic[] logicOrder, int lineNumber){
+ if (logicOrder [logicOrder.Length - 1].currentType != WordTypes.indentOperator)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.IfStatements, IfErrorType.missingIndentOperator.ToString(), null);
+
+ if (logicOrder.Length < 3)
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.IfStatements, IfErrorType.unknownFormat.ToString(), null);
+
+
+ Logic[] statementLogic = new Logic[logicOrder.Length - 2];
+
+ for (int i = 1; i < logicOrder.Length - 1; i++)
+ statementLogic [i - 1] = logicOrder [i];
+
+ if(!PossibleStatement.validStatement(statementLogic, lineNumber))
+ ErrorMessage.sendErrorMessage (lineNumber, ErrorType.System, SystemFailureErrorType.possibleComparissonStatements.ToString(), null);
+
+ return true;
+ }
+
+
+ private static bool elseCheck(Logic[] logicOrder, int lineNumber){
+ if (logicOrder.Length != 2)
+ ErrorMessage.sendErrorMessage (lineNumber, "Okänkt format på din Else sats");
+
+ if (logicOrder [logicOrder.Length - 1].currentType != WordTypes.indentOperator)
+ ErrorMessage.sendErrorMessage (lineNumber, "Det saknas ett \":\" i slutet av din Else");
+
+ return true;
+ }
+
+ private static bool forCheck(Logic[] logicOrder, int lineNumber, Scope currentScope){
+ if (logicOrder.Length != 5)
+ ErrorMessage.sendErrorMessage (lineNumber, "Okänt format på din for loop");
+
+ if (logicOrder [1].currentType != WordTypes.variable)
+ ErrorMessage.sendErrorMessage (lineNumber, "Förväntade sig en variabel som 2:a ord");
+
+ if (logicOrder[2].word != "in")
+ ErrorMessage.sendErrorMessage (lineNumber, "Förväntade sig ordet \"in\" 3:e ord");
+
+ if (logicOrder [3].currentType != WordTypes.functionCall)
+ ErrorMessage.sendErrorMessage (lineNumber, "Förväntade sig funktionsanrop till \"range\" som 4:e ord");
+
+ FunctionParser.linkFunctionCall ((logicOrder [3] as FunctionCall), lineNumber, currentScope);
+ if ((logicOrder [3] as FunctionCall).targetFunc.name != "range")
+ ErrorMessage.sendErrorMessage (lineNumber, "Förväntade sig funktionsanrop till \"range\" som 4:e ord");
+
+ if (logicOrder [4].currentType != WordTypes.indentOperator)
+ ErrorMessage.sendErrorMessage (lineNumber, "Saknas ett \":\" i slutet av din for loop");
+
+
+ return true;
+ }
+
+ private static bool whileCheck(Logic[] logicOrder, int lineNumber){
+ if (logicOrder.Length < 3)
+ ErrorMessage.sendErrorMessage (lineNumber, "Okänt format i din While loop");
+
+ if (logicOrder [logicOrder.Length -1].currentType != WordTypes.indentOperator)
+ ErrorMessage.sendErrorMessage (lineNumber, "Saknas ett \":\" i slutet av din While loop");
+
+
+ Logic[] statementLogic = new Logic[logicOrder.Length - 2];
+ for (int i = 1; i < logicOrder.Length - 1; i++)
+ statementLogic [i - 1] = logicOrder [i];
+
+
+ if(!PossibleStatement.validStatement(statementLogic, lineNumber))
+ ErrorMessage.sendErrorMessage (lineNumber, "Okänt format i din While loops expression");
+
+
+ return true;
+ }
+
+
+ private static bool defCheck(Logic[] logicOrder, int lineNumber){
+ if (logicOrder.Length != 3)
+ ErrorMessage.sendErrorMessage (lineNumber, "Okänt format i din funktions definiering");
+
+ if (logicOrder [logicOrder.Length -1].currentType != WordTypes.indentOperator)
+ ErrorMessage.sendErrorMessage (lineNumber, "Saknas ett \":\" i slutet av din funktions definiering");
+
+ if (logicOrder [1].currentType != WordTypes.functionCall)
+ ErrorMessage.sendErrorMessage (lineNumber, "Funktionsnamnet går av någon anledning inte att använda");
+
+ return true;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/LineParser/SyntaxCheck/PossibleStatement.cs b/LineParser/SyntaxCheck/PossibleStatement.cs
new file mode 100644
index 0000000..e45f403
--- /dev/null
+++ b/LineParser/SyntaxCheck/PossibleStatement.cs
@@ -0,0 +1,108 @@
+using ErrorHandler;
+using System.Collections.Generic;
+using System;
+using Compiler;
+
+public class PossibleStatement{
+
+ internal static bool validStatement(Logic[] logicOrder, int lineNumber){
+ List statementParts = new List ();
+
+ int lastOperatorPos = -1;
+ for (int i = 0; i < logicOrder.Length; i++)
+ if (logicOrder [i].currentType == WordTypes.andOperator || logicOrder [i].currentType == WordTypes.orOperator) {
+ statementParts.Add(InternalParseFunctions.getSubArray(logicOrder,lastOperatorPos+1, i-1, lineNumber));
+ lastOperatorPos = i;
+ }
+
+ statementParts.Add (InternalParseFunctions.getSubArray (logicOrder, lastOperatorPos + 1, logicOrder.Length-1, lineNumber));
+
+
+ List partStatementValues = new List ();
+ foreach (Logic[] l in statementParts)
+ if (validPartStatement (l, lineNumber) != true)
+ return false;
+
+
+
+ return true;
+ }
+
+
+
+ internal static bool validPartStatement(Logic[] logicOrder, int lineNumber){
+ #region findOperators
+ int operatorLow = 0;
+ int operatorHigh = 0;
+ int operatorAmount = 0;
+ for (int i = 0; i < logicOrder.Length; i++)
+ if (isStatementOperator (logicOrder [i])) {
+ if (operatorLow == 0)
+ operatorLow = i;
+ else
+ operatorHigh = i;
+ operatorAmount++;
+ }
+
+ #endregion
+
+ if (operatorAmount > 2)
+ ErrorMessage.sendErrorMessage (lineNumber, "Operatorerna i ditt expression går inte att tyda");
+ if (operatorAmount == 0)
+ return true;
+
+ if (operatorAmount == 2) {
+ if (operatorHigh - operatorLow != 1)
+ ErrorMessage.sendErrorMessage (lineNumber, "Operatorerna måste komma efter varandra");
+
+ }
+ else
+ operatorHigh = operatorLow;
+
+
+
+
+ Logic[] leftSide = new Logic[operatorLow];
+ Logic[] rightSide = new Logic[logicOrder.Length - 1 - operatorHigh];
+ Logic[] operators = new Logic[operatorAmount];
+
+ setSidesOfStatement (logicOrder, leftSide, rightSide, operators, operatorLow, operatorHigh);
+
+ ComparisonType operatorType = ComparisonOperatorParser.parseOperators (operators);
+
+ if (operatorType == ComparisonType.unknown)
+ ErrorMessage.sendErrorMessage (lineNumber, "Operatorerna går inte att tyda");
+
+ ValidSumCheck.checkIfValidSum (leftSide, lineNumber);
+ ValidSumCheck.checkIfValidSum (rightSide, lineNumber);
+
+ return true;
+ }
+
+ static void setSidesOfStatement(Logic[] logicOrder, Logic[] leftSide, Logic[] rightSide, Logic[] operators, int operatorLow, int operatorHigh){
+
+ for (int i = 0; i < leftSide.Length; i++)
+ leftSide [i] = logicOrder [i];
+
+ for (int i = operatorHigh+1; i < logicOrder.Length; i++)
+ rightSide [i - (operatorHigh+1)] = logicOrder [i];
+
+ for (int i = operatorLow; i <= operatorHigh; i++)
+ operators [i - operatorLow] = logicOrder [i];
+ }
+
+ public static bool isStatementOperator(Logic currentLogic){
+ if (currentLogic.currentType == WordTypes.equalSign)
+ return true;
+
+ if (currentLogic.currentType == WordTypes.lessThenSign || currentLogic.currentType == WordTypes.greaterThenSign)
+ return true;
+
+ if (currentLogic.currentType == WordTypes.xorOperator)
+ return true;
+
+ return false;
+ }
+
+
+}
diff --git a/LineParser/SyntaxCheck/PossibleVariableDeclare.cs b/LineParser/SyntaxCheck/PossibleVariableDeclare.cs
new file mode 100644
index 0000000..451e876
--- /dev/null
+++ b/LineParser/SyntaxCheck/PossibleVariableDeclare.cs
@@ -0,0 +1,35 @@
+using System.Collections;
+using Runtime;
+using Compiler;
+
+public class PossibleVariableDeclare{
+
+ internal static bool checkForVariableDecleration(Logic[] logicOrder, int lineNumber){
+
+ if (logicOrder.Length < 3)
+ return false;
+
+ if (logicOrder [0].currentType != WordTypes.variable)
+ return false;
+
+ int equalPos = 0;
+ for (int i = 0; i < logicOrder.Length; i++, equalPos++)
+ if (logicOrder [i].currentType == WordTypes.equalSign)
+ break;
+
+ if (equalPos != 1 && equalPos != 2)
+ return false;
+
+ if (equalPos == 2 && logicOrder [1].currentType != WordTypes.mathOperator)
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, "Du kan bara ha matte operatorer i special deklareringar!");
+
+ Logic[] afterEqualSign = new Logic[logicOrder.Length - (equalPos+1)];
+ for (int i = equalPos+1; i < logicOrder.Length; i++)
+ afterEqualSign [i-(equalPos+1)] = logicOrder [i];
+
+
+ ValidSumCheck.checkIfValidSum (afterEqualSign, lineNumber);
+
+ return true;
+ }
+}
diff --git a/LineParser/Tags/Logic/BoolType.cs b/LineParser/Tags/Logic/BoolType.cs
new file mode 100644
index 0000000..5d43ae9
--- /dev/null
+++ b/LineParser/Tags/Logic/BoolType.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Compiler
+{
+ public interface BoolType
+ {
+ }
+}
+
diff --git a/LineParser/Tags/Logic/ComparisonScope.cs b/LineParser/Tags/Logic/ComparisonScope.cs
new file mode 100644
index 0000000..f2e30eb
--- /dev/null
+++ b/LineParser/Tags/Logic/ComparisonScope.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace Compiler
+{
+ public interface ComparisonScope
+ {
+ void setEnterScope(bool value);
+ void setParseLine(bool value);
+ void initNextstatement();
+ void linkNextStatement(ComparisonScope nextScope);
+ }
+}
+
diff --git a/LineParser/Tags/Logic/Value.cs b/LineParser/Tags/Logic/Value.cs
new file mode 100644
index 0000000..b1cfe4b
--- /dev/null
+++ b/LineParser/Tags/Logic/Value.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Compiler
+{
+ public interface Value
+ {
+ }
+}
+
diff --git a/LineParser/Tags/Operators/AndOrOperator.cs b/LineParser/Tags/Operators/AndOrOperator.cs
new file mode 100644
index 0000000..87c7458
--- /dev/null
+++ b/LineParser/Tags/Operators/AndOrOperator.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Compiler
+{
+ public interface AndOrOperator
+ {
+ }
+}
+
diff --git a/LineParser/Tags/Operators/ComparisonOperator.cs b/LineParser/Tags/Operators/ComparisonOperator.cs
new file mode 100644
index 0000000..cd9ea80
--- /dev/null
+++ b/LineParser/Tags/Operators/ComparisonOperator.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Compiler
+{
+ public interface ComparisonOperator
+ {
+ }
+}
+
diff --git a/LineParser/Variables/Values/BooleanValue.cs b/LineParser/Variables/Values/BooleanValue.cs
new file mode 100644
index 0000000..4ef79d5
--- /dev/null
+++ b/LineParser/Variables/Values/BooleanValue.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace Compiler
+{
+ public class BooleanValue : Logic, BoolType{
+
+ public bool value;
+
+ public BooleanValue(bool inputValue){
+ base.currentType = WordTypes.booleanValue;
+ base.word = "Bool Value";
+ value = inputValue;
+ }
+
+ }
+}
+
diff --git a/LineParser/Variables/Values/CalculationValue.cs b/LineParser/Variables/Values/CalculationValue.cs
new file mode 100644
index 0000000..737b48a
--- /dev/null
+++ b/LineParser/Variables/Values/CalculationValue.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace Compiler
+{
+ public class CalculationValue : Logic
+ {
+ int lineNumber;
+
+ public CalculationValue(int lineNumber){
+ this.lineNumber = lineNumber;
+ base.currentType = WordTypes.calculationValue;
+ }
+
+ }
+}
+
diff --git a/LineParser/Variables/Values/NumberValue.cs b/LineParser/Variables/Values/NumberValue.cs
new file mode 100644
index 0000000..3717da0
--- /dev/null
+++ b/LineParser/Variables/Values/NumberValue.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Compiler
+{
+ public class NumberValue : Logic{
+
+ public double value = 0;
+
+ public NumberValue(string word){
+ base.currentType = WordTypes.number;
+ base.word = word;
+ double.TryParse (word, out value);
+ }
+
+ public NumberValue(double value){
+ base.currentType = WordTypes.number;
+ base.word = value.ToString();
+ this.value = value;
+ }
+ }
+}
+
diff --git a/LineParser/Variables/Values/TextValue.cs b/LineParser/Variables/Values/TextValue.cs
new file mode 100644
index 0000000..829350a
--- /dev/null
+++ b/LineParser/Variables/Values/TextValue.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace Compiler
+{
+ public class TextValue : Logic{
+
+ public string value;
+
+ public TextValue(string word){
+ base.currentType = WordTypes.textString;
+ base.word = word;
+
+ if (word [0] == '"' && word [word.Length - 1] == '"')
+ removeQoutes ();
+ else
+ value = word;
+ }
+
+ private void removeQoutes(){
+ if (word.Length < 3)
+ value = "";
+ else
+ value = word.Substring (1, word.Length - 2);
+ }
+
+ }
+}
+
diff --git a/LineParser/Variables/Values/UnknownLogic.cs b/LineParser/Variables/Values/UnknownLogic.cs
new file mode 100644
index 0000000..c1a2b9b
--- /dev/null
+++ b/LineParser/Variables/Values/UnknownLogic.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace Compiler
+{
+ public class UnknownLogic : Logic {
+
+ int lineNumber;
+
+ public UnknownLogic(int lineNumber){
+ this.lineNumber = lineNumber;
+ base.currentType = WordTypes.unknown;
+ }
+
+ }
+
+}
+
diff --git a/LineParser/Variables/Variable.cs b/LineParser/Variables/Variable.cs
new file mode 100644
index 0000000..58e81fb
--- /dev/null
+++ b/LineParser/Variables/Variable.cs
@@ -0,0 +1,85 @@
+using System;
+
+namespace Compiler
+{
+
+ public class Variable : Logic, BoolType
+ {
+ public VariableTypes variableType;
+ public string name;
+ public bool isCalcVar = false;
+ public bool isReturnCalcVar = false;
+
+ private double numberValue;
+ private bool boolValue;
+ private string stringValue;
+
+ public bool isForLoopVariable = false;
+
+ public Variable(){
+ variableType = VariableTypes.unknown;
+ }
+
+ public Variable(string name){
+ this.name = name;
+ this.word = name;
+ variableType = VariableTypes.None;
+ }
+ public Variable(string name, string newValue, bool isCalcVar = false){
+ this.name = name;
+ this.word = name;
+ variableType = VariableTypes.textString;
+ stringValue = newValue;
+ this.isCalcVar = isCalcVar;
+ }
+ public Variable(string name, double newValue, bool isCalcVar = false){
+ this.name = name;
+ this.word = name;
+ variableType = VariableTypes.number;
+ numberValue = newValue;
+ this.isCalcVar = isCalcVar;
+ }
+ public Variable(string name, bool newValue, bool isCalcVar = false){
+ this.name = name;
+ this.word = name;
+ variableType = VariableTypes.boolean;
+ boolValue = newValue;
+ this.isCalcVar = isCalcVar;
+ }
+
+
+
+
+
+ public void setValue(double newValue){
+ variableType = VariableTypes.number;
+ numberValue = newValue;
+ }
+ public void setValue(string newValue){
+ variableType = VariableTypes.textString;
+ stringValue = newValue;
+ }
+ public void setValue(bool newValue){
+ variableType = VariableTypes.boolean;
+ boolValue = newValue;
+ }
+
+ public void setValue(){
+ variableType = VariableTypes.None;
+ }
+
+
+ public double getNumber(){
+ return numberValue;
+ }
+
+ public bool getBool(){
+ return boolValue;
+ }
+
+ public string getString(){
+ return stringValue;
+ }
+ }
+}
+
diff --git a/LineParser/Variables/VariableTypes.cs b/LineParser/Variables/VariableTypes.cs
new file mode 100644
index 0000000..1ae9af2
--- /dev/null
+++ b/LineParser/Variables/VariableTypes.cs
@@ -0,0 +1,13 @@
+
+namespace Compiler
+{
+ public enum VariableTypes{
+ number,
+ boolean,
+ textString,
+ None,
+ unsigned,
+ unknown
+ };
+}
+
diff --git a/LineParser/Variables/Variables.cs b/LineParser/Variables/Variables.cs
new file mode 100644
index 0000000..6412a2a
--- /dev/null
+++ b/LineParser/Variables/Variables.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using B83.ExpressionParser;
+using Runtime;
+using ErrorHandler;
+
+namespace Compiler
+{
+
+ public class Variables
+ {
+ public List variableList = new List();
+
+ //Later fix!
+ //Should be possible to avoid all the else if statements.
+ public void addVariable(Variable newVar, ExpressionParser scopePareser, int lineNumber){
+ //First we check if the variable we are trying to add already exists, if it does we change the value of it.
+ //Otherwise create a new variable
+ int tempCont = containsVariable (newVar.name);
+ if (tempCont >= 0) {
+ variableList [tempCont] = newVar;
+
+ if (newVar.variableType == VariableTypes.boolean)
+ changeExistingVariable (tempCont, newVar.getBool (), scopePareser);
+ else if (newVar.variableType == VariableTypes.number)
+ changeExistingVariable (tempCont, newVar.getNumber (), scopePareser);
+ else if (newVar.variableType == VariableTypes.textString)
+ changeExistingVariable (tempCont, newVar.getString (), scopePareser);
+ else if(newVar.variableType == VariableTypes.None)
+ changeExistingVariable (tempCont, newVar.getString (), scopePareser);
+ else
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, ErrorType.System, SystemFailureErrorType.addOrChangeUnsupportedVariableType.ToString(), null);
+
+ }
+ else {
+ if (newVar.variableType != VariableTypes.unknown && newVar.variableType != VariableTypes.unsigned) {
+ variableList.Add (newVar);
+ if (newVar.variableType == VariableTypes.number)
+ scopePareser.AddConst (newVar.name, () => newVar.getNumber ());
+ }
+ else
+ ErrorHandler.ErrorMessage.sendErrorMessage (lineNumber, ErrorType.System, SystemFailureErrorType.addOrChangeUnsupportedVariableType.ToString(), null);
+
+ }
+
+ }
+
+
+ #region Alteration methods
+ public void changeExistingVariable(int index, double newValue, ExpressionParser scopeParser){
+ removeFromParser (variableList [index].name, scopeParser);
+
+ variableList [index].setValue (newValue);
+ scopeParser.AddConst(variableList [index].name, () => variableList [index].getNumber());
+ }
+
+ public void changeExistingVariable(int index, string newValue, ExpressionParser scopeParser){
+ removeFromParser (variableList [index].name, scopeParser);
+ variableList [index].setValue (newValue);
+ }
+
+ public void changeExistingVariable(int index, bool newValue, ExpressionParser scopeParser){
+ removeFromParser (variableList [index].name, scopeParser);
+ variableList [index].setValue (newValue);
+ }
+
+ public void changeExistingVariable(int index, ExpressionParser scopeParser){
+ removeFromParser (variableList [index].name, scopeParser);
+ variableList [index].setValue ();
+ }
+
+ void removeFromParser(string name, ExpressionParser scopeParser){
+ if (scopeParser.containgsConst (name))
+ scopeParser.RemoveConst (name);
+ }
+ #endregion
+
+
+ #region searchFunctions
+ public int containsVariable(string name){
+ for (int i = 0; i < variableList.Count; i++)
+ if (variableList [i].name == name)
+ return i;
+
+
+ return -1;
+ }
+
+ public int containsVariableOfType(string name, VariableTypes checkType){
+ for (int i = 0; i < variableList.Count; i++)
+ if (variableList [i].name == name)
+ if (variableList [i].variableType == checkType)
+ return i;
+ else
+ return -1;
+
+ return -1;
+ }
+ #endregion
+
+
+ public void printVariableList(){
+ foreach (Variable v in variableList)
+ Print.print (v.name + " Num: " + v.getNumber () + " Bool: " + v.getBool () + " String: " + v.getString ());
+
+ }
+ }
+
+
+
+}
+
diff --git a/LineParser/bin/Debug/LineParser.dll b/LineParser/bin/Debug/LineParser.dll
new file mode 100644
index 0000000..3db1727
Binary files /dev/null and b/LineParser/bin/Debug/LineParser.dll differ
diff --git a/LineParser/bin/Debug/LineParser.dll.meta b/LineParser/bin/Debug/LineParser.dll.meta
new file mode 100644
index 0000000..cc6a9e4
--- /dev/null
+++ b/LineParser/bin/Debug/LineParser.dll.meta
@@ -0,0 +1,25 @@
+fileFormatVersion: 2
+guid: 54a5ac61b77308749a1a4bf2f6c49f6d
+timeCreated: 1496606432
+licenseType: Free
+PluginImporter:
+ serializedVersion: 1
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ Any:
+ enabled: 1
+ settings: {}
+ Editor:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ WindowsStoreApps:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/LineParser/bin/Debug/LineParser.pdb b/LineParser/bin/Debug/LineParser.pdb
new file mode 100644
index 0000000..049cbfc
Binary files /dev/null and b/LineParser/bin/Debug/LineParser.pdb differ
diff --git a/LineParser/bin/Debug/LineParser.pdb.meta b/LineParser/bin/Debug/LineParser.pdb.meta
new file mode 100644
index 0000000..430b367
--- /dev/null
+++ b/LineParser/bin/Debug/LineParser.pdb.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 397e9d89cd72d704297ce233e28261b5
+timeCreated: 1496606432
+licenseType: Free
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/LineParser/bin/Debug/sync.ffs_db b/LineParser/bin/Debug/sync.ffs_db
new file mode 100644
index 0000000..d79aaba
Binary files /dev/null and b/LineParser/bin/Debug/sync.ffs_db differ
diff --git a/LineParser/countRows.py b/LineParser/countRows.py
new file mode 100644
index 0000000..3283f08
--- /dev/null
+++ b/LineParser/countRows.py
@@ -0,0 +1,11 @@
+import glob
+
+fileList = glob.glob('./**/*.cs', recursive = True)
+print(len(fileList), " files.")
+
+rows = 0
+for file in fileList:
+ with open(file, 'r') as f:
+ rows += sum(1 for line in f)
+
+print(rows)
diff --git a/LineParser/obj/Debug/Compiler.csproj.CoreCompileInputs.cache b/LineParser/obj/Debug/Compiler.csproj.CoreCompileInputs.cache
new file mode 100644
index 0000000..3f9d4b1
--- /dev/null
+++ b/LineParser/obj/Debug/Compiler.csproj.CoreCompileInputs.cache
@@ -0,0 +1 @@
+df9ac10051b48dc0a890de5aee53326683f228b5
diff --git a/LineParser/obj/Debug/Compiler.csproj.FileListAbsolute.txt b/LineParser/obj/Debug/Compiler.csproj.FileListAbsolute.txt
new file mode 100644
index 0000000..65c1945
--- /dev/null
+++ b/LineParser/obj/Debug/Compiler.csproj.FileListAbsolute.txt
@@ -0,0 +1,35 @@
+C:\Users\FreddeFrallan\Documents\GitHub\If Game\plugins\LineParser\LineParser\bin\Debug\LineParser.dll
+C:\Users\FreddeFrallan\Documents\GitHub\If Game\plugins\LineParser\LineParser\bin\Debug\LineParser.pdb
+C:\Users\FreddeFrallan\Documents\GitHub\If Game\plugins\LineParser\LineParser\obj\Debug\Compiler.csprojResolveAssemblyReference.cache
+C:\Users\FreddeFrallan\Documents\GitHub\If Game\plugins\LineParser\LineParser\obj\Debug\LineParser.dll
+C:\Users\FreddeFrallan\Documents\GitHub\If Game\plugins\LineParser\LineParser\obj\Debug\LineParser.pdb
+C:\Users\FreddeFrallan\Desktop\LOL\LineParser\LineParser\obj\Debug\Compiler.csprojResolveAssemblyReference.cache
+C:\Users\FreddeFrallan\Desktop\LOL\LineParser\LineParser\obj\Debug\LineParser.dll
+C:\Users\FreddeFrallan\Desktop\LOL\LineParser\LineParser\obj\Debug\LineParser.pdb
+C:\Users\FreddeFrallan\Desktop\LOL\LineParser\LineParser\bin\Debug\LineParser.dll
+C:\Users\FreddeFrallan\Desktop\LOL\LineParser\LineParser\bin\Debug\LineParser.pdb
+C:\Users\FreddeFrallan\Documents\GitHub\Hello-Python-Compiler\LineParser\bin\Debug\LineParser.dll
+C:\Users\FreddeFrallan\Documents\GitHub\Hello-Python-Compiler\LineParser\bin\Debug\LineParser.pdb
+C:\Users\FreddeFrallan\Documents\GitHub\Hello-Python-Compiler\LineParser\obj\Debug\LineParser.dll
+C:\Users\FreddeFrallan\Documents\GitHub\Hello-Python-Compiler\LineParser\obj\Debug\LineParser.pdb
+C:\Users\Jonathan\Documents\GitHub\TestCompiler\LineParser\bin\Debug\LineParser.dll
+C:\Users\Jonathan\Documents\GitHub\TestCompiler\LineParser\bin\Debug\LineParser.pdb
+C:\Users\Jonathan\Documents\GitHub\TestCompiler\LineParser\obj\Debug\LineParser.dll
+C:\Users\Jonathan\Documents\GitHub\TestCompiler\LineParser\obj\Debug\LineParser.pdb
+C:\Users\Tifos\Documents\GitHub\TestCompiler\LineParser\bin\Debug\LineParser.dll
+C:\Users\Tifos\Documents\GitHub\TestCompiler\LineParser\bin\Debug\LineParser.pdb
+C:\Users\Tifos\Documents\GitHub\TestCompiler\LineParser\obj\Debug\LineParser.dll
+C:\Users\Tifos\Documents\GitHub\TestCompiler\LineParser\obj\Debug\LineParser.pdb
+C:\Users\Jonathan\Documents\GitHub\TestCompiler\LineParser\obj\Debug\Compiler.csprojResolveAssemblyReference.cache
+C:\Users\Jonathan\Documents\GitHub\compiler\LineParser\obj\Debug\Compiler.csprojResolveAssemblyReference.cache
+C:\Users\Jonathan\Documents\GitHub\compiler\LineParser\obj\Debug\LineParser.dll
+C:\Users\Jonathan\Documents\GitHub\compiler\LineParser\bin\Debug\LineParser.dll
+C:\Users\Jonathan\Documents\GitHub\compiler\LineParser\bin\Debug\LineParser.pdb
+C:\Users\Jonathan\Documents\GitHub\compiler\LineParser\obj\Debug\LineParser.pdb
+C:\Users\Tifos\Documents\GitHub\compiler\LineParser\bin\Debug\LineParser.dll
+C:\Users\Tifos\Documents\GitHub\compiler\LineParser\bin\Debug\LineParser.pdb
+C:\Users\Tifos\Documents\GitHub\compiler\LineParser\obj\Debug\LineParser.dll
+C:\Users\Tifos\Documents\GitHub\compiler\LineParser\obj\Debug\LineParser.pdb
+C:\Users\Tifos\Documents\GitHub\compiler\LineParser\obj\Debug\Compiler.csproj.CoreCompileInputs.cache
+C:\Users\Tifos\Documents\GitHub\compiler\LineParser\obj\Debug\Compiler.csprojResolveAssemblyReference.cache
+C:\Users\Jonathan\Documents\GitHub\compiler\LineParser\obj\Debug\Compiler.csproj.CoreCompileInputs.cache
diff --git a/LineParser/obj/Debug/Compiler.csprojResolveAssemblyReference.cache b/LineParser/obj/Debug/Compiler.csprojResolveAssemblyReference.cache
new file mode 100644
index 0000000..72c7c2c
Binary files /dev/null and b/LineParser/obj/Debug/Compiler.csprojResolveAssemblyReference.cache differ
diff --git a/LineParser/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/LineParser/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
new file mode 100644
index 0000000..ebb752c
Binary files /dev/null and b/LineParser/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ
diff --git a/LineParser/obj/Debug/LineParser.csproj.FileListAbsolute.txt b/LineParser/obj/Debug/LineParser.csproj.FileListAbsolute.txt
new file mode 100644
index 0000000..75b250c
--- /dev/null
+++ b/LineParser/obj/Debug/LineParser.csproj.FileListAbsolute.txt
@@ -0,0 +1,4 @@
+C:\Users\FreddeFrallan\Documents\GitHub\If Game\plugins\LineParser\LineParser\bin\Debug\LineParser.dll
+C:\Users\FreddeFrallan\Documents\GitHub\If Game\plugins\LineParser\LineParser\bin\Debug\LineParser.pdb
+C:\Users\FreddeFrallan\Documents\GitHub\If Game\plugins\LineParser\LineParser\obj\Debug\LineParser.dll
+C:\Users\FreddeFrallan\Documents\GitHub\If Game\plugins\LineParser\LineParser\obj\Debug\LineParser.pdb
diff --git a/LineParser/obj/Debug/LineParser.dll b/LineParser/obj/Debug/LineParser.dll
new file mode 100644
index 0000000..3db1727
Binary files /dev/null and b/LineParser/obj/Debug/LineParser.dll differ
diff --git a/LineParser/obj/Debug/LineParser.pdb b/LineParser/obj/Debug/LineParser.pdb
new file mode 100644
index 0000000..049cbfc
Binary files /dev/null and b/LineParser/obj/Debug/LineParser.pdb differ
diff --git a/LineParser/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs b/LineParser/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs
new file mode 100644
index 0000000..e69de29
diff --git a/LineParser/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs b/LineParser/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs
new file mode 100644
index 0000000..e69de29
diff --git a/LineParser/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs b/LineParser/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs
new file mode 100644
index 0000000..e69de29
diff --git a/LineParser/obj/Release/Compiler.csproj.CoreCompileInputs.cache b/LineParser/obj/Release/Compiler.csproj.CoreCompileInputs.cache
new file mode 100644
index 0000000..4178d18
--- /dev/null
+++ b/LineParser/obj/Release/Compiler.csproj.CoreCompileInputs.cache
@@ -0,0 +1 @@
+a8ca14afb972976d36384874364e04774b37b311