public void TestFor() { const string code = "for(int i=0; i<5; i++) { a = 3; }"; var compilator = new Compilator(); compilator.Compile(code, path); Assert.True(true); // lancer test si calcul ok en lançant msm }
public void TestDivision() { const string expression = "10/2"; var compilator = new Compilator(); compilator.Compile(expression, path); Assert.True(true); // lancer test si calcul ok en lançant msm }
public void TestIfElse() { const string code = "if(2<5) { a = 3; } else { a = 10; }"; var compilator = new Compilator(); compilator.Compile(code, path); Assert.True(true); // lancer test si calcul ok en lançant msm }
public void TestSuperiorEqual() { const string code = "if (2 >= 1) { }"; var compilator = new Compilator(); compilator.Compile(code, path); Assert.True(true); // lancer test si calcul ok en lançant msm }
static void Main(string[] args) { var filePath = args[0]; int index = -1; var outfile = "./out.s"; if ((index = args.ToList().IndexOf("-o")) > 0) { if (index >= args.Length) { Console.WriteLine("you must to specify the out file"); return; } outfile = args[index + 1]; } Compilator.Compile(args[0], outfile); }
/// <summary> /// Добавляет присвоение переменной в код. /// </summary> /// <param name="variableName">Имя переменной.</param> /// <param name="variableExpression">Присваеваемое выражение.</param> public void AddVariableAssignment(string variableName, TokenList variableExpression, bool isGlobal) { bool isReassignment = variables.Contains(variableName); string prefix = (!isReassignment && !isGlobal) ? "var " : ""; string operationCode = $"{prefix}{variableName} = {variableExpression};"; if (!isReassignment) { variables.Add(variableName); } if (isGlobal) { Compilator.AddVariable(variableName); } code.Add(TransformOperationCode(operationCode)); }
public static void Main(string[] argsArray) { Arguments args = new Arguments(argsArray); if (args.runMode == RunMode.Default || args.runMode == RunMode.Compile) { if (Path.GetExtension(args.filePath) != GlobalParams.codeExtention) { throw new RunException($"Неверное расширение, ожидается '{GlobalParams.codeExtention}'"); } string code = File.ReadAllText(args.filePath, GlobalParams.defaultFileEncoding); CodeManager.UpdateNamesMap(GlobalParams.linksPath); try { TokenList tokens = Lexer.Lex(code); if (args.debug) { Console.WriteLine(tokens.ToDebug()); } Parser.ParseRoot(tokens); } catch (Exception error) { Console.WriteLine(error); return; } Delegate assembly = Compilator.CompileCode(args.save, args.debug, args.logs, args.executable); if (args.run) { if (args.logs) { Console.WriteLine("VerteX[Лог]: Запуск сборки."); Console.WriteLine("VerteX[Вывод]: "); } assembly.DynamicInvoke(); } } }
//List<string> Postfix(List<string> expression, HashSet<string> Identifiers) // { // List<string> postfix = new List<string>(); // Stack<string> opStack = new Stack<string>(); // foreach ( string element in expression ) // { // if ( Identifiers.Contains(element) ) // postfix.Add(element); // else // switch ( element ) // { // case "(":{ // opStack.Push(element); // break; // } // case ")":{ // var top = opStack.Pop(); // while ( top!= "(" ){ // postfix.Add(top); // top = opStack.Pop(); // } // break; // } // default:{ // while ( opStack.Count>0 && Operators[opStack.Peek()] >= Operators[element]) // postfix.Add(opStack.Pop()); // opStack.Push(element); // break; // } // } // } // while ( opStack.Count > 0 ) // postfix.Add(opStack.Pop()); // return postfix; // } /// <summary> /// Выполняет постфиксную запись лексем /// </summary> /// <param name="Postfix"></param> /// <returns></returns> //float Evaluate(List<string> Postfix) // { // Stack<string> buffer = new Stack<string>(); // foreach ( var item in Postfix ) // { // if ( !Operators.ContainsKey(item) ) // buffer.Push(item); // else // { // var op2 = int.Parse(buffer.Pop()); // var op1 = int.Parse(buffer.Pop()); // var result = Functions[item](op1, op2); // buffer.Push(result.ToString()); // } // } // return float.Parse(buffer.Pop()); // } void button1_Click(object sender, EventArgs e) { //IdentifierManager.Clear(); //Memory.Clear(); lexemsText.Text = ""; var lines = Compilator.LAnalize(textInput.Text); foreach (var line in lines) { lexemsText.Text += String.Join(" ", line) + "\r\n"; } HashSet <ILexem> Identifiers; List <List <ILexem> > expressions = Compilator.SAnalize(lines, out Identifiers); lexTable.Text = ""; foreach (var item in Identifiers) { lexTable.Text += $"{item.Serialize()}\r\n"; } Identifier res; postfixText.Text = ""; try { foreach (var expression in expressions) { postfixText.Text += String.Join(" ", expression) + "\r\n"; res = Compilator.Evaluate(expression); postfixText.Text += "out: " + res.Value.ToString() + "\r\n"; } } catch (TypeMismatchException ex) { postfixText.Text += ex.Message; } catch (VariableException ex) { postfixText.Text += ex.Message; } }
public Form1() { executControler = new ExecutController(new MyExecutor()); compilator = new Compilator(); InitializeComponent(); }
/// <summary> /// Парсит тела конструкций, в том числе и новой функции. /// </summary> public static void Parse(TokenList tokens, out int counter, bool isRoot = false) { counter = 0; while (counter < tokens.Count) { BaseGenerator generator = CodeManager.GetGenerator(parseMode); TokenList nextTokens = tokens.GetRange(counter); Token currentToken = tokens[counter]; Token nextToken = tokens.Get(counter + 1); if (currentToken.TypeIs(TokenType.NextLine)) { lineIndex++; counter++; continue; } if (currentToken.TypeIs(TokenType.Id)) { // <variableName> = <expression>; if (nextToken.TypeIs(TokenType.AssignOperator)) { string variableName = currentToken.value; TokenList expression = nextTokens.GetRange(nextTokens.IndexOf("=") + 1, nextTokens.IndexOf(";")); generator.AddVariableAssignment(variableName, expression, isRoot); counter += nextTokens.IndexOf(";") + 1; } // <id>(<expression>); else if (nextToken.TypeIs(TokenType.BeginParenthesis)) { Token name = currentToken; TokenList attributes = GetExpressionInParenthesis(nextTokens, errors: false); if (attributes.Count == 0 && !nextTokens.Get(2).TypeIs(TokenType.EndParenthesis)) { throw new ParseException($"После '(' при вызове функции без параметров ожидалось ')', а не '{nextToken}'", lineIndex); } generator.AddFunctionCall(name, attributes); counter += nextTokens.IndexOf(";") + 1; } else { throw new ParseException($"После '{currentToken}' ожидалось '=' либо '(', а не '{nextToken}'", lineIndex); } } else if (currentToken.TypeIs(TokenType.Keyword)) { // функция <functionName>(<parameters>) { <functionBody> } if (currentToken.TypeIs(KeywordType.Function)) { NewFunction newFunction = CodeManager.NewFunction; string name = nextToken.value; TokenList parameters = GetExpressionInParenthesis(nextTokens, errors: false); TokenList body = GetBody(nextTokens, out counter, counter); if (!nextToken.TypeIs(TokenType.Id)) { throw new ParseException($"После ключевого слова 'функция' ожидалось название объявляемой функции, а не '{nextToken}'", lineIndex); } if (!nextTokens.Get(2).TypeIs(TokenType.BeginParenthesis)) { throw new ParseException($"После названия функции ожидалось '(', а не '{nextToken}'", lineIndex); } if (parameters.Count == 0 && !nextTokens.Get(3).TypeIs(TokenType.EndParenthesis)) { throw new ParseException($"После '(' при объявлении функции без параметров ожидалось ')', а не '{nextToken}'", lineIndex); } parameters.DeleteAll(","); newFunction.AddFunctionHeader(name, parameters); parseMode = ParseMode.FunctionCreation; Parse(body, out _); newFunction.Create(); parseMode = ParseMode.Default; } // если (<expresion>) { <body> } else if (currentToken.TypeIs(KeywordType.If)) { TokenList expression = GetExpressionInParenthesis(nextTokens); TokenList body = GetBody(nextTokens, out counter, counter); if (!nextToken.TypeIs(TokenType.BeginParenthesis)) { throw new ParseException($"После ')' ожидалось '{{', а не {nextToken}", lineIndex); } generator.AddIfConstruction(expression); Parse(body, out _); generator.AddConstructionEnd(); } // иначе { <body> } else if (currentToken.TypeIs(KeywordType.Else)) { TokenList body = GetBody(nextTokens, out counter, counter); generator.AddElseConstruction(); Parse(body, out _); generator.AddConstructionEnd(); } // делать { <body> } пока (<expression>) else if (currentToken.TypeIs(KeywordType.Do)) { TokenList body = GetBody(nextTokens, out counter, counter); generator.AddDoConstruction(); Parse(body, out _); generator.AddConstructionEnd(); nextTokens = tokens.GetRange(counter); currentToken = tokens[counter]; if (currentToken.TypeIs(KeywordType.While)) { TokenList expression = GetExpressionInParenthesis(nextTokens); if (expression.Count == 0) { throw new ParseException($"Конструкция 'пока' без выражения", lineIndex); } generator.AddEndingWhileConstruction(expression); counter += nextTokens.IndexOf(";") + 1; } else { throw new ParseException($"После окончания конструкции 'делать' ожидалось ключевое слово 'пока'", lineIndex); } } // пока (<expression>) { <body> } else if (currentToken.TypeIs(KeywordType.While)) { TokenList expression = GetExpressionInParenthesis(nextTokens); TokenList body = GetBody(nextTokens, out counter, counter); generator.AddWhileConstruction(expression); Parse(body, out _); generator.AddConstructionEnd(); } // пробовать { <tryBody> } отловить [(<errorValue>)] { <catchBody> } else if (currentToken.TypeIs(KeywordType.Try)) { TokenList tryBody = GetBody(nextTokens, out counter, counter); generator.AddTryConstruction(); Parse(tryBody, out _); generator.AddConstructionEnd(); nextTokens = tokens.GetRange(counter); currentToken = tokens[counter]; if (currentToken.TypeIs(KeywordType.Catch)) { TokenList expression = GetExpressionInParenthesis(nextTokens, errors: false); TokenList catchBody = GetBody(nextTokens, out counter, counter); if (expression.Count == 1 && expression[0].TypeIs(TokenType.Id)) { generator.AddCatchConstruction(expression[0]); } else { generator.AddCatchConstruction(); } Parse(catchBody, out _); generator.AddConstructionEnd(); } } // определить (<value>) { <body> } else if (currentToken.TypeIs(KeywordType.Switch)) { TokenList expression = GetExpressionInParenthesis(nextTokens); TokenList body = GetBody(nextTokens, out counter, counter); if (expression.Count == 1 && expression[0].TypeIs(TokenType.Id)) { generator.AddSwitchConstruction(expression[0]); ParseSwitch(body); generator.AddConstructionEnd(); } } // использовать ... else if (currentToken.TypeIs(KeywordType.Use)) { // ссылки "<path>" if (nextToken.TypeIs(KeywordType.Links) && nextTokens.Get(2).TypeIs(TokenType.String) && Path.GetExtension(nextTokens[2].value) == GlobalParams.linksExtention) { CodeManager.UpdateNamesMap(nextTokens[2].value); } // <id> else if (nextToken.TypeIs(TokenType.Id)) { Compilator.AddUsing(nextToken.ToString()); Compilator.AddClassRef(nextToken.ToString()); } counter += nextTokens.IndexOf(";") + 1; } // импорт ... else if (currentToken.TypeIs(KeywordType.Import)) { if (nextToken.TypeIs(TokenType.String)) { string path = nextToken.value; if (File.Exists(path)) { string extention = Path.GetExtension(path); if (extention == GlobalParams.codeExtention) { // ...... } else { Compilator.AddRef(path); } } } counter += nextTokens.IndexOf(";") + 1; } else { throw new ParseException($"На первой позиции не ожидалось ключевое слово {currentToken}", lineIndex); } } else { throw new ParseException($"Не удалось распознать слово '{currentToken}'", lineIndex); } } }